我有一些随机结果,我想模拟随机结果。
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
格式。如果可能的话,我想维护一个主要的“结果映射”字典,以便在我的函数中引用。
答案 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
)或其他范围检查。