GA将?開発日記~王理のその先へ~

ネタ勢最強を目指して絶賛開発中。

8/20の日記の補足

 id:streakeagle:20070820:1187623564で書いた三目並べのマルチスレッドの件です。

http://d.hatena.ne.jp/Gasyou/20070820/1187623564
GA将!さんが、三目並べを並列処理で試しているらしい。
強化学習かな。

http://d.hatena.ne.jp/mkomiya/20070822/p1

 強化学習でマルチスレッドなんですが、高速化を狙ったものではありません。

 まず、前提として、強化学習のエージェントは以下の様に行動します。

while( 飽きるまで ) {

 while( 対局終了まで ) {

  // 今の状態を環境(盤面+相手プレイヤーをまとめたもの)から取得
  State state = this.environment.getState();

  // 今の状態で取れる行動から一つ選択
  Action action = this.selectOne( state.getActionList() );

  // 環境に対して自分がとる行動を伝え、報酬を取得する
  final double returns = this.environment.play( action );

  // 学習する
  this.learn( returns );

 }// while(...)

}// while(...)

 で、三目並べや将棋だとエージェントが先手と後手で2つになるのですが、それらをシングルスレッドで扱おうと思うと上記のループを適当に修正する必要が出てきます。

 さらに、私はメタ強化学習*1を実装する予定なので、さらにエージェント数が増えます。

 そうすると、全部で4つか5つのエージェントになるのですが、そうするとループの処理が結構面倒になります。

 また、エージェント内部の実装はなるべく外に意識させたくないので、そういう意味でも(比較的メイン関数に近い位置にある)ループ内でエージェントの事を考えるのは避けたいところです。


 なら、各エージェントに一つのスレッドを割り当てて、各自がてんでんばらばらに動く*2。ただし、environmentが適当にタイミングを調整してくれる、という実装にしようと思っています。

 例えば、三目並べの場合だと先手エージェントがapply(Action)で行動した後に学習して、その後内側while()文の先頭に戻ってgetState()を呼びます。

 この時、後手エージェントがまだ行動していなければ、getState()内で先手エージェントのスレッドの処理を停止ます。

 例えば、三目並べの場合だと先手エージェントがapply()で行動します。すると、apply()メソッド内部で後手が指すのを待ちます。

 で、後手エージェントは別スレッドで動いているのでそのうち行動し、そうすると今度は先手番になるので、その時に停止していた先手エージェントのスレッドを再開するし、apply()が報酬を返す、という感じです。


 要するに、シングルスレッド版では全体のタイミングを調整する「指揮者」みたいな人がいたわけですけど、それをなくして各エージェントが好き勝手に動く。ただし、環境内部で適当にタイミングを調整してくれる、って事です。

 ・・・と、ここまで書いといてなんですが、高々5エージェント程度ならシングルスレッドでもいい気がしてきました。趣味の問題かなぁ。

 8/22 22:40 間違えてたんで修正

*1:エージェント内のメタパラメータを調整する為のエージェントを実装する手法

*2:スレッド関数内で上記のループを実行する