如何模拟有偏硬币的翻转?

Posted

技术标签:

【中文标题】如何模拟有偏硬币的翻转?【英文标题】:How do I simulate flip of biased coin? 【发布时间】:2010-10-03 09:31:57 【问题描述】:

在无偏掷硬币中,H 或 T 出现 50% 的次数。

但我想模拟硬币,它给出概率为“p”的 H 和概率为“(1-p)”的 T。

类似这样的:

def flip(p):
   '''this function return H with probability p'''
   # do something
   return result

>> [flip(0.8) for i in xrange(10)]
[H,H,T,H,H,H,T,H,H,H]

【问题讨论】:

【参考方案1】:
import random
def flip(p):
    return (random.random() < p)

这会返回一个布尔值,然后您可以使用它来选择您想要的 H 或 T(或在任意两个值之间进行选择)。您还可以在方法中包含选项:

def flip(p):
    if random.random() < p:
        return 'H'
    else:
        return 'T'

但这样一般用处不大。

【讨论】:

【参考方案2】:

导入一个0-1之间的随机数(可以使用randrange函数)

如果数字大于 (1-p),则返回尾部。

否则,返回头

【讨论】:

【参考方案3】:

random.random() 返回 [0, 1) 范围内的均匀分布伪随机浮点数。此数字小于范围 [0,1) 中的给定数字 p,概率为 p。因此:

def flip(p):
    return 'H' if random.random() < p else 'T'

一些实验:

>>> N = 100
>>> flips = [flip(0.2) for i in xrange(N)]
>>> float(flips.count('H'))/N
0.17999999999999999  # Approximately 20% of the coins are heads

>>> N = 10000
>>> flips = [flip(0.2) for i in xrange(N)]
>>> float(flips.count('H'))/N
0.20549999999999999  # Better approximation 

【讨论】:

【参考方案4】:

您希望“偏差”基于对称分布吗?或者可能是指数分布?高斯有人吗?

嗯,这里是所有方法,从随机文档本身中提取。

首先,三角分布的例子:

print random.triangular(0, 1, 0.7)

random.triangular(low, high, mode)

返回一个随机浮点数N 使得low &lt;= N &lt; high 和 与那些之间的指定模式 界限。 lowhigh 边界 默认为 一个mode 参数默认为中点 在边界之间,给出一个对称的 分布。

random.betavariate(alpha, beta)

测试版分发。参数条件为alpha &gt; 0beta &gt; 0。返回值介于01 之间。

random.expovariate(lambd)

指数分布。 lambd1.0 除以所需的平均值。这应该 是非零。 (参数将是 称为“lambda”,但这是一个 Python 中的保留字。)返回 值范围从0正 无穷大 如果lambd 是正数,并且 如果lambd,则从负无穷大0 是否定的。

random.gammavariate(alpha, beta)

伽马分布。 (不是伽马 功能!)上的条件 参数为alpha &gt; 0beta &gt; 0

random.gauss(mu, sigma)

高斯分布。 mu 是平均值,sigma 是标准 偏差。这稍微快一点 比normalvariate() 函数 定义如下。

random.lognormvariate(mu, sigma)

对数正态分布。如果你拿 这个的自然对数 分布,你会得到一个正常的 平均分布mu 和标准 偏差sigmamu 可以有任何 值,并且sigma 必须大于

random.normalvariate(mu, sigma)

正态分布。 mu 是平均值, sigma 是标准差。

random.vonmisesvariate(mu, kappa)

mu 是平均角度,表示为 02*pikappa 之间的弧度 是浓度参数,其中 必须大于或等于。 如果kappa 等于,则此 分布简化为均匀分布 在02*pi 范围内的随机角度。

random.paretovariate(alpha)

帕累托分布。 alpha 是 形状参数。

random.weibullvariate(alpha, beta)

威布尔分布。 alpha 是 比例参数和beta 是形状 参数。

【讨论】:

【参考方案5】:

怎么样:

import numpy as np
n, p = 1, .33  # n = coins flipped, p = prob of success
s = np.random.binomial(n, p, 100)

【讨论】:

【参考方案6】:

也可以使用sympyX ~ Bernoulli(p) 分布nsamples 中采样:

from sympy.stats import Bernoulli, sample_iter
list(sample_iter(Bernoulli('X', 0.8), numsamples=10)) # p = 0.8 and nsamples=10
# [1, 1, 0, 1, 1, 0, 1, 1, 1, 1]

返回 'H''T' 代替使用

def flip(p, n):
    return list(map(lambda x: 'H' if x==1 else 'T', sample_iter(Bernoulli('X', p), numsamples=n)))

print(flip(0.8, 10)) # p = 0.8 and nsamples=10
# ['H', 'H', 'T', 'H', 'H', 'T', 'H', 'H', 'H', 'H']

【讨论】:

【参考方案7】:
import random
def flip():
    return ["H" if random.randint(0,3) <= 2 else "T" for i in range(10)]

现在正面的概率是 75%,反面的概率是 25%(0,1,2 都是正面,只有 3 是反面)。通过使用 random.randint(),您可以在保持随机性的同时有任何偏差概率。

【讨论】:

以上是关于如何模拟有偏硬币的翻转?的主要内容,如果未能解决你的问题,请参考以下文章

硬币翻转指令

LQ0224 翻硬币模拟

P1146 硬币翻转

luogu P1146 硬币翻转

洛谷——P2708 硬币翻转

P1146 硬币翻转