我想模拟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
答案 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的配方。
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