首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >旋转游戏蒙特卡洛

旋转游戏蒙特卡洛
EN

Stack Overflow用户
提问于 2019-05-20 22:34:53
回答 1查看 88关注 0票数 3

问题:

这里有一个蒙特卡罗挑战问题,考虑下面的游戏,它使用两个旋转盘。假设播放器根据以下规则旋转磁盘上的一个或另一个指针:

  1. 如果玩家旋转指针I并停止在区域p_{ij},他从磁盘i移动到磁盘j (ij是1或2);
  2. 如果指针在区域x_i中停止,则游戏结束;
  3. 如果游戏以区域x_1结束,则玩家获胜,但如果指针在区域x_2中停止,则玩家将输掉。

从磁盘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的代码。

代码语言:javascript
复制
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情况

问题来自于书名为“数字骰子”(PaulJ.Nahim)第27-29页(Theres )

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-21 11:56:07

我对这个问题进行了数学分析,发现解决办法实际上是:

(1 - p_11 - p_12) * (1 - p_22) / ((1 - p_11) * (1 - p_22) - p_12 * p_21) (在某些情况下(例如p_22 = 1)实际上是不正确的)

这实际上是写在附录6的数字骰子书,所以我不会证明它。

用你的数字,它给出了0.65的答案,这是正确的。您的代码发生了很大变化,现在它给出了1.0的输出,而不是问题中所写的内容。在这里,我更正了代码的第一个版本:

代码语言:javascript
复制
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中断。我们可以通过添加额外的标志lost来修复它,这将给出正确的答案。

代码语言:javascript
复制
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)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56229004

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档