代码之家  ›  专栏  ›  技术社区  ›  Gen Tan

如何在python中模拟随机相遇

  •  2
  • Gen Tan  · 技术社区  · 6 年前

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

    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 回复  |  直到 6 年前
        1
  •  2
  •   Andrej Kesely    6 年前

    你可以用 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})
    
        2
  •  0
  •   Shan    6 年前

    我的看法是,当结果的映射如下所示时,每个可能性的键都有下限和上限:

    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 例如)或其他范围检查。

        3
  •  0
  •   Zinki    6 年前

    既然你已经有了一本字典,你可以这样做

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

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

    你需要保留 cumulative 计数是你的地图包含绝对概率:结果B将显示60%的时间,但这是滚动范围” 0.1 0.7 ,所以我们需要从结果A中加上10%(感谢您指出@marcus.aurelianus)。