基于每个行动的概率创建一个行动列表

3

我有三个行动和它们的概率:

走路:5

说话:1

奔跑:2

我需要做所有的动作。

但是最重要的动作应该(但不一定)首先执行,并且仅执行一次。

因此,在说话之前,走路有五倍的机会被执行。

如果从未走过路,则不能奔跑。

我的当前解决方案很昂贵,但有效。现在我组成一个列表,将第一个动作插入列表开头:

actions_poll = ['walk']*5 + ['run']*2 + ['talk']*1
flow_control= []
while len(flow_control) != 3:
    action = roll one action from action pool
    if action not in flow_control:
       * check if action is run and walk is in flow control
       flow_control.append(action)

我认为在actions_poll中使用带有数量的列表并不是最好的方法,而且当walk是5000而talk是1时,反复尝试循环可能需要很长时间。

有什么建议吗?


你可以尝试使用random.choices([选项列表], [每个选项对应的概率列表])(Python 3.6或3.7)。 - Reblochon Masque
为什么flow_controls需要最大尺寸为3? - Nikaido
但是最重要的事情应该(但不一定)首先执行,并且仅执行一次。我需要按概率对它们进行排序,但是走路不必总是排在第一位,只需在大多数情况下如此... - Sion C
1
如果你写成 while len(flow_control) != 3,它会在插入三次后停止。我不理解这一部分。因为你说它没有限制,但是...它有!我认为你的意思是 len(set(flow_controls)) != 3(每个动作至少需要在列表中出现一次)。 - Nikaido
不需要set,因为每个操作只会在列表中执行一次。 - Sion C
显示剩余4条评论
1个回答

3
你可以使用np.random.choice来根据它们的概率(使用参数p=)抽样动作,并使用set来检查是否已经对所有动作进行了抽样,就像这样:
import numpy as np

actions = ['walk', 'talk','run']
weights = np.array([5,1,2]) 

flows_control = set()
flows_decision = []
while len(flows_control) < len(actions):
    action = np.random.choice(actions, p=weights/weights.sum(), size=1)[0]
    flows_control.add(action)
    flows_decision.append(action)

如果你希望你的 flows_decision 是一个唯一决策列表,只需执行以下操作:
np.random.choice(actions, p=weights/weights.sum(), size=len(actions), replace=False)

你不应该每次插入操作时都从操作列表中弹出该操作吗? 那性能呢?我仍然看到一个长度条件的 while 循环,而我想避免这种情况。 - Sion C
如果您不想要循环,并且不想让您的操作列表中出现重复项,您应该选择我提出的第二个解决方案。我尝试了10,000个不同的操作,只需要几毫秒就可以完成。 - dtrckd
1
顺便提一下,如果你有像“如果walk从未被看到就不能run”这样的硬性限制,我认为除了循环之外没有其他解决方案,还要添加测试变量(bool或dict)来断言是否已经采取了某些操作。你还可以使用这些测试变量仅在有新操作时将其附加到流程中。 - dtrckd
但问题在于,当一个操作的概率非常小时,它可能会循环数秒钟! - Sion C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接