Come generare numeri casuali in Ruby

Mentre nessun computer può generare numeri veramente casuali, Ruby fornisce l'accesso a un metodo che restituirà pseudocasuale numeri.

Nessun computer può generare veramente numeri casuali puramente per calcolo. Il meglio che possono fare è generare pseudocasuale numeri, che sono una sequenza di numeri che apparire casuale ma non lo sono.

Per un osservatore umano, questi numeri sono davvero casuali. Non ci saranno brevi sequenze ripetitive e, almeno per l'osservatore umano, non presenteranno uno schema chiaro. Tuttavia, dato il tempo e la motivazione sufficienti, l'originale seme può essere scoperto, ricreata la sequenza e indovinato il numero successivo nella sequenza.

Per questo motivo, i metodi discussi in questo articolo probabilmente non dovrebbero essere usati per generare numeri che devono essere crittograficamente sicuri.

I generatori di numeri pseudocasuali devono essere seminato al fine di produrre sequenze che differiscono ogni volta che viene generato un nuovo numero casuale. Nessun metodo è magico: questi numeri apparentemente casuali sono generati usando algoritmi relativamente semplici e aritmetica relativamente semplice. Seminando il PRNG, lo si avvia in un punto diverso ogni volta. Se non lo seminassi, genererebbe ogni volta la stessa sequenza di numeri.

instagram viewer

In Ruby, il Kernel # srand il metodo può essere chiamato senza argomenti. Sceglierà un seme di numero casuale basato sul tempo, l'ID del processo e un numero di sequenza. Semplicemente chiamando srand ovunque all'inizio del programma, ogni volta che lo avvierai genererà una serie diversa di numeri apparentemente casuali. Questo metodo viene chiamato implicitamente all'avvio del programma e esegue il seeding del PRNG con il tempo e l'ID del processo (nessun numero di sequenza).

Una volta che il programma è in esecuzione e Kernel # srand è stato chiamato implicitamente o esplicitamente, il Kernel # rand il metodo può essere chiamato. Questo metodo, chiamato senza argomenti, restituirà un numero casuale compreso tra 0 e 1. In passato, questo numero era in genere ridimensionato al numero massimo che si desidera generare e forse to_i lo chiamò per convertirlo in un numero intero.

Tuttavia, Ruby rende le cose un po 'più semplici se si utilizza Ruby 1.9.x. Il Kernel # rand Il metodo può accettare un singolo argomento. Se questo argomento è a Numerico di qualsiasi tipo, Ruby genererà un numero intero compreso tra 0 e (non incluso) quel numero.

Tuttavia, cosa succede se si desidera generare un numero compreso tra 10 e 15? In genere, si genera un numero compreso tra 0 e 5 e lo si aggiunge a 10. Tuttavia, Ruby lo rende più facile.

Assicurati di prestare attenzione ai due tipi di intervalli. Se hai chiamato rand (10..15), che genererebbe un numero da 10 a 15 Compreso 15. Mentre rand (10... 15) (con 3 punti) genererebbe un numero da 10 a 15 non incluso 15.

A volte è necessaria una sequenza di numeri dall'aspetto casuale, ma è necessario generare sempre la stessa sequenza. Ad esempio, se si generano numeri casuali in un unit test, è necessario generare ogni volta la stessa sequenza di numeri.

Un test unitario che fallisce su una sequenza dovrebbe fallire di nuovo alla successiva esecuzione, se ha generato una sequenza di differenze la volta successiva, potrebbe non fallire. Per farlo, chiama Kernel # srand con un valore noto e costante.

L'implementazione di Kernel # rand è piuttosto non-rubino. Non estrae in alcun modo il PRNG, né consente di creare un'istanza del PRNG. Esiste uno stato globale per il PRNG condiviso da tutto il codice. Se si modifica il seme o si modifica in altro modo lo stato del PRNG, potrebbe avere un intervallo di effetti più ampio di quanto previsto.

Tuttavia, poiché i programmi prevedono che il risultato di questo metodo sia casuale - questo è il suo scopo! - questo probabilmente non sarà mai un problema. Solo se il programma prevede di vedere una sequenza di numeri prevista, come se avesse chiamato srand con un valore costante, dovrebbe vedere risultati inattesi.

instagram story viewer