怪しいモンテカルロ法を使ってカジノを再建しよう

#0. 概要
モナコ公国モンテカルロのカジノを潰した攻略法と呼ばれている「モンテカルロ法」。
英語で検索しても何も情報は出てこない・・・。

出典はどこなのだろうか？こんな方法、気にならないわけがない

実際にシミュレータを作って利得を計算したい。



#1. モンテカルロ法
モンテカルロ法の具体的なやり方を説明する。

まず、
・最少ベット数が1$
・儲けたい金額を4$
とする

処理手順:
・合計が4$になるよう数列を作る
[1, 2, 3]
・両端の合計をベット金額とする
1, 3から4 $
・勝った場合は両端の数字を削除
[1, 2, 3] -> [2]
・負けた場合はベット金額を右端に追記
[1, 2, 3] -> [1, 2, 3, 4]
・これを繰り返し、数列が1つもなくなれば終了
・数字が1つ残った場合は、floor(x/2), floor(x/2)+1で分割する
[1] -> [0, 1]

#2. モンテカルロのカジノを破滅させる
まずは、トータルの損失が-50ドルになるまで賭け続ける。
また、10ドルの儲けが出た時点で終了する。

トータル損失の許容量が大きくなればなるほど、勝率は高くなるが、
負けた時の負債額が大きくなる。

勝率はrouletteの18/37の確率を採用。

実際に回してみた。

```
Configuration:
Return rate 1.0
Max bet 50
Target bet 5
Win rate 0.4864864864864865
-------------------
win
count 1
array[1 2 3 4] -> [2 3]
bet 5
total_won_money 5.0
total_won_num 1
total_lost_money 0
total_lost_num 0
total_benefit 5.0
-------------------
lose
count 2
array[2 3] -> [2 3 5]
bet 5
total_won_money 5.0
total_won_num 1
total_lost_money 5
total_lost_num 1
total_benefit 0.0
-------------------
lose
count 3
array[2 3 5] -> [2 3 5 7]
bet 7
total_won_money 5.0
total_won_num 1
total_lost_money 12
total_lost_num 2
total_benefit -7.0
-------------------
lose
count 4
array[2 3 5 7] -> [2 3 5 7 9]
bet 9
total_won_money 5.0
total_won_num 1
total_lost_money 21
total_lost_num 3
total_benefit -16.0
-------------------
win
count 5
array[2 3 5 7 9] -> [3 5 7]
bet 11
total_won_money 16.0
total_won_num 2
total_lost_money 21
total_lost_num 3
total_benefit -5.0
-------------------
win
count 6
array[3 5 7] -> [5]
bet 10
total_won_money 26.0
total_won_num 3
total_lost_money 21
total_lost_num 3
total_benefit 5.0
-------------------
win
count 7
array[2. 3.] -> []
bet 5.0
total_won_money 31.0
total_won_num 4
total_lost_money 21
total_lost_num 3
total_benefit 10.0
-------------------
epochs 0
+ epochs total benefit 10.0
```

途中-16ドルになるものの、最後は+10ドルに転じた。

もう一度実行してみる。

```
Configuration:
Return rate 1.0
Max bet 50
Target bet 5
Win rate 0.4864864864864865
-------------------
win
count 1
array[1 2 3 4] -> [2 3]
bet 5
total_won_money 5.0
total_won_num 1
total_lost_money 0
total_lost_num 0
total_benefit 5.0
-------------------
win
count 2
array[2 3] -> []
bet 5
total_won_money 10.0
total_won_num 2
total_lost_money 0
total_lost_num 0
total_benefit 10.0
-------------------
epochs 0
+ epochs total benefit 10.0
```

今回はなんと2回連続勝利で+10ドルとなった。


この条件だと勝率は70%を超える。

因みに負けるときはこんな感じ。

```
Configuration:
Return rate 1.0
Max bet 50
Target bet 5
Win rate 0.4864864864864865
-------------------
lose
count 1
array[1 2 3 4] -> [1 2 3 4 5]
bet 5
total_won_money 0
total_won_num 0
total_lost_money 5
total_lost_num 1
total_benefit -5
-------------------
lose
count 2
array[1 2 3 4 5] -> [1 2 3 4 5 6]
bet 6
total_won_money 0
total_won_num 0
total_lost_money 11
total_lost_num 2
total_benefit -11
-------------------
win
count 3
array[1 2 3 4 5 6] -> [2 3 4 5]
bet 7
total_won_money 7.0
total_won_num 1
total_lost_money 11
total_lost_num 2
total_benefit -4.0
-------------------
lose
count 4
array[2 3 4 5] -> [2 3 4 5 7]
bet 7
total_won_money 7.0
total_won_num 1
total_lost_money 18
total_lost_num 3
total_benefit -11.0
-------------------
lose
count 5
array[2 3 4 5 7] -> [2 3 4 5 7 9]
bet 9
total_won_money 7.0
total_won_num 1
total_lost_money 27
total_lost_num 4
total_benefit -20.0
-------------------
lose
count 6
array[2 3 4 5 7 9] -> [ 2  3  4  5  7  9 11]
bet 11
total_won_money 7.0
total_won_num 1
total_lost_money 38
total_lost_num 5
total_benefit -31.0
-------------------
lose
count 7
array[ 2  3  4  5  7  9 11] -> [ 2  3  4  5  7  9 11 13]
bet 13
total_won_money 7.0
total_won_num 1
total_lost_money 51
total_lost_num 6
total_benefit -44.0
-------------------
win
count 8
array[ 2  3  4  5  7  9 11 13] -> [ 3  4  5  7  9 11]
bet 15
total_won_money 22.0
total_won_num 2
total_lost_money 51
total_lost_num 6
total_benefit -29.0
-------------------
lose
count 9
array[ 3  4  5  7  9 11] -> [ 3  4  5  7  9 11 14]
bet 14
total_won_money 22.0
total_won_num 2
total_lost_money 65
total_lost_num 7
total_benefit -43.0
-------------------
win
count 10
array[ 3  4  5  7  9 11 14] -> [ 4  5  7  9 11]
bet 17
total_won_money 39.0
total_won_num 3
total_lost_money 65
total_lost_num 7
total_benefit -26.0
-------------------
lose
count 11
array[ 4  5  7  9 11] -> [ 4  5  7  9 11 15]
bet 15
total_won_money 39.0
total_won_num 3
total_lost_money 80
total_lost_num 8
total_benefit -41.0
-------------------
win
count 12
array[ 4  5  7  9 11 15] -> [ 5  7  9 11]
bet 19
total_won_money 58.0
total_won_num 4
total_lost_money 80
total_lost_num 8
total_benefit -22.0
-------------------
lose
count 13
array[ 5  7  9 11] -> [ 5  7  9 11 16]
bet 16
total_won_money 58.0
total_won_num 4
total_lost_money 96
total_lost_num 9
total_benefit -38.0
-------------------
win
count 14
array[ 5  7  9 11 16] -> [ 7  9 11]
bet 21
total_won_money 79.0
total_won_num 5
total_lost_money 96
total_lost_num 9
total_benefit -17.0
-------------------
lose
count 15
array[ 7  9 11] -> [ 7  9 11 18]
bet 18
total_won_money 79.0
total_won_num 5
total_lost_money 114
total_lost_num 10
total_benefit -35.0
-------------------
win
count 16
array[ 7  9 11 18] -> [ 9 11]
bet 25
total_won_money 104.0
total_won_num 6
total_lost_money 114
total_lost_num 10
total_benefit -10.0
-------------------
lose
count 17
array[ 9 11] -> [ 9 11 20]
bet 20
total_won_money 104.0
total_won_num 6
total_lost_money 134
total_lost_num 11
total_benefit -30.0
-------------------
win
count 18
array[ 9 11 20] -> [11]
bet 29
total_won_money 133.0
total_won_num 7
total_lost_money 134
total_lost_num 11
total_benefit -1.0
-------------------
lose
count 19
array[5. 6.] -> [ 5.  6. 11.]
bet 11.0
total_won_money 133.0
total_won_num 7
total_lost_money 145.0
total_lost_num 12
total_benefit -12.0
-------------------
lose
count 20
array[ 5.  6. 11.] -> [ 5.  6. 11. 16.]
bet 16.0
total_won_money 133.0
total_won_num 7
total_lost_money 161.0
total_lost_num 13
total_benefit -28.0
-------------------
lose
count 21
array[ 5.  6. 11. 16.] -> [ 5.  6. 11. 16. 21.]
bet 21.0
total_won_money 133.0
total_won_num 7
total_lost_money 182.0
total_lost_num 14
total_benefit -49.0
-------------------
lose
count 22
array[ 5.  6. 11. 16. 21.] -> [ 5.  6. 11. 16. 21. 26.]
bet 26.0
total_won_money 133.0
total_won_num 7
total_lost_money 208.0
total_lost_num 15
total_benefit -75.0
-------------------
epochs 0
- epochs total benefit -75.0
```

損失額は大きいが、めったに負けることはないので問題はない！！
なんていったって勝率は70%を超えているわけであるから！！

<b>皆でこの方法を使ってカジノを破滅させよう！！！！！！！</b>

#3. モンテカルロのカジノを再建させる
さて、この手法を使うことによってモンテカルロにあるカジノを破滅させることが出来るということが分かった。
では、次にどのようにしたら再建させられるのであろうか？

それは、この手法を何回も使うことである。
仮に-50ドルの負債を超えたら辞めるというルールでやっているわけであるが、
負けたまま終わりたくないというのが心情。

そこで、勝利、もしくは-50ドル以上負けたら一回リセットして
再度、同条件でモンテカルロ法をやり直す。これが勝利への最短ルートである。

では、この方法で100回やってみた。

```
Configuration:
Return rate 1.0
Max bet 50
Target bet 5
Win rate 0.4864864864864865
-------------------
epochs 0
- epochs total benefit -64.0
epochs 1
+ epochs total benefit -54.0
epochs 2
+ epochs total benefit -44.0
epochs 3
+ epochs total benefit -34.0
epochs 4
+ epochs total benefit -24.0
epochs 5
+ epochs total benefit -14.0
epochs 6
+ epochs total benefit -4.0
epochs 7
+ epochs total benefit 6.0
epochs 8
- epochs total benefit -59.0
epochs 9
+ epochs total benefit -49.0
epochs 10
- epochs total benefit -101.0
epochs 11
+ epochs total benefit -91.0
epochs 12
+ epochs total benefit -81.0
epochs 13
- epochs total benefit -137.0
epochs 14
+ epochs total benefit -127.0
epochs 15
- epochs total benefit -183.0
epochs 16
- epochs total benefit -244.0
epochs 17
+ epochs total benefit -234.0
epochs 18
+ epochs total benefit -224.0
epochs 19
+ epochs total benefit -214.0
epochs 20
+ epochs total benefit -204.0
epochs 21
+ epochs total benefit -194.0
epochs 22
- epochs total benefit -251.0
epochs 23
+ epochs total benefit -241.0
epochs 24
- epochs total benefit -303.0
epochs 25
+ epochs total benefit -293.0
epochs 26
+ epochs total benefit -283.0
epochs 27
- epochs total benefit -342.0
epochs 28
+ epochs total benefit -332.0
epochs 29
+ epochs total benefit -322.0
epochs 30
+ epochs total benefit -312.0
epochs 31
- epochs total benefit -367.0
epochs 32
- epochs total benefit -424.0
epochs 33
+ epochs total benefit -414.0
epochs 34
+ epochs total benefit -404.0
epochs 35
+ epochs total benefit -394.0
epochs 36
+ epochs total benefit -384.0
epochs 37
+ epochs total benefit -374.0
epochs 38
+ epochs total benefit -364.0
epochs 39
+ epochs total benefit -354.0
epochs 40
+ epochs total benefit -344.0
epochs 41
+ epochs total benefit -334.0
epochs 42
+ epochs total benefit -324.0
epochs 43
+ epochs total benefit -314.0
epochs 44
+ epochs total benefit -304.0
epochs 45
+ epochs total benefit -294.0
epochs 46
+ epochs total benefit -284.0
epochs 47
+ epochs total benefit -274.0
epochs 48
+ epochs total benefit -264.0
epochs 49
+ epochs total benefit -254.0
epochs 50
+ epochs total benefit -244.0
epochs 51
+ epochs total benefit -234.0
epochs 52
- epochs total benefit -290.0
epochs 53
+ epochs total benefit -280.0
epochs 54
- epochs total benefit -343.0
epochs 55
- epochs total benefit -396.0
epochs 56
+ epochs total benefit -386.0
epochs 57
+ epochs total benefit -376.0
epochs 58
+ epochs total benefit -366.0
epochs 59
+ epochs total benefit -356.0
epochs 60
+ epochs total benefit -346.0
epochs 61
- epochs total benefit -417.0
epochs 62
+ epochs total benefit -407.0
epochs 63
+ epochs total benefit -397.0
epochs 64
- epochs total benefit -465.0
epochs 65
- epochs total benefit -538.0
epochs 66
- epochs total benefit -597.0
epochs 67
+ epochs total benefit -587.0
epochs 68
- epochs total benefit -647.0
epochs 69
+ epochs total benefit -637.0
epochs 70
+ epochs total benefit -627.0
epochs 71
+ epochs total benefit -617.0
epochs 72
+ epochs total benefit -607.0
epochs 73
+ epochs total benefit -597.0
epochs 74
+ epochs total benefit -587.0
epochs 75
+ epochs total benefit -577.0
epochs 76
+ epochs total benefit -567.0
epochs 77
+ epochs total benefit -557.0
epochs 78
+ epochs total benefit -547.0
epochs 79
+ epochs total benefit -537.0
epochs 80
+ epochs total benefit -527.0
epochs 81
+ epochs total benefit -517.0
epochs 82
+ epochs total benefit -507.0
epochs 83
+ epochs total benefit -497.0
epochs 84
+ epochs total benefit -487.0
epochs 85
- epochs total benefit -542.0
epochs 86
+ epochs total benefit -532.0
epochs 87
+ epochs total benefit -522.0
epochs 88
+ epochs total benefit -512.0
epochs 89
- epochs total benefit -570.0
epochs 90
+ epochs total benefit -560.0
epochs 91
+ epochs total benefit -550.0
epochs 92
+ epochs total benefit -540.0
epochs 93
+ epochs total benefit -530.0
epochs 94
+ epochs total benefit -520.0
epochs 95
+ epochs total benefit -510.0
epochs 96
+ epochs total benefit -500.0
epochs 97
+ epochs total benefit -490.0
epochs 98
+ epochs total benefit -480.0
epochs 99
+ epochs total benefit -470.0
```

プラスマークが勝利で終わったエポックを示している。
もうプラスマークのオンパレードであり、圧倒的な勝率である。
これではモンテカルロのカジノもぐうの音も出ないはずである！！！


そして、最終Total benefitは・・・

<h3><b>-470.0ドル !!!!!!!!!! </b></h3>

再建への道のりは近い。

因みに10万回程度やると収束してくる。その場合はカジノ側が
<h3><b>165700ドル 程度の儲けとなる</b></h3>







# A. ソースコード

``` python
import numpy as np
import random

## fields
RETURN_RATE = 1.0 # /2
WIN_RATE = 18/37  # roulette
TOTAL_BET = 50
TARGET_BET = 5
TOTAL_EXPERIMENT_NUM = 1000
TOTAL_EPOCHS = 100
DISP = 1

## 
won_money = 0
bet = 0
total_won_money = 0
total_won_num = 0
total_lost_num = 0
total_lost_money = 0
total_benefit = 0
epochs_total_benefit = 0
mcArray = np.array(range(1, TARGET_BET))
prvArray = []


print("Start...")
print("Configuration:")
print("Return rate " + str(RETURN_RATE))
print("Max bet " + str(TOTAL_BET))
print("Target bet " + str(TARGET_BET))
print("Win rate " + str(WIN_RATE))
print("-------------------")
for epochs in range(TOTAL_EPOCHS):
  won_money = 0
  bet = 0
  total_won_money = 0
  total_won_num = 0
  total_lost_num = 0
  total_lost_money = 0
  total_benefit = 0
  mcArray = np.array(range(1, TARGET_BET))
  prvArray = []
  for i in range(TOTAL_EXPERIMENT_NUM):
    if len(mcArray) == 0:
      break

    if total_benefit <= -TOTAL_BET:
      break

    if len(mcArray) == 1:
      if (mcArray[0] % 2) == 1:
        mcArray = np.append(mcArray, np.floor(mcArray[0] / 2))
        mcArray = np.append(mcArray, np.floor(mcArray[0] / 2) + 1)
        mcArray = np.delete(mcArray, 0)
      else:
        mcArray = np.append(mcArray, mcArray[0] / 2)
        mcArray = np.append(mcArray, mcArray[0] / 2)
        mcArray = np.delete(mcArray, 0)

    prvArray = mcArray
    bet = mcArray[0] + mcArray[-1]
    binary_score = random.random()
    if binary_score < WIN_RATE:
      # win
      if DISP == 1:
        print("win")
      won_money = bet * RETURN_RATE
      total_won_money += won_money
      total_benefit += won_money
      total_won_num += 1
      mcArray = np.delete(mcArray, 0)
      mcArray = np.delete(mcArray, len(mcArray)-1 )
    else:
      # lose
      if DISP == 1:
        print("lose")
      total_lost_money += bet
      total_benefit -= bet
      total_lost_num += 1
      mcArray = np.append(mcArray, bet)

    if DISP == 1:
      print("count " + str(i+1))
      print("array" + str(prvArray) + " -> " + str(mcArray))
      print("bet " + str(bet))
      print("total_won_money " + str(total_won_money))
      print("total_won_num " + str(total_won_num))
      print("total_lost_money " + str(total_lost_money))
      print("total_lost_num " + str(total_lost_num))
      print("total_benefit " + str(total_benefit))
      print("-------------------")

  epochs_total_benefit += total_benefit
  if total_benefit < 0:
    print("epochs " + str(epochs))
    print("- epochs total benefit " + str(epochs_total_benefit))
  else:
    print("epochs " + str(epochs))
    print("+ epochs total benefit " + str(epochs_total_benefit))
      
```