如何在python中模拟偏置模?

时间:2009-01-26 09:37:48

标签: python probability

我想模拟N面偏置模具?

def roll(N,bias):
     '''this function rolls N dimensional die with biasing provided'''
     # do something
     return result

>> N=6
>> bias=( 0.20,0.20,0.15,0.15,0.14,0.16,)
>> roll(N,bias)
   2

9 个答案:

答案 0 :(得分:24)

这里有一点数学。

常规骰子会给出每个数字1-6的概率相等,即1/6。这被称为uniform distribution(它的离散版本,而不是连续版本)。这意味着如果X是描述单个角色结果的随机变量,那么X~U[1,6] - 意味着X将平均分配给掷骰子的所有可能结果,1到6。

这等同于在[0,1)中选择一个数字,同时将其分为6个部分:[0,1/6)[1/6,2/6)[2/6,3/6)[3/6,4/6),{{1 },[4/6,5/6)

您正在请求不同的分发,这是有偏见的。 实现此目的的最简单方法是将[5/6,1)部分分为6个部分,具体取决于您想要的偏差。因此,在您的情况下,您可能希望将其划分为以下内容: [0,1)[0,0.2)[0.2,0.4)[0.4,0.55)0.55,0.7)[0.7,0.84)

如果你看一下wikipedia entry,你会发现在这种情况下,累积概率函数不会由6个等长部分组成,而是由6个部分组成,它们的长度根据不同而不同偏见你给了他们。同样适用于质量分布。

回到问题,根据您使用的语言,只需将其转换回您的掷骰子。在Python中,这是一个非常粗略但虽然有效的例子:

[0.84,1)

答案 1 :(得分:9)

更多语言不可知,但您可以使用查找表。

使用0-1范围内的随机数并在表格中查找值:

0.00 - 0.20   1
0.20 - 0.40   2
0.40 - 0.55   3
0.55 - 0.70   4
0.70 - 0.84   5
0.84 - 1.00   6

答案 2 :(得分:5)

import random

def roll(sides, bias_list):
    assert len(bias_list) == sides
    number = random.uniform(0, sum(bias_list))
    current = 0
    for i, bias in enumerate(bias_list):
        current += bias
        if number <= current:
            return i + 1

偏见将成比例。

>>> print roll(6, (0.20, 0.20, 0.15, 0.15, 0.14, 0.16))
6
>>> print roll(6, (0.20, 0.20, 0.15, 0.15, 0.14, 0.16))
2

也可以使用整数(更好):

>>> print roll(6, (10, 1, 1, 1, 1, 1))
5
>>> print roll(6, (10, 1, 1, 1, 1, 1))
1
>>> print roll(6, (10, 1, 1, 1, 1, 1))
1
>>> print roll(6, (10, 5, 5, 10, 4, 8))
2
>>> print roll(6, (1,) * 6)
4

答案 3 :(得分:3)

有点令人惊讶的是np.random.choice答案在这里没有给出。

from numpy import random 
def roll(N,bias):
    '''this function rolls N dimensional die with biasing provided'''
    return random.choice(np.range(N),p=bias)

p选项给出&#34;与 a &#34;中的每个条目相关联的概率,其中 a 对我们来说是np.range(N)。 &#34;如果没有给出,则样本假定在 a &#34;中的所有条目上均匀分布。

答案 4 :(得分:1)

有关具有不同概率的随机对象,请参阅Walker's alias method的配方。 例如,字符串A B C或D的概率为.1 .2 .3 .4 -

abcd = dict( A=1, D=4, C=3, B=2 )
  # keys can be any immutables: 2d points, colors, atoms ...
wrand = Walkerrandom( abcd.values(), abcd.keys() )
wrand.random()  # each call -> "A" "B" "C" or "D"
                # fast: 1 randint(), 1 uniform(), table lookup
欢呼辞 - 丹尼斯

答案 5 :(得分:0)

只是建议一个更有效(和pythonic3)的解决方案,可以使用bisect来搜索累积值的向量 - 此外可以预先计算并存储,希望后续调用函数将引用同样的“偏见”(按照问题的说法)。

from bisect import bisect
from itertools import accumulate
from random import uniform

def pick( amplitudes ):
    if pick.amplitudes != amplitudes:
        pick.dist = list( accumulate( amplitudes ) )
        pick.amplitudes = amplitudes
    return bisect( pick.dist, uniform( 0, pick.dist[ -1 ] ) )
pick.amplitudes = None

如果没有Python 3累积,可以编写一个简单的循环来计算累积和。

答案 6 :(得分:0)

from random import random
biases = [0.0,0.3,0.5,0.99]
coins = [1 if random()<bias else 0 for bias in biases]

答案 7 :(得分:0)

我为字典创建了一个代码,给出了一个事件和相应的概率,它会返回相应的密钥,即该概率的事件。

import random


def WeightedDie(Probabilities):   


    high_p = 0   
    rand = random.uniform(0,1)

    for j,i in Probabilities.items():
        high_p = high_p + i
        if rand< high_p:
            return j

答案 8 :(得分:0)

我们也可以使用numpy的{​​{1}}发行版

multinomial

如果您要对偏斜的骰子(具有给定的import numpy as np bias = [0.10,0.10,0.15,0.15,0.14,0.16,0.05,0.06,0.04,0.05] # a 10-sided biased die np.where(np.random.multinomial(1, bias, size=1)[0]==1)[0][0]+1 # just 1 roll # 4 概率)滚动bias次,请使用以下函数

n