[英]A spin game monte carlo
問題:
這是一個小小的蒙特卡羅挑戰問題,請考慮以下游戲,該游戲使用兩個微調器磁盤。 假設播放器根據以下規則旋轉磁盤上的一個或另一個指針:
如果玩家旋轉指針i並且它在區域p_{ij}
的區域停止,則他從磁盤i
移動到磁盤j
( i
和j
是1或2);
如果指針在區域x_i
的區域停止,則游戲結束;
如果游戲在區域x_1
的區域結束,則玩家獲勝,但如果指針在區域x_2
的區域停止,則玩家輸掉。
從磁盤1開始,玩家獲勝的概率是多少? 假設每個磁盤的面積為1,因此x_1+p_{11}+p_{12} =1
,以及x_2+p_{21}+p_{22} =1
針對p_{11} =0.2
, p_{12} =0.4
, p_{21} =0.3
和p_{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_22
和p_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.