Как сгенерировать случайное число Rust в диапазоне без смещения? - PullRequest
0 голосов
/ 22 сентября 2018

Как вы генерируете случайный бросок костей в Rust?

Я знаю, что могу использовать rand::random, но для этого нужно, чтобы я сгенерировал значение целочисленного типа.Использование rand::random<u8>() % 6 приводит к смещению.

Ответы [ 2 ]

0 голосов
/ 22 сентября 2018

Используйте Rng::gen_range для одноразового значения:

use rand::{self, Rng}; // 0.6.4

fn main() {
    let mut rng = rand::thread_rng();

    let die = rng.gen_range(1, 7);

    println!("The die was: {}", die);
}

Под капотом это создает структуру Uniform.Создайте эту структуру самостоятельно, если вы будете получать несколько случайных чисел:

use rand::{
    self,
    distributions::{Distribution, Uniform},
}; // 0.6.4

fn main() {
    let mut rng = rand::thread_rng();
    let die_range = Uniform::new_inclusive(1, 6);

    let die = die_range.sample(&mut rng);

    println!("{}", die);
}

Uniform выполняет некоторые предварительные вычисления, чтобы выяснить, как отобразить полный диапазон случайных значений в желаемый диапазон без внесения смещения.Он переводит и изменяет размер вашего исходного диапазона, чтобы наиболее точно соответствовать диапазону генератора случайных чисел, отбрасывает любые случайные числа, которые выходят за пределы этого нового диапазона, затем изменяет размеры и переводит обратно в исходный диапазон.

См. Также:

0 голосов
/ 22 сентября 2018

Вы правы, что смещение введено;всякий раз, когда вы хотите отобразить из набора A в набор B, где количество элементов набора B не является множителем или кратным множеству набора A, вы будете иметь смещение.

В вашем случае 42*6=252.Таким образом, вы можете просто выбросить любые u8 значения 252 или более (и снова вызвать random).

Затем ваш вывод можно безопасно отобразить с помощью оператора модуля.Наконец, добавьте 1, чтобы получить стандартный [1,6] результат игры в кости.

Может показаться нечистым снова вызвать случайный вызов, но нет способа отобразить набор из 256 значений в набор из 6 без введения смещения.

Редактировать: похоже, что у ящика с рандом есть что-то, что учитывает смещение: https://docs.rs/rand/latest/rand/distributions/uniform/struct.Uniform.html

...