あまりにも遅いので、シングル版を作りました。
単純な局所ルールと相互作用によりカオス的な複雑な現象が創発するのが確認できたでしょうか?
また、木の生成確率により、ランダム(カオス的)な現象(確率0.05)、収束する現象(確率1, 0.013)が確認できたでしょうか?
また、確率0.013の時は、クリックを何回かすることにより、偶発的にカオス的な現象に移行することが確認できたでしょうか?
残念ながら、第1回で書いたようなカオスの縁と呼ばれるような現象がどのあたりの確率で出てくるのか、またどのように見えるのか、私にはわかりませんでした。
非常に汚いですが、ソースを載せます。 森林火災シミュレーションsource
さて、『複雑適応系』に話しを絞って考えた場合、系の特徴としてどのようなものを備えてなければならないでしょうか。
+--------+
+-------->|RL Agent|
| +---->| |----+
| | +--------+ |
| | |
State| | Reward | Action
| | |
| | +-----------+ |
| '---|Environment|<--+
+-------| |
+-----------+
|
+--------+ 1 +--------------+
|RL Agent|--------|Value Function|
| | +--------------+
| | 1 +--------------+ 1 +-----+
| |--------|Environment |------|State|
| | |(Singleton) | +-----+
+--------+ +--------------+
|
ただし、とれるActionの種類がStateによって変わる場合は、Environment側で次に取れるActionのリストを送るほうが実際的だと思われます。
例えばハムレットの場合、上まで駒が入ってしまった列には、それ以上駒が入らないので、StateによりとれるActionが変わるということです。
これを反映させると、RLの構造的には、以下のようになり、
+--------+
+--------------->lRL Agent|
| +-------->| |
| | +---->| |----+
| | | +--------+ |
| | | |
Action| State| | Reward | Action
List | | | |
| | | +-----------+ |
| | '---|Environment|<--+
| +-------| |
+--------------| |
+-----------+
|
+--------+ 1 +--------------+
|RL Agent|--------|Value Function|
| | +--------------+
| | 1 +--------------+ 1 +-----+
| |--------|Environment |------|State|
| | |(Singleton) | +-----+
+--------+ | | 1 +-----------+ * +-------+
| |------|Action List|---------|Action |
+--------------+ +-----------+ +-------+
|
+---------+ +--------+ 1 +--------------+
|Game Host| 2 |RL Agent|--------|Value Function|
| |-------| | +--------------+
| | | | 1 +--------------+ 1 +-----+
+---------+ | |--------|Environment |------|State|
| | |(Singleton) | +-----+
+--------+ | | 1 +-----------+ * +-------+
| |------|Action List|---------|Action |
+--------------+ +-----------+ +-------+
|
上記の図を見ていると、EnvironmentとRL Agentの橋渡し(State, Action List, Reward, Actionのやり取り)は、Game Hostの役目にしたほうがよさそうです。
+---------+ +--------+ 1 +--------------+
|Game Host| 2 |RL Agent|--------|Value Function|
| |-------| | +--------------+
| | +--------+ +--------------+ 1 +-----+
| | 1 |Environment |------|State|
| |-------------------------|(Singleton) | +-----+
+---------+ | | 1 +-----------+ * +-------+
| |------|Action List|---------|Action |
+--------------+ +-----------+ +-------+
|
+------------------------------------------+
| << interface >> |
| IfGameHost |
+------------------------------------------+
+------------------------------------------+
| public void initialization(Agent, Agent) |
| pubilc void startGame() |
+------------------------------------------+
|
しかし、このままではmainがAgentを知っていなければなりません。
個人的には、mainは、"Agentの種類"は知っているが、"Agent Class"は知らない。という状態にしたいと思います。
これによって、mainが勝手にAgentのメソッドを使用することをなくしたいのです。
そこで、IfGameHostをFactory Methodにし、同時にGameHostの抽象クラスを設計してしまいます。
+--------------------------------------------+
| << interface >> |
| IfGameHost |
+--------------------------------------------+
+--------------------------------------------+
| public void initialization() |
| public void initGameAgent(String, String) |
| pubilc void startGame() |
+--------------------------------------------+
+----------------------------------------------+
| << abstract >> |
| AbsGameHost implements IfGameHost |
+----------------------------------------------+
| protected Agent _player[] |
| protected Environment _environement |
| protected Map _agentList |
+----------------------------------------------+
| public AbsGameHost() | // <-- Call initialization();
| public abstract void initialization() | // <-- GameHostのConcreteクラスがAgentの種類全てをsingupPlayerを呼び出して、signupする。
| protected void signupPlayer(String, String) | // <-- Call _agentList.put();
| public void initGameAgent(String, String) | // <-- _agentListから該当クラスを見つけ、Instanciateし、_player[]に代入。
| pubilc void startGame() | // <-- gameを進めるメインのメソッド。
+----------------------------------------------+
|
+----------------------------------------------+
| << interface >> |
| IfEnvironment |
+----------------------------------------------+
+----------------------------------------------+
| public static Environement getEnvironment() | // <-- Singletonなので、このstaticメソッドでインスタンス取得
| public void initState() | // <-- State(盤面の状態)の初期化
| public void updateToNewState(player, Action) | // <-- ActionによるStateの更新
| pubilc double getReward() | // <-- 報酬の計算
| pubilc ActionArray possibleActions() | // <-- 次のターンで取り得るAction
| pubilc boolean isContinuable() | // <-- ゲーム終了かどうか
| |
| pubilc State getCurrentStateCopy() |
+----------------------------------------------+
|
最後の"getCurrentStateCopy"は、強化学習(Reinforcement Learning)の学習において、State毎の価値(Value)を
学習するということがあるため、Agentで使用する"State"を得るために入れてあります。
+----------------------------------------------+
| << interface >> |
| IfState |
+----------------------------------------------+
+----------------------------------------------+
| public void initState() | // <-- Stateの初期化Game開始時に呼ばれる
| |
| public State getNewState(player, Action) | // <-- Actionを起こした後の盤面のコピーを返す(現状の盤面は、変化しない)
| |
| public boolean equals(Object) | // <-- Stateオブジェクトの同一性をチェックする (override)
| pubilc int hashCode(); | // <-- StateをHashTableなどに保持することを考えインプリメント(override)
+----------------------------------------------+
|
真ん中の"getNewState(player, Action)"は、強化学習においては、自分が手を打った後の盤面に対して価値(value)の学習を行うため、
実際の盤面を変更せずに"手を打った後の盤面のコピー"が必要となるためいれています。
下の2つは、強化学習においてState毎に価値(value)の学習を行いますが、同一Stateかどうかの判断を行う場合に必要となります。
Environmentから使用するメソッドも含めて抽象クラスを書くと、下記のようになります。
+----------------------------------------------------------+
| << abstract >> |
| AbsState |
+----------------------------------------------------------+
+----------------------------------------------------------+
| public abstract void initState() | // <-- Stateの初期化Game開始時に呼ばれる
| public abstract State getNewState(player, Action) | // <-- Actionを起こした後の盤面のコピーを返す(現状の盤面は、変化しない)
| |
| public abstract boolean equals(Object) | // <-- Stateオブジェクトの同一性をチェックする (override)
| pubilc abstract int hashCode(); | // <-- StateをHashTableなどに保持することを考えインプリメント(override)
| |
| protected abstract void updateToNewState(player,Action) |
| protected State getCopy() |
+----------------------------------------------------------+
|
AbState側に、possibleActions()や、isContinuable()などをインプリし、Environment側ではAbStateに委譲するだけというインプリも出来ますね。
+----------------------------------------------+
| << interface >> |
| IfAgent |
+----------------------------------------------+
+----------------------------------------------+
| public void initAgent() | // <-- Agentの初期化Game開始時に呼ばれる
| public Action returnAction(ActionList,State) | // <-- 取り得るActionのリストと現状の状態(State)を受け取り次のActionを返す
| pubilc double setReward() | // <-- 報酬の受け取りと学習
+----------------------------------------------+
|
Case: 後攻の場合
(最初の状態)
[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ]
|
上記図において、ValueFunctionは、2つの働きをしています。
ActionListのそれぞれに対して:
現状StateにActionを行った場合のStateを得る。
新しいStateの価値を自分自身の価値関数から得る。
得られた価値の最も高いものを出力
|
+-------------------------------------------------+
| << interface >> |
| IfRLValueFunction |
+-------------------------------------------------+
+-------------------------------------------------+
| pubilc viod getStateValue(State) | // <-- Stateの価値を得る
| pubilc void updateStateValue(State,State,reward)| // <-- oldState,newState,reward を元に価値関数のアップデート
+-------------------------------------------------+
|
次回は、インプリに進みたいと思います。