如何在python中模拟随机遭遇

时间:2018-07-23 06:57:29

标签: python

我有一些随机结果,我想模拟随机结果。

outcomes_mapping = {0.10:"Outcome A", 0.60:"Outcome B", 0.30:"Outcome C"}

结果A应该在10%的时间发生,结果B在60%的时间发生,结果C在30%的时间发生。

当前,我的解决方案是这样的:

def random_encounter():
    roll = np.random.rand()        
    if roll <= 0.1:
         return "Outcome A"
    if roll > 0.1 and roll <=0.6:
         return "Outcome B"

有一些更聪明的方法吗?我的解决方案显然涉及很多硬编码。我应该使用累积概率吗?即使我这样做了,我的函数仍将采用if roll > 0.1, return this, else return that格式。如果可能的话,我想维护一个主要的“结果映射”字典,以便在我的函数中引用。

3 个答案:

答案 0 :(得分:2)

您可以在weights中使用random.choices参数:

from collections import Counter
import random

outcomes_mapping = {0.10:"Outcome A", 0.60:"Outcome B", 0.30:"Outcome C"}

c = Counter()
for i in range(1000):
    c.update( random.choices([*outcomes_mapping.values()], weights=outcomes_mapping.keys()) )

print(c)

打印:

Counter({'Outcome B': 596, 'Outcome C': 317, 'Outcome A': 87})

答案 1 :(得分:0)

由于您已经具有包含值的字典,因此可以执行类似

的操作
cumulative = 0
for k in outcomes_mapping: 
    cumulative += k
    if roll <= cumulative:
        return outcomes_mapping[k]

这样,您只需在更改或添加值时更新字典。

您需要保持cumulative计数的原因是您的地图包含绝对概率:结果B将显示60%的时间,但是范围是从“ 0.1到{{1 }}”,因此我们需要从结果A中添加10%(感谢您指出@ marcus.aurelianus)。

答案 2 :(得分:0)

当结果映射如下所示时,我的看法是:对于每种可能性,键分别保持上下限:

mapping = {(0.0, 0.1) : "A", (0.1, 1) : "B"}

def roll(mapping, roll):
    for limit, val in mapping.items():
        if limit[0] < roll <= limit[1]:
            return val

输出:

roll(mapping, 0.1)
'A'

roll(mapping, 0.2)
'B'

根据您想要的范围以及滚动的输入值,您可以使用稍微更改的映射(例如,从0.0-0.1)或其他范围检查。