霞と側杖を食らう

ほしいものです。なにかいただけるとしあわせです。[https://www.amazon.jp/hz/wishlist/ls/2EIEFTV4IKSIJ?ref_=wl_share]

バドミントン戦略シミュレーションとの衝動遊戯:第2ゲーム

 

「バドミントン戦略シミュレーションとの衝動遊戯:第1ゲーム」で書いた内容の補足的な記事です。

moratoriamuo.hatenablog.com

 

戦略関数について

戦略関数のコードを以下に掲載する。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回のシミュレーションについては各々独立した処理なので、そんなに苦労せず書けただろうが、結局やらなかった。

バドミントンついて

今回、シミュレーションをするために、バドミントンのかなりの部分を捨象して、モデル化を行った。プレー中、自分のショットの成功確率やその効果は、自分の練習量や疲労度合によって変わるし、相手のショットの種類も初めて戦う相手だと全く分からない。不確実な状況下で、プレーを行う。そのあたりにもまた奥深さがあるのだが、今回は紹介しきれなかった。紹介しきれなかったことや、バドミントンの上達方法やプレーについて考えたことは、また今度記事にする予定でいる。