如何在一个范围内生成随机数向量



如何生成 1 到 20 范围内的 100 个 64 位整数值的向量,允许重复?

这里有一些主要部分。首先,如何创建 100 个计算项的向量?最简单的方法是创建 100 的范围并映射这些项目。例如,您可以执行以下操作:

let vals: Vec<u64> = (0..100).map(|v| v + 1000).collect();
// [1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, ...

拆分一下:

  1. 0..100创建 0 到 99 的迭代器
  2. .map处理迭代
  3. 器时处理迭代器中的每个项。
  4. .collect() 采用迭代器并将其转换为实现FromIterator的任何类型,在您的情况下Vec .

针对随机值进行扩展,您可以使用rand箱的gen_range函数调整.map函数以生成从 0 到 20 的随机值,以在给定范围内创建数值。

use rand::Rng; // 0.6.5
fn main() {
    let mut rng = rand::thread_rng();
    let vals: Vec<u64> = (0..100).map(|_| rng.gen_range(0, 20)).collect();
    println!("{:?}", vals);
}

(在操场上(

您还应考虑使用 rand::distributions::Uniform 类型预先创建范围,这比多次调用gen_range,然后从中提取样本 100 次更有效:

use rand::{distributions::Uniform, Rng}; // 0.6.5
fn main() {
    let mut rng = rand::thread_rng();
    let range = Uniform::new(0, 20);
    let vals: Vec<u64> = (0..100).map(|_| rng.sample(&range)).collect();
    println!("{:?}", vals);
}

(在操场上(

TL;DR:

use rand::{distributions::Uniform, Rng}; // 0.8.0
fn main() {
    let range = Uniform::from(0..20);
    let values: Vec<u64> = rand::thread_rng().sample_iter(&range).take(100).collect();
    println!("{:?}", values);
}

重要的是使用rand::distributions::uniform::Uniform而不是简单地执行统一随机数的取模。请参阅为什么人们说使用随机数生成器时存在模偏差?了解更多详情。

由于我们从一个范围生成多个数字,因此创建一次Uniform并重复使用它的性能更高。创建Uniform会执行一些计算以避免采样偏差。

我们可以使用Rng::sample_iter来创建随机值的迭代器,然后take其中的一些数量,收集到一个Vec中。 collect甚至会利用Iterator::size_hint来分配正确数量的元素。

<小时 />

如果您只需要范围内的一个随机数,则可以使用快捷方式Rng::gen_range

use rand::Rng; // 0.8.0
fn main() {
    let mut rng = rand::thread_rng();
    let value: u64 = rng.gen_range(0..20);
}

如果您需要一个不限于范围的随机值向量,您可以使用Standard分布:

use rand::{distributions::Standard, Rng}; // 0.8.0
fn main() {
    let values: Vec<u64> = rand::thread_rng().sample_iter(Standard).take(100).collect();
    println!("{:?}", values);
}

最新更新