簡體   English   中英

旋轉游戲蒙特卡洛

[英]A spin game monte carlo

問題:

這是一個小小的蒙特卡羅挑戰問題,請考慮以下游戲,該游戲使用兩個微調器磁盤。 假設播放器根據以下規則旋轉磁盤上的一個或另一個指針:

  1. 如果玩家旋轉指針i並且它在區域p_{ij}的區域停止,則他從磁盤i移動到磁盤jij是1或2);

  2. 如果指針在區域x_i的區域停止,則游戲結束;

  3. 如果游戲在區域x_1的區域結束,則玩家獲勝,但如果指針在區域x_2的區域停止,則玩家輸掉。

從磁盤1開始,玩家獲勝的概率是多少? 假設每個磁盤的面積為1,因此x_1+p_{11}+p_{12} =1 ,以及x_2+p_{21}+p_{22} =1

針對p_{11} =0.2p_{12} =0.4p_{21} =0.3p_{22} =0.35的情況運行代碼。

import random
p_11 = 0.2
p_12 = 0.4 #0.2+0.4
p_21 = 0.3
p_22 = 0.35


wins = 0
pointer = 0
pointer2 = 0
for i in range(10**7):
    while pointer < p_11:
        pointer2 = 0    #resetting pointer2
        pointer = random.uniform(0,1)
        if p_11+p_21  < pointer < 1:  #area corresponding to x_1
            wins += 1  #wins
            pointer = 0  
            break
        else:
            pointer = 0  #resetting pointer1
            while pointer2 < p_22:
                pointer2 = random.uniform(0,1)
                if p_22+p_21 < pointer2 < 1:  #area corresponding to x_2
                    pointer2 = 0
                    break  #loses

print(wins/10**7)

正確的答案是0.5821,但我得到0.7141465。 我哪里做錯了?

我編輯了我的代碼,在這種情況下,它再次為p_22p_11情況p_22磁盤

在此輸入圖像描述

這個問題來自於名為Digital Dice(Paul J. Nahim)的書第27-29頁(Theres a pdf)

我已經用數學方法分析了這個問題並發現解決方案實際上是:

(1 - p_11 - p_12) * (1 - p_22) / ((1 - p_11) * (1 - p_22) - p_12 * p_21) (在某些p_22 = 1情況下實際上不正確(例如p_22 = 1 ))

這實際上寫在數字骰子書的附錄6中,所以我不會證明這一點。

使用您的數字,它給出了0.65的答案,這是正確的。 你的代碼發生了很大的變化,現在它的輸出為1.0而不是問題中的內容。 在這里,我更正了您的代碼的第一個版本:

import random


p_11 = 0.2
p_12 = 0.4
p_21 = 0.3
p_22 = 0.35

total_iterations = 10 ** 6

wins = 0
num = 0
for i in range(total_iterations):
    current_disk = 1
    while True:
        num = random.uniform(0, 1)
        if current_disk == 1:
            if num < p_12:
                current_disk = 2
                continue
            elif num > p_11 + p_12:
                wins += 1  #wins
                break
        else:
            if num < p_21:
                current_disk = 1
                continue
            elif num > p_21 + p_22:
                break

print(wins / total_iterations)
print((1 - p_11 - p_12) * (1 - p_22) / ((1 - p_11) * (1 - p_22) - p_12 * p_21))

現在關於你當前的代碼。 這是錯誤的,因為break # loses while pointer2 < p_22 while pointer < p_11從循環while pointer2 < p_22 ,而不是while pointer < p_11從循環while pointer < p_11 我們可以通過添加額外的標志lost來修復它,這將給你正確的答案。

import random
p_11 = 0.2
p_12 = 0.4 #0.2+0.4
p_21 = 0.3
p_22 = 0.35


wins = 0
pointer = 0
pointer2 = 0
for i in range(10**6):
    while pointer < p_11:
        pointer2 = 0    #resetting pointer2
        pointer = random.uniform(0,1)
        if p_11+p_21  < pointer < 1:  #area corresponding to x_1
            wins += 1  #wins
            pointer = 0  
            break
        else:
            pointer = 0  #resetting pointer1
            lost = False
            while pointer2 < p_22:
                pointer2 = random.uniform(0,1)
                if p_22+p_21 < pointer2 < 1:  #area corresponding to x_2
                    pointer2 = 0
                    lost = True
                    break  #loses
            if lost:
                break

print(wins/10**6)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM