如何生成范围内的随机数向量?

时间:2018-01-12 01:51:30

标签: vector random rust

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

2 个答案:

答案 0 :(得分:7)

这里有一些主要部分。首先,如何创建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. 的迭代器 处理迭代器时,
  3. .map处理迭代器中的每个项目。
  4. .collect()接受一个迭代器并将其转换为实现FromIterator的任何类型,在您的情况下为Vec
  5. 对您的随机值进行扩展,您可以调整.map函数,使用rand crate的gen_range函数生成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);
    }
    

    On the Playground

    您还应考虑使用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);
    }
    

    On the Playground

答案 1 :(得分:6)

TL; DR:

use rand::{distributions::Uniform, Rng}; // 0.6.5

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而不是简单地执行统一随机数的模数非常重要。有关详细信息,请参阅Why do people say there is modulo bias when using a random number generator?

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

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

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

use rand::Rng; // 0.6.5

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