「バドミントン戦略シミュレーションとの衝動遊戯:第1ゲーム」で書いた内容の補足的な記事です。
戦略関数について
戦略関数のコードを以下に掲載する。6種類の戦略関数を定義して、strategy.Rという名前で保存している。自分で戦略関数を付け加えれば、シミュレーションすることが可能となる。
#戦略関数リスト
list_fstr <- c("fstr_allsafety", "fstr_allrisky", "fstr_tit4tat", "fstr_tit4tat_inv","fstr_trigger", "fstr_random")
#### fstr_allsafety ####
#全てsafety shotを打つ戦略関数
fstr_allsafety <- function(shot){
shot <- 0
return(shot)
}
#### fstr_allrisky ####
#全てrisky shotを打つ戦略関数
fstr_allrisky <- function(shot){
shot <- 1
return(shot)
}
#### fstr_tit4tat ####
#相手のshotと同じshotを打つ戦略関数
fstr_tit4tat <- function(shot){
return(shot)
}
#### fstr_tit4tat_inv ####
#相手のshotと違うshotを打つ戦略関数
fstr_tit4tat_inv <- function(shot){
shot <- ifelse(shot==1, 0, 1)
return(shot)
}
#### fstr_trigger ####
fstr_trigger <- function(shot){
shot <- ifelse(shot==1, 1, 0)
return(shot)
}
#### fstr_random ####
fstr_random <- function(shot){
shot <- sample(c(0,1),1)
return(shot)
}
高速化について
条件分岐とループ処理がほとんどを占めるので、Rだとやはり遅い。 Rcppパッケージを使ってC++によって高速化したかったのだが、担当日までにコードの書き換えが上手くできなかった。 二か所上手くいかなかったc++のコードの途中作成物を以下に掲載する。
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List frally(Function f1, Function f0){
int ngame = 1000;
double reffect = 0.284;
NumericMatrix mresult(ngame, 6);
NumericVector vresult(6);
for(int game = 0; game < ngame; ++game){
NumericVector vcrally(0);
int p1point = 0;
int p0point = 0;
int player = 1;
while(p1point < 21 && p0point < 21){
int judge = 1;
int shot = 0;
int crally = 0;
while(judge==1){
Function fstr = (player==1)? f1: f0;
double effect = (shot==0)? 0: reffect;
shot = fstr(shot); //ここでassigning to 'int' from incompatible type type 'SEXP'と怒られる
double prob = (shot==0)? 0.9-effect: 0.7-effect;
judge = (runif(1) < prob)? 1: 0; //ここも怒られる
player = (player==1)? 0: 1;
crally = crally + 1;
}
vcrally.insert(vcrally.end(),crally);
if(player==1){
p1point = p1point + 1;
}else{p0point = p0point + 1;}
}
//vresult <- c(mean(vcrally),var(vcrally),max(vcrally),p1point,p0point,ifelse(p1point>p0point,1,0))
//mresult <- rbind(mresult,vresult)
}
return 0;
}
Rの関数(定義した戦略関数)2つを引数にとって試合結果をリストとして出力する関数のコードを書こうとしたが、1ラリーをシミュレーションしているところ(while(judge==1){}のループ処理のところ)が上手くいかなくて躓いた。戦略関数をC++で書いて、includeする方法も試したが、同じように上手くいかなかった。 もう少し、C++とRcppについて学んでみようと思う。
Rの高速化として、並列化について、今年の秋に『Rによるハイパフォーマンスコンピューティング』を読んで学んだので、そちらを試しても良かった。10000回のシミュレーションについては各々独立した処理なので、そんなに苦労せず書けただろうが、結局やらなかった。
バドミントンついて
今回、シミュレーションをするために、バドミントンのかなりの部分を捨象して、モデル化を行った。プレー中、自分のショットの成功確率やその効果は、自分の練習量や疲労度合によって変わるし、相手のショットの種類も初めて戦う相手だと全く分からない。不確実な状況下で、プレーを行う。そのあたりにもまた奥深さがあるのだが、今回は紹介しきれなかった。紹介しきれなかったことや、バドミントンの上達方法やプレーについて考えたことは、また今度記事にする予定でいる。