3人の”囚人のジレンマ”の良い戦略を見つけれんま？

#はじめに

ゲーム理論で有名な囚人のジレンマを3人で考えて，あらゆる戦略をシミュレーションしたい所存です。
ここでは，とりあえず動くところまで。

ちなみに，「囚人のジレンマを3人以上に拡大したもの」を社会学分野では”社会的ジレンマ”と**呼ぶことがあるらしい**ですが，”n人囚人のジレンマ”の名前で扱う書籍があったりと，不明瞭なので適当に呼びます。

#そもそも”囚人のジレンマ”とは（[Wiki](https://ja.wikipedia.org/wiki/%E5%9B%9A%E4%BA%BA%E3%81%AE%E3%82%B8%E3%83%AC%E3%83%B3%E3%83%9E#CITEREF%E5%B1%B1%E5%B2%B82000)参照）


囚人のジレンマとは，「**お互い協力する方が協力しないよりもよい結果になることが分かっていても，協力しない者が利益を得る状況では互いに協力しなくなる**」というジレンマである。

名前の通り，以下のようなゲーム。

```
共同で犯罪を行ったと思われる2人の囚人A・Bを自白させるため、検事はその2人の囚人A・Bに次のような司法取引をもちかけた。

・ 本来ならお前たちは懲役5年なんだが、もし2人とも黙秘したら、証拠不十分として減刑し、2人とも懲役2年だ。
・ もし片方だけが自白したら、そいつはその場で釈放してやろう（つまり懲役0年）。
・ この場合黙秘してた方は懲役10年だ。ただし、2人とも自白したら、判決どおり2人とも懲役5年だ。

このとき、「2人の囚人A・Bはそれぞれ黙秘すべきかそれとも自白すべきか」というのが問題である。
なお2人の囚人A・Bは別室に隔離されており、相談することはできない状況に置かれているものとする。
```

囚人A・Bは，裏切り合って（自白）懲役5年になるよりも，協力（黙秘）して懲役2年の方が得です。
しかし，それぞれが自分の利益のみ追求する（即釈放を求める）限り，結果的に裏切り合って一番の損をしてしまいます。（ゲーム理論では「個々は自分の利益を最大化するよう意思決定を行う」ことが前提）
まさにジレンマ。

これを3人にして考えます。


#利得表

A，B，Cがそれぞれ協力・裏切りをしたときの利得を，仮に以下のように設定します。
（Aの利得, Bの利得, Cの利得）

- **C 協力**

|            | B 協力     | B 裏切り   |
|------------|-----------|-----------|
| **A 協力**  | （3, 3, 3） | （1, 5, 1） |
| **A 裏切り** | （5, 1, 1） | （4, 4, 1） |

- **C 裏切り**

|            | B 協力     | B 裏切り   |
|------------|-----------|-----------|
| **A 協力**  | （1, 1, 5） | （1, 4, 4） |
| **A 裏切り** | （4, 1, 4） | （1, 1, 1） |

問題設定として正しいのかなこれ。

#実装

例えば自分をAとし，B・Cが協力するか裏切るかはランダムのとき，
利得が最大となるような戦略は何か？を考えたいわけです。

今回はとりあえず動けばいいので，自分Aの行動もランダムとします。
（**でたらめ戦略**と呼ぶらしい）

誰が何周目にどう行動したのかも，一応記録。
適当にif文をいっぱい並べて15回まわします。

```Python
import numpy as np

# パラメータ設定やら
action = [0, 1] #協力（state=0）, 裏切り（state=1）
N_trial = 15 #試行回数
actionTab = np.zeros([3, N_trial]) #行動記録（人,action） 
gain = np.zeros([3,N_trial]) #利得記録（人,利得）


for i in range(N_trial):
   
    # A:0 B:1 C:2
    # B・Cはランダムに行動
    actionTab[1,i] = np.random.choice(action)
    actionTab[2,i] = np.random.choice(action)
    
    ### 戦略１：でたらめ戦略
    actionTab[0,i] = np.random.choice(action)
        

    if(actionTab[0,i] == 0): #A協力

        if(actionTab[1,i] == 0): #B協力

            if(actionTab[2,i] == 0): #C協力
                gain[0,i], gain[1,i], gain[2,i] = 3,3,3
            else: #C裏切り
                gain[0,i], gain[1,i], gain[2,i] = 1,1,5
                
        else: #B裏切り
            
            if(actionTab[2,i] == 0): #C協力
                gain[0,i], gain[1,i], gain[2,i] = 1,5,1
            else: #C裏切り
                gain[0,i], gain[1,i], gain[2,i] = 1,4,4
            
    else: #Aが裏切り
        
        if(actionTab[1,i] == 0): #B協力
            
            if(actionTab[2,i] == 0): #C協力
                gain[0,i], gain[1,i], gain[2,i] = 5,1,1
            else: #C裏切り
                gain[0,i], gain[1,i], gain[2,i] = 4,1,4
                
        else: #B裏切り
            
            if(actionTab[2,i] == 0): #C協力
                gain[0,i], gain[1,i], gain[2,i] = 4,4,1
            else: #C裏切り
                gain[0,i], gain[1,i], gain[2,i] = 1,1,1
```

ただのゴリ押しです。


#結果

申し訳程度に，利得合計の平均値だけ置いておきます。（標本数100）

```
Mean: (A 37.250000, B 37.370000, C 37.540000)
```
当然近い。

#おわりに

簡単に3人の囚人のジレンマをモデリングし，ソースはどうあれ，ちゃんと動きました。
次は，[wiki](https://ja.wikipedia.org/wiki/%E5%9B%9A%E4%BA%BA%E3%81%AE%E3%82%B8%E3%83%AC%E3%83%B3%E3%83%9E#CITEREF%E5%B1%B1%E5%B2%B82000)掲載の代表的な戦略とやらをシミュレーションするつもりです。


```
代表的な戦略の例

・しっぺ返し戦略 (Tit For Tat)
　　初回は協調を選択し、2回目以降は前回に相手が出した手と同じ手を出す。
・逆しっぺ返し戦略 (Reverse Tit For Tat)
　　初回は裏切りを選択し、2回目以降は前回に相手が出した手と同じ手を出す。
・堪忍袋戦略 (Tit-For-Two-Tats)
　　初回は協調を選択し、相手が2回連続で裏切りを選んだとき、次回に裏切りを出す。
・フリードマン戦略 (Friedman)
　　初回は協調を選択し、相手が1回でも裏切りを選んだら、以後は最後まで裏切りを出す。
・ヨッス戦略 (Joss)
　　初回は協調を選択し、2回目以降は相手が前回に裏切りを選んでいたら裏切りを出す。
　　前回に協調を出していたら、90%の確率で協調を、10%の確率で裏切りを出す。
・テュロック戦略 (Tullock)
　　最初の10回は協調を選択する。以降は、最初の10回の間に相手が協調を選んだ頻度より10%低い確率で協調を出す。
・デービス戦略 (Davis)
　　最初の10回は協調を選択する。その間、相手が1回でも裏切りを出していれば、以降は裏切りを出す。
・悪人戦略 (All-D)
　　常に裏切りを出す。
・善人戦略 (All-C)
　　常に協調を出す。
```

他に使えそうな戦略があれば，コメントください。