Genera arrays random con suffisso predicibile

COSÌ,

Il problema

È ben noto sui numbers pseudo-casuali . "Pseudo" in realtà significa che, nonostante siano casuali (cioè imprevedibili) in generale, saranno uguali in sequenza, in cui è stato utilizzato lo stesso valore di init del generatore. Ad esempio, in PHP c'è la function mt_srand () per farlo. Esempio:

mt_srand(1); var_dump(mt_rand(), mt_rand(), mt_rand()); 

-non import, quante volte avremo lanciato il nostro script: i tre numbers generati saranno sempre gli stessi in sequenza.

Ora, il mio problema è come fare lo stesso – ma per mischiare l'arrays. Vale a dire, voglio creare una function, che accetterà arrays di input per shuffle e seed . Nello stesso shuffling del valore di seme deve avere lo stesso ordine consecutivo. Cioè, chiamiamo la function shuffleWithSeed() – e in seguito dovrebbe funzionare per each avvio di script:

 $input = ['foo', 'bar', 'baz']; $test = shuffleWithSeed($input, 1000);//1000 is just some constant value var_dump($test); //let it be ['bar', 'foo', 'baz'] $test = shuffleWithSeed($test, 1000); var_dump($test); //let it be ['baz', 'foo', 'bar'] $test = shuffleWithSeed($test, 1000); var_dump($test); //let it be ['baz', 'bar', 'foo'] //... 

-e non import quante volte faremo shuffle per il nostro arrays – Voglio che il prossimo ordine di avvio dello script sia sempre lo stesso all'interno di un valore di seed .

Il mio approccio

Ho in mente questo algorithm:

  1. Inizializza il generatore di numbers casuali con seed passato
  2. Genera N numbers casuali, where N è il numero di $input membri di $input
  3. Ordina i numbers dal passaggio 2
  4. Fare in modo che i numbers corrispondenti dipendano da $input tasti di $input .

L'ho implementato in:

 function shuffleWithSeed(arrays $input, $seed=null) { if(!isset($seed)) { shuffle($input); return $input; } if(!is_int($seed)) { throw new InvalidArgumentException('Invalid seed value'); } mt_srand($seed); $random = []; foreach($input as $key=>$value) { $random[$key] = mt_rand(); } asort($random); $random = arrays_combine(arrays_keys($random), arrays_values($input)); ksort($random); return $random; } 

-ora, abbiamo anche trovato l'algorithm Fisher-Yates – ma non sono sicuro se possa funzionare con numbers pseudocasuali (cioè con seme)

La domanda

Come puoi vedere, sto facendo due tipi nella mia function: prima con i valori e poi con i tasti.

  • Questo può essere fatto con un solo tipo? O senza alcun tipo? L'arrays di input potrebbe essere grande, quindi voglio evitare questo.
  • Tuttavia, potrebbe essere il mio algorithm non sta bene? Se sì, quali altre opzioni potrebbero essere suggerite?

Ecco una copia e incolla di una function che ho implementato qualche tempo fa esattamente per questo scopo:

 /** * Shuffles an arrays in a repeatable manner, if the same $seed is provided. * * @param arrays &$items The arrays to be shuffled. * @param integer $seed The result of the shuffle will be the same for the same input ($items and $seed). If not given, uses the current time as seed. * @return void */ protected function seeded_shuffle(arrays &$items, $seed = false) { $items = arrays_values($items); mt_srand($seed ? $seed : time()); for ($i = count($items) - 1; $i > 0; $i--) { $j = mt_rand(0, $i); list($items[$i], $items[$j]) = arrays($items[$j], $items[$i]); } } 

Implementa un semplice rimescolamento di Fisher-Yates con un generatore di numbers casuali seminato.