nashidos’s diary

アルゴリズムとか機械学習とか色々

モンテカルロ法【カジノ】は負けるのかシミュレートしてみた

本記事では、モンテカルロ法と呼ばれるカジノにおける攻略法についてシミュレーションを行います。

行ったシミュレーション結果から長期的にモンテカルロ法を使った場合にどうなるのか分析していこうと思います。



モンテカルロ法とは

この攻略法は以下のような流れで進められます。

  1. 数列を用意する(例 [1, 2, 3])
  2. 端同士を足した金額を賭ける(例 1+3=4)
  3. 勝敗結果に応じて数列を操作
    1. 負けた場合は賭けた金額を数列に追加(例 [1, 2, 3, 4])
    2. 勝った場合は両端の数字を数列から削除(例 [1, 2, 3])
  4. 数字が1つ、もしくは無くなるまで2, 3を繰り返す

この攻略法は「負けにくい戦略」というのが特徴です。

負けた場合、前回のベット金額以上のお金をベットすることで多少の負けでは破産しません。

じゃあモンテカルロ法を使って億万長者になれるのかというと話はまた変わってきます。

それをシミュレーションを通して確認していきましょう。

シミュレーション

今回は以下の設定でシミュレーションを行いました。

  • 初期資産:100000円
  • ベースのベット金額:100円
  • ラウンド数(ループの終了で1ラウンド):100
  • 勝ったら賭けた金額が倍、負ければ0

実際に書いたソースコードも載せておきます。

ソースコード

import random
from matplotlib import pyplot as plt
%matplotlib inline

# 初期資産
balance = 100000
# 賭ける金額
bet = 100
# ラウンド数
rounds = 100

record = []

for i in range(rounds):
    monte = [1,2,3]
    while len(monte) > 1 and balance > 0:
        record.append(balance)
        
        # 50%の確率で勝つ/負ける
        result = random.choice(['win', 'lose'])
        
        if result == 'lose':# 負けの場合
            balance -= (monte[0]+monte[-1])*bet
            # 足したものを追加
            monte.append(monte[0]+monte[-1])
            
        elif result == 'win':# 勝ちの場合
            balance += (monte[0]+monte[-1])*bet
            # 端の数字を消す
            del monte[0]
            del monte[-1]
            
# グラフ出力
plt.xlabel("game")
plt.ylabel("balance")
plt.plot(record)

シミュレーション結果

シミュレーションを回した結果が以下のグラフです。

f:id:nashidos:20210501204144p:plain

あれ、儲かってる?

一度200ゲーム目付近で落ち込んではいますが、最終的には140000円ほどに成長しています。

これはもしかして億万長者になる方法を見つけてしまったかもしれません。

念のためラウンドを1000に増やしてもう一度実行してみます。

f:id:nashidos:20210501204546p:plain

はい、死にました。

残金が0になり強制終了です。

このようにモンテカルロ法はすぐには負けないけど、長期的にみると負けてしまう戦法のようです。

ただ、これだけしかシミュレーションを回していないと偶然という可能性もあります。

ということで、一気に10回ぐらいシミュレーションを回してどうなるのか見てみようと思います。

複数のシミュレーション

複数回シミュレーションを回すためにソースコードを以下のように変更しました。

for文で囲むだけです。

ソースコード

import random
from matplotlib import pyplot as plt
%matplotlib inline

count = 10

for j in range(count):
    # 初期資産
    balance = 100000
    # 賭ける金額
    bet = 100
    # ラウンド数
    rounds = 100

    record = []

    for i in range(rounds):
        monte = [1,2,3]
        while len(monte) > 1 and balance > 0:
            record.append(balance)

            # 50%の確率で勝つ/負ける
            result = random.choice(['win', 'lose'])

            if result == 'lose':# 負けの場合
                balance -= (monte[0]+monte[-1])*bet
                # 足したものを追加
                monte.append(monte[0]+monte[-1])

            elif result == 'win':# 勝ちの場合
                balance += (monte[0]+monte[-1])*bet
                # 端の数字を消す
                del monte[0]
                del monte[-1]
            
    # グラフ出力
    plt.xlabel("game")
    plt.ylabel("balance")
    plt.plot(record)

シミュレーション結果

まず先ほどと同じ初期設定で、10回シミュレーションした結果が下の画像です。

f:id:nashidos:20210501205622p:plain

お!やはり100ラウンド程度であれば100%利益がでていますね。

次に、ラウンド数を1000にして10回シミュレートしてみます。

f:id:nashidos:20210501205739p:plain

はい、8割ほど死んでいます。

シミュレーション回数を増やしてもやはり長期的にモンテカルロ法のみで勝ち続けることは難しそうです。

まとめ

モンテカルロ法はたしかに負けにくい攻略法で短期間であればかなりの確率で利益を出すことができそうです。

しかし、長期的に見るとこの攻略法だけでは勝ち続けることはできず、ほぼ確実に負けてしまいます。

世の中簡単に億万長者にはなれませんね。

おわり