Генерация случайных чисел в диапазоне, смещенном к середине - PullRequest
2 голосов
/ 07 января 2020

Я пытаюсь сгенерировать несколько случайных целых чисел без знака между двумя изменяющимися (очень маленькими) целочисленными значениями без знака (максимальное и минимальное варьируются между 1 и 6 на самом деле). Я хотел бы сместить генератор к середине диапазона.

Я пытался использовать Normal дистрибутив из rand_distr ящика , но, похоже, это для поплавков и неограниченных сверх вероятности, т.е. я хочу значения от 2 до 5, но я потенциально может получить результат, например, 0,81 или 6,92, даже если они довольно редки. Я не смог найти целую версию дистрибутива Normal в документации. Я предполагаю, что его не существует.

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

Возможно, регулярный get_range для целочисленных значений может быть как-то арифметически смещен к среднему значению после запуска генератора. У кого-нибудь есть интересные решения для этого?

Ответы [ 2 ]

1 голос
/ 07 января 2020

Необработанное решение: возьмите 2 числа из равномерного распределения за интервал и используйте среднее значение.

Это даст распределение следующим образом: _ / \ _

Для более точного контроля Вам нужна пошаговая интерполяция.

0 голосов
/ 09 января 2020

Если вы хотите получить смещенное случайное распределение из выборки значений, вы можете использовать rand ящика 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());
}

Вы можете попробовать код здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...