【问题标题】:Generating random unsigned integers within a range biased toward the middle在偏向中间的范围内生成随机无符号整数
【发布时间】:2020-01-07 08:25:59
【问题描述】:

我正在尝试在一个非常窄的范围内生成多个随机 u32 整数。我的最大值和最小值都在 1 到 6 之间变化。我想将生成器偏向范围的中间。

我有tried using the Normal distribution from the rand_distr crate,但它似乎适用于浮点数和无限概率,即我想要介于 2 和 5 之间的值,但我可能会得到像 0.81 或 6.92 这样的结果,即使它们相当罕见。我无法在文档中找到Normal 分布的整数版本。我假设它不存在。

我也希望它高效,所以我感觉浮点数的正态分布不会很高效。我还注意到一种称为加权索引的分布,但这需要在每次迭代时手动计算权重。

也许整数值的常规get_range 在生成器运行后可能会以某种方式偏向于算术平均值。有没有人对此有任何有趣的解决方案?

【问题讨论】:

  • 拿一张纸,在一列中写下整数0..99。在另一列中写下分布中的整数,只要你希望它们出现的频率(例如,可能写1 6 次,2 12 次,等等)。现在你有一个函数可以将[0,100) 中的随机整数转换为你想要的分布。
  • 从较小的范围内画两个整数并将它们相加?例如,在 1 到 3 之间画一个,在 1 到 2 之间画另一个,得到一个 1 到 5(含)之间的数字。
  • 二项分布可能是您想要的?它是有界的、整数值的,并且近似于正态分布(在某种数学意义上)docs.rs/rand_distr/0.2.2/rand_distr/struct.Binomial.html

标签: random rust normal-distribution


【解决方案1】:

如果您想从值样本中获得有偏的随机分布,您可以使用rand crate 的rand::distributions::weighted::WeightedIndex 通过定义样本中每个项目的权重来精细控制您的偏差。

use rand::prelude::*;
use rand::distributions::WeightedIndex;

fn main(){

    let mut rng = thread_rng();
    //item value and it's weight increasing till middle and then decreasing till end
    let sample_item = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 3), ('f', 2), ('g', 1)];


    let weight_dist = WeightedIndex::new(sample_item.iter().map(|(_, weight)| weight)).unwrap();

    let mut pool = vec![];

    for _ in 1..100{
        let item = sample_item[weight_dist.sample(&mut rng)];
        pool.push(item.0);
    }
    println!("{:?}", pool.iter().filter(|x| **x == 'a').count());
    println!("{:?}", pool.iter().filter(|x| **x == 'b').count());
    println!("{:?}", pool.iter().filter(|x| **x == 'c').count());
    println!("{:?}", pool.iter().filter(|x| **x == 'd').count());
    println!("{:?}", pool.iter().filter(|x| **x == 'e').count());
    println!("{:?}", pool.iter().filter(|x| **x == 'f').count());
}

你可以试试代码here

【讨论】:

    【解决方案2】:

    粗略的解决方案:从区间上的均匀分布中取 2 个数字并使用平均值。

    它会给出这样的分布:_/\_

    要进行更细粒度的控制,您需要一些逐步插值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-30
      • 2010-09-22
      相关资源
      最近更新 更多