抛硬币模拟意想不到的概率
Coin tossing simulation unexpected probabilities
这是我编写的脚本,用于模拟以给定的固定结果序列结束的投币游戏(投掷结果为 1 或 0)。这个固定的顺序是游戏的特点。例如,coin_series('01'
) 模拟一系列抛掷,最终以 0
结束,然后是 1
;有效结果是 x01
,其中 x
是一串零和不包含模式 01
的字符串。
脚本给出了终止两场比赛所需的投掷次数,01
和 11
,这应该有相同的结果,因为硬币不是有偏见的(结果机会均等)零或结果一折腾)。
然而事实并非如此,我的输出分别是6和4,其中只有第一个是正确的。所以我一定是脚本中有错误。
我的问题是:如何使脚本更简洁一点,希望这有助于找到错误;其次,是否存在除我以外所有人都知道的错误?
import numpy as np
class coin_series(object):
def __init__(self,win_state): #win_state is a string of ones and zeroes
self.win_state=win_state
self.d=self.draw()
self.series=[self.d.next() for i in range(len(self.win_state))]
self.n=len(self.win_state)
while not self.check():
self.play()
def draw(self):
while True:
t=np.random.rand()
if t>=0.5:
yield 1
else:
yield 0
def check(self):
return(self.win_state==''.join(map(str,self.series)))
def play(self):
self.series=self.series[1:]+[self.d.next()]
self.n+=1
if __name__=='__main__':
print np.mean([coin_series('11').n for i in range(100000)])
print np.mean([coin_series('01').n for i in range(100000)])
这不是错误,您的代码工作正常!
当你抛硬币时,如果你的目标是0
,那么你的目标是1
,你得到了0
,但1
最终变成了另一个0
,那么你已经走到一半了,你只是希望再次获得1
。
另一方面,如果您的目标是 1
,然后是 1
并取得 1
,那么如果您不取得第二个 [=11] =],您现在正在 0
并返回等待第一个 1
。
所以换一种说法,在第一种情况下,如果你失败了,你只会在中途重置,但在第二种情况下,如果你失败了,那么你又回到了起点——从而提高了平均水平得到它们的投掷次数。
看看 this redit post 的另一种解释。
没有错误。您需要生成 单独的翻转对 才能使这些值相等。如果您生成连续的翻转序列并查看重叠对,11
平均比 01
.
花费更长的时间
这是我编写的脚本,用于模拟以给定的固定结果序列结束的投币游戏(投掷结果为 1 或 0)。这个固定的顺序是游戏的特点。例如,coin_series('01'
) 模拟一系列抛掷,最终以 0
结束,然后是 1
;有效结果是 x01
,其中 x
是一串零和不包含模式 01
的字符串。
脚本给出了终止两场比赛所需的投掷次数,01
和 11
,这应该有相同的结果,因为硬币不是有偏见的(结果机会均等)零或结果一折腾)。
然而事实并非如此,我的输出分别是6和4,其中只有第一个是正确的。所以我一定是脚本中有错误。
我的问题是:如何使脚本更简洁一点,希望这有助于找到错误;其次,是否存在除我以外所有人都知道的错误?
import numpy as np
class coin_series(object):
def __init__(self,win_state): #win_state is a string of ones and zeroes
self.win_state=win_state
self.d=self.draw()
self.series=[self.d.next() for i in range(len(self.win_state))]
self.n=len(self.win_state)
while not self.check():
self.play()
def draw(self):
while True:
t=np.random.rand()
if t>=0.5:
yield 1
else:
yield 0
def check(self):
return(self.win_state==''.join(map(str,self.series)))
def play(self):
self.series=self.series[1:]+[self.d.next()]
self.n+=1
if __name__=='__main__':
print np.mean([coin_series('11').n for i in range(100000)])
print np.mean([coin_series('01').n for i in range(100000)])
这不是错误,您的代码工作正常!
当你抛硬币时,如果你的目标是0
,那么你的目标是1
,你得到了0
,但1
最终变成了另一个0
,那么你已经走到一半了,你只是希望再次获得1
。
另一方面,如果您的目标是 1
,然后是 1
并取得 1
,那么如果您不取得第二个 [=11] =],您现在正在 0
并返回等待第一个 1
。
所以换一种说法,在第一种情况下,如果你失败了,你只会在中途重置,但在第二种情况下,如果你失败了,那么你又回到了起点——从而提高了平均水平得到它们的投掷次数。
看看 this redit post 的另一种解释。
没有错误。您需要生成 单独的翻转对 才能使这些值相等。如果您生成连续的翻转序列并查看重叠对,11
平均比 01
.