Как детерминировано перетасовать массив с помощью семени?

Мне трудно перетасовать массив детерминистически, то есть со случайным начальным числом в Rust. Чего я пытаюсь достичь (в псевдокоде):

let v = vec![0, 1, 2, 3];
pseudo_shuffle(v, randomSeed1) // always produces e.g. [3,1,2,0]
pseudo_shuffle(v, randomSeed2) // always produces e.g. [0,2,3,1]

В другом ответе на переполнение стека я узнал, как использовать rand::Rng::shuffle() для недетерминированного перемешивания вектора, но, похоже, он не предоставляет API для применения случайного начального числа к функции генерации, и мне трудно придумать решение, которое не использует какой-то нелепый алгоритм сложности n!.


person jonny    schedule 01.05.2018    source источник


Ответы (1)


Используйте генератор случайных чисел, реализующий трейт SeedableRng, и вызовите from_seed с нужным начальным числом.

Пример:

use rand::{seq::SliceRandom, SeedableRng}; // 0.6.5
use rand_chacha::ChaChaRng; // 0.1.1

fn main() {
    let seed = [0; 32];
    let mut rng = ChaChaRng::from_seed(seed);

    let mut v1 = vec![1, 2, 3, 4, 5];
    v1.shuffle(&mut rng);
    assert_eq!(v1, [3, 5, 2, 4, 1]);
}

Клонируйте ГСЧ перед его использованием или создайте новый с нуля с тем же начальным числом, чтобы вернуться к исходному состоянию.

Вас также может заинтересовать ReseedingRng как Что ж.

person Boiethios    schedule 01.05.2018
comment
Полностью упустил эту черту, я пончик. Спасибо большое! - person jonny; 01.05.2018