LoginSignup
1
1

More than 3 years have passed since last update.

100日後にエンジニアになるキミ - 64日目 - プログラミング - 確率について2

Last updated at Posted at 2020-05-23

昨日までのはこちら

100日後にエンジニアになるキミ - 63日目 - プログラミング - 確率について1

100日後にエンジニアになるキミ - 59日目 - プログラミング - アルゴリズムについて

100日後にエンジニアになるキミ - 53日目 - Git - Gitについて

100日後にエンジニアになるキミ - 42日目 - クラウド - クラウドサービスについて

100日後にエンジニアになるキミ - 36日目 - データベース - データベースについて

100日後にエンジニアになるキミ - 24日目 - Python - Python言語の基礎1

100日後にエンジニアになるキミ - 18日目 - Javascript - JavaScriptの基礎1

100日後にエンジニアになるキミ - 14日目 - CSS - CSSの基礎1

100日後にエンジニアになるキミ - 6日目 - HTML - HTMLの基礎1

期待値について

期待値とは1回の試行で得られる平均値のことです。

得られる全ての値とそれが起こる確率の積を足し上げたものです。

サイコロの例で考えてみましょう。

サイコロの目が出る確率は以下の通りです。

出る目(x) 1 2 3 4 5 6
確率(p) 1/6 1/6 1/6 1/6 1/6 1/6

出る目の期待値は出る目 * 確率を足し上げたものです。

$ 1 * \frac{1}{6} + 2 * \frac{1}{6} +3 * \frac{1}{6} +4 * \frac{1}{6} +5 * \frac{1}{6} +6 * \frac{1}{6} = 3.5$

サイコロを1回振る際の平均は3.5になると期待できます。

還元率

ギャンブルにも期待値があります。その際掛け金に対して、払い戻される金額の割合を
還元率と言っていたりします。

例えば1000万円払って50%の確率で1500万円、40%で500万円、10%の確率で0円になるギャンブルがあったとします。

期待値(50%×1500万円)+(40%×500万円)+(20%×0円)=950万円

還元率950万円/1000万円95%となります。

こんなギャンブルがあったらやりますか?
やり続ければやり続けるほど、お金が減っていくと思います。

よく言われている国内のギャンブルの還元率は

種類 還元率
競馬 約75%
競輪 約75%
競艇 約75%
オートレース 約75%
宝くじ 約46%
サッカーくじ 約50%
パチンコ 約80~90%

やればやるほどお金が減っていくわけですね。

宣伝費をかけて集客をしても
人が集まれば集まるだけ親が儲かるのですから
たまらない商売ですね。

基本的に還元率が100%を超えるギャンブルは存在し得ないハズです。

もし還元率が100%を超えるギャンブルが有ったとしたら
掛けている側のお金がどんどん増えていきます。

ギャンブルの確率

様々なギャンブルの確率を考えてみましょう。

競馬

競馬は16,18頭だてで着順を当てにいくものです。
当てる着順によって買い方が変わります。

単勝

1着を当てに行きます。

この場合当たる確率は
16頭だて$\frac{1}{16} = 6.25$%
18頭だて$\frac{1}{18} = 5.556$%

複勝

1-3着に入る馬を当てます。

予想した馬が1位でも3位でも良いので
単純に単勝の3倍になります。

この場合当たる確率は
16頭だて$\frac{3}{16} = 18.75$%
18頭だて$\frac{3}{18} = 16.667$%

複勝であれば
6回に1回は当たるという確率ですね。

ただし払い戻しは平均2倍程度なので
あまり美味しくはありません。

枠連

18頭の馬は9の枠に入れられます。
それぞれ1-2頭ほどで構成され
その枠での順位を当てるというものです。

9枠の中から2枠を選ぶというものです。

36通り有るので
$\frac{1}{36} = 2.7778$%

馬連

選んだ2頭が1-2着になる組み合わせで1-2,2-1どちらでも良いという買い方です。

16頭だて$\frac{1}{120} = 0.83333$%
18頭だて$\frac{1}{153} = 0.65359$%

馬単

選んだ2頭が1-2着になる組み合わせで1-2着をそのまま当てる買い方です。

16頭だて$\frac{1}{240} = 0.41667$%
18頭だて$\frac{1}{306} = 0.3268$%

ワイド

3着以内に入る組み合わせのうち2つを
それらの着順に依らず順不同で予想するものです。

1-2 , 1-3 , 2-3着になれば良いので
単純に馬連の3倍の確率になります。

16頭だて$\frac{3}{120} = 2.5$%
18頭だて$\frac{3}{153} = 1.9608$%

3連複

1着・2着・3着になる組み合わせを順不同で予想する
組み合わせ16C3 , 18C3

16頭だて$\frac{1}{560} = 0.17857$%
18頭だて$\frac{1}{816} = 0.12255$%

3連単

1着・2着・3着になる組み合わせを着順通りに予想する
順列16P3, 18P3

16頭だて$\frac{1}{3360} = 0.029762 $%
18頭だて$\frac{1}{4896} = 0.020425 $%

WIN5

JRAが指定する5つのレース
それぞれの1着を予想するものです。
単勝の5乗ですね

18頭だて$\frac{1}{1889568} = 0.0000529221$%

約190万分の1の確率です。

宝くじなどの確率が1000万分の1の確率で同じくらいの金額なので
WIN5の方が期待値は上かと思います。

競馬の確率の高さは

複勝>単勝>枠連>ワイド>馬連>馬単>3連複>3連単>WIN5

になります。

ロトシックス

ロト6は1-43まで数字のうち本数字6個1個のボーナス数字
計7個の数字を選択して当てるもので1-5等まであります。

1等

本数字6個すべて一致 43C6

$\frac{1}{6096454} = 0.0000164030$%

1等は約600万分の1の確率となります。

2等

本数字5個と一致,ボーナス数字1個と一致

$\frac{6}{6096454} = 0.0000984179$%

2等は約100万分の1の確率となります。

3等

6個のうち5個が本数字に一致

$\frac{216}{6096454} = 0.0035430432$%

大雑把に3万分の1くらいの確率です。

4等

6個のうち4個が本数字に一致

$\frac{9990}{6096454} = 0.1638657488 $%

600回に一回くらいは当たる確率ですかね。

5等

6個のうち3個が本数字に一致

$\frac{155400}{6096454} = 2.5490227598 $%

40回に1回くらいの確率ですね。

5等は1000円なので2.5%の確率でしか当たらないので
40回買っても1000円しか戻ってこないのです。

1位がでなければキャリーオーバーで持ち越しになり、金額が増えますが
そもそも600万分の1の確率では人生において当たることはほぼないでしょうね。

ポーカー

ポーカーはトランプ52枚を使ったゲームで役が決まっています。
その役がどれだけ有るのかを求めます。

役は

内容
ロイヤルストレートフラッシュ A-K-Q-J-10
ストレートフラッシュ 連続した数字で(絵柄)
同じスートの5枚のカード
フォーカード 同じランクのカード4枚と他1枚カー
フルハウス 同じランクのカード 3 枚と別の同じランクのカード 2 枚。
フラッシュ 同じスートの 5 枚のカード。
ストレート 連続した数字の 5 枚のカード。
スリーカード 同じランクのカード 3 枚と、ランクの異なる 2 枚のサイドカード。
ツーペア 同じランクのカード 2 枚 1 組が 2 組と、1 枚のサイドカード。
ワンペア 同じランクのカード 2 枚と、ランクの異なる 3 枚のサイドカード。
ハイカード 上記のどれにも当てはまらない手札。ブタ

今回は役を判定するプログラムを作って
全カードの組み合わせからその役がなんなのかを判定して
役の組み合わせ数を求めます。

デッキはカード52枚としてそれを判定する関数を作成し
全52枚の中から5枚を選んだ際の組み合わせから
役が何かを求めて役の個数をカウントします。

# デッキの生成
deck=[b+':'+str(a) for a in range(1,14) for b in ['C','S','D','H']]

# 役の判定
def jadge_role(card):
    s = {}
    for c in card:
        k = int(c.split(':')[1])
        if k in s:
            s[k]+=1
        else:
            s[k] =1
    t = {c.split(':')[0] for c in card}
    n = sorted([c for c in s.keys()])
    if len(t)==1 and all([1 in n,10 in n ,11 in n,12 in n,13 in n]):
        return 'RSF'
    if len(t)==1 and (all([1 in n,10 in n ,11 in n,12 in n,13 in n]) or
             (max(n)-min(n)==4) and len(s)==5):
        return 'SF'
    if 4 in s.values():
        return '4C'
    if 3 in s.values() and 2 in s.values():
        return 'FH'
    if len(t)==1:
        return 'FL'
    if (all([1 in n,10 in n ,11 in n,12 in n,13 in n]) or
             (max(n)-min(n)==4) and len(s)==5):
        return 'ST'
    if 3 in s.values():
        return '3C'
    if list(s.values()).count(2)==2:
        return '2P'
    if list(s.values()).count(2)==1:
        return '1P'
    return 'BT'

# 組み合わせを計算
cards = itertools.combinations(deck,5)
calc_dict = {}
for card in cards:
    role = jadge_role(card)
    if role in calc_dict:
        calc_dict[role] += 1
    else:
        calc_dict[role]  = 1

# 結果
poker_base = math.factorial(52) // (math.factorial(52 - 5) * math.factorial(5))
print(poker_base)
for k,v in sorted(calc_dict.items(),reverse=True,key=lambda x:x[1]):
    print(k,'\t',v,'\t','{0:.10f}%'.format(v/poker_base*100))

2598960

回数 割合
BT 1302540 50.12%
1P 1098240 42.26%
2P 123552 4.75%
3C 54912 2.1128%
ST 10200 0.39246%
FL 5108 0.19654%
FH 3744 0.144057%
4C 624 0.024009%
SF 36 0.001385%
RSF 4 0.0001539%

このような結果になります。

ロイヤルストレートフラッシュは約64万回に1回ほどは出る計算ですね

フラッシュストレートではストレートの方が2倍も出る確率が高いのです。
なのでどちらかを迷う場合は確率の高いストレートを狙うというのが
戦略になるのかもしれませんね。

まとめ

確率、期待値が求められれば、還元率についても計算することができます。
ガチャなどはルーレットゲームなどと一緒なので
確率を求めれば、どれくらいの金額を突っ込めばキャラが当たるのか
シミュレーションできます。

ゲームやガチャなどでは確率、期待値を求めることも多いので
様々な確率の計算方法などを押さえておくといいかもしれません。

君がエンジニアになるまであと36日

作者の情報

乙pyのHP:
http://www.otupy.net/

Youtube:
https://www.youtube.com/channel/UCaT7xpeq8n1G_HcJKKSOXMw

Twitter:
https://twitter.com/otupython

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1