3.9 随机过程
2 分钟阅读
你可能注意到 Distribution trait 不允许修改 self(没有 &mut self 方法)。这是有意为之:概率分布定义为将事件映射到概率。
相比之下,随机过程关心以随机方式变化的一族变量(或状态)。
我们不试图定义涵盖随机过程的通用 API,也不提供直接支持来建模它们。此处仅讨论其中一些。
无放回抽样
例如,给定一袋 10 颗红弹珠和 30 颗绿弹珠,从袋中抽取的弹珠为红色的初始概率是 10/(10 + 30) = ¼ = 0.25。若第一颗弹珠是红色且未放回,则第二颗为红色的概率是 9/(9 + 30) = 3/13 ≅ 0.23。
rand crate 不提供支持逐步无放回抽样的系统。它提供的是一步从序列中抽取多个不同值的支持:
IteratorRandom::choose_multiple 和 SliceRandom::choose_multiple。
若需自行实现逐步抽样,以下是一些思路:
- 将所有元素放入
Vec。每步采样并移除一个值。注意若所有可能元素的集合很大,这效率低下,因为Vec::remove是O(n),且必须构造所有元素。 - 将所有元素放入
Vec并洗牌。每步直接取下一个元素。 - 构造从初始分布采样值的方法,外加表示「已取」值的空
HashSet。每步采样一个值;若在HashSet中则拒绝并重新采样,否则在HashSet中放入副本并返回。注意除非采样数量远小于可用元素数量,否则此方法效率低下。 - 研究
src/seq/index.rs:使用了若干抽样算法,可调整用于此应用。