2012-04-25 20 views

risposta

22

Per generare un elenco di 1000 elementi con numeri casuali compreso tra 1 e 10:

[rand:uniform(10) || _ <- lists:seq(1, 1000)]. 

Cambio 10 e 1000 per i numeri appropriati. Se ometti il ​​10 dalla chiamata rand:uniform, otterrai un numero a virgola mobile casuale compreso tra 0.0 e 1.0.

Nelle versioni di Erlang inferiore a 18.0: Utilizzare invece il modulo random. Attenzione! È necessario eseguire random:seed/3 prima di utilizzarlo per processo, per evitare di ottenere gli stessi numeri pseudo casuali.

+4

Questa è una buona idea da eseguire casualmente: seed (now()). prima di quello – fycth

+0

** non ** otterrà "numeri casuali veri" da un generatore di numeri pseudo-casuali seminato con l'ora corrente. Non saranno crittograficamente sicuri. Quello che intendi è che ogni processo dovrebbe usare il proprio seme, in modo che non ottengano gli stessi numeri pseudo-casuali. –

+0

@FilipHaglund Grazie, corretto. –

13

Assicurarsi di seminare in modo appropriato.

> F = fun() -> io:format("~p~n", [[random:uniform(10) || _ <- lists:seq(1, 10)]]) end. 
> spawn(F). 
[1,5,8,10,6,4,6,10,7,5] 
> spawn(F). 
[1,5,8,10,6,4,6,10,7,5] 

Il tuo intuito è che i risultati sarebbero diversi. Un seme casuale in Erlang è specifico del processo. Tuttavia, il seme predefinito è stato risolto. Ecco perché ottieni lo stesso risultato anche se nell'esempio sono presenti due processi.

> G = fun() -> {A1,A2,A3} = now(), 
       random:seed(A1, A2, A3), 
       io:format("~p~n", [[random:uniform(10) || _ <- lists:seq(1, 10)]]) 
     end. 
> spawn(G). 
[3,1,10,7,9,4,9,2,8,3] 
> spawn(G). 
[9,1,4,7,8,8,8,3,5,6] 

Nota che se il valore di ritorno della now() è la stessa in due processi differenti si finisce con lo stesso problema di cui sopra. Questo è il motivo per cui alcune persone amano usare uno gen_server per avvolgere la generazione di numeri casuali. In alternativa puoi usare semi migliori.

+4

'now()' tuttavia non garantisce mai lo stesso risultato due volte nello stesso nodo. –

+4

Ci sono altri generatori di numeri casuali più forti nel modulo 'crypto' (si veda [http://www.erlang.org/doc/man/crypto.html](http://www.erlang.org/doc/man/ crypto.html)) – Tilman

2

sarò più che felice di ottenere anche un sito che sarò in grado di leggere lì. Grazie.

Si consiglia di verificare Learn You Some Erlang che guiderà l'utente attraverso la lingua.

2

Il generatore di numeri pseudocasuali dal modulo di crittografia funziona meglio crypto:rand_uniform(From, To).
Per generare un elenco di 1000 elementi con numeri casuali compreso tra 1 e 10:

crypto:start(), 
[crypto:rand_uniform(1, 10) || _ <- lists:seq(1, 1000)].