Numero casuale C ++ tra 0 e 1

Numero casuale C ++ tra 0 e 1
Un numero casuale viene generato in un intervallo, da un numero minimo a un numero massimo. Supponiamo che questi numeri minimi e massimi siano maggiori di 1. Lascia che il numero generato all'interno dell'intervallo sia num. Lascia che il numero minimo sia min e lascia che il numero massimo sia massimo. Con questi, per convertire il numero tra 0 e 1, utilizzare la formula:
random_number = (num - min)/(max - min)

Random_number dovrebbe ora essere tra 0 e 1.
Le prossime domande sono come generare numeri casuali e come decidere min e max. In effetti, i numeri casuali, come descritto dalle specifiche C ++ 20, sono in realtà numeri pseudo-casuali. La specifica C ++ 20 fornisce una guida alla produzione di numeri veramente casuali (numeri casuali non deterministici). Il problema con questo generatore di numeri veramente casuale è che la responsabilità del compilatore, o il programmatore, è fornire l'algoritmo a ciò che è considerato la generazione di numeri casuali non deterministici. Questo articolo non affronta numeri casuali non determinanti.

I numeri pseudo-casuali sono generati in una sequenza (un ordine) di numeri, che sembrano numeri casuali. La generazione di un numero casuale ha bisogno di quello che viene chiamato seme. Il seme è un valore iniziale. Questo articolo spiega le basi della generazione di numeri casuali in C ++ 20. Se il numero risultante è maggiore di 1, viene portato tra 0 e 1, usando la formula sopra. La libreria C ++ deve essere inclusa nel programma per avere una sequenza di numeri casuali o casuali.

Contenuto dell'articolo

  • Distribuzioni
  • linear_congruential_engine
  • default_random_engine
  • Classi di distribuzione dei numeri casuali
  • Migliore numero casuale
  • Conclusione

Distribuzioni
Distribuzione uniforme

Una distribuzione uniforme è quella in cui la probabilità di un numero è uno del numero totale di numeri nella sequenza. Considera la seguente sequenza:

0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100

Se questi undici numeri sono una sequenza di numeri casuali, ogni numero è apparso una volta su undici eventi. Ciò significa che è una distribuzione uniforme. In pratica, non tutto può apparire una volta. Uno o due o tre possono apparire più di una volta e non apparirebbero in ordine regolare.

Se il numero casuale restituito è 40, il programma deve convertire il numero casuale tra 0 e 1 usando

random_number = (40 - 0)/(100 - 0)
= 4/10 = 0.4

Qui, Num è 40; min è 0 e max è 100.

Distribuzione binomiale

La distribuzione binomiale non è una distribuzione uniforme. "Bi", il prefisso del binomiale, significa due. Il numero di valori nella distribuzione binomiale è rappresentato da t in c++. Se i numeri BI interessati per la distribuzione sono 2 e 3 e se T è 1, allora la sequenza è:

2, 3

Se t è 2 per gli stessi numeri BI (2 e 3), allora la sequenza diventa,

4, 12, 9

Se T è 3 per gli stessi numeri BI (2 e 3), allora la sequenza diventa,

8, 36, 54, 27

Se T è 4 per gli stessi numeri BI (2 e 3), allora la sequenza diventa,

16, 96, 216, 216, 81

T è un intero positivo che può essere più di 4. Per ogni valore di T, ci sono elementi T+1 nella sequenza. Una sequenza dipende dai numeri BI scelti e dal valore di T. I numeri BI possono essere qualsiasi coppia, E.G., 13 e 17. Anche la somma dei numeri BI è importante. Una sequenza è sviluppata da quello che è noto come teorema binomiale.

Ci sono altre distribuzioni nella libreria casuale in C++.

linear_congruential_engine

Ci sono un numero di motori a numero casuale in C++. linear_congruential_engine è uno di questi. Questo motore prende un seme, lo moltiplica con un moltiplicatore e aggiunge un numero C costante al prodotto per avere il primo numero casuale. Il primo numero casuale diventa il nuovo seme. Questo nuovo seme viene moltiplicato per lo stesso "a", il cui prodotto viene aggiunto allo stesso c, per avere il secondo numero casuale. Questo secondo numero casuale diventa il nuovo seme per il prossimo numero casuale. Questa procedura viene ripetuta per tutti i numeri casuali richiesti dal programmatore.

Il seme qui ha il ruolo di un indice. Il seme predefinito è 1.

Una sintassi per Linear_Congruential_Engine è:

linear_congruential_enginelce

LCE è il nome della scelta del programmatore. Questa sintassi utilizza il seme predefinito di 1. Il primo parametro del modello qui dovrebbe essere specializzato con "INT non firmato". Il secondo e il terzo dovrebbero avere i valori effettivi di "A" e C. Il quarto dovrebbe avere il valore effettivo del numero casuale massimo previsto, più 1.

Supponendo che sia richiesto un seme del valore 2, la sintassi sarebbe:

linear_congruential_engineLCE (2)

Nota il seme tra parentesi subito dopo LCE.

Il seguente programma, illustra l'uso di linear_congruential_engine, con il seme predefinito di 1:

#includere
#includere
Utilizzo dello spazio dei nomi std;
int main ()

linear_congruential_enginelce;
cout <cout <cout <cout <cout <cout <cout <cout <restituzione 0;

L'output è:

4
13
40
121
364
0
499

Nota il modo in cui è stato istanziato l'oggetto LCE per il motore. Qui, 'a' è 3, c è 1 e il massimo, sperato di raggiungere il numero, m è 500. m è in realtà un modulo - vedi più tardi. lce (), come usato qui, non è un costruttore. È un operatore che restituisce il prossimo numero casuale richiesto per il motore nella sequenza di output. min per questo schema è 0 e max è 499 e questi possono essere utilizzati per convertire un numero restituito tra 0 e 1 - vedi sotto.

Il primo numero casuale restituito è 4. È uguale a 1 x 3 + 1 = 4. 4 diventa il nuovo seme. Il prossimo numero casuale è 13, che è pari a 4 x 3 + 1 = 13. 13 diventa il nuovo seme. Il prossimo numero casuale è 40, che è pari a 13 x 3 + 1 = 40. In questo modo, i numeri casuali successivi sono 121 e 364.

Il seguente codice, illustra l'uso di linear_congruential_engine, con un seme di 2:

linear_congruential_enginelce (2);
cout <cout <cout <cout <cout <cout <cout <cout <

L'output è:

7
22
67
202
607
0
999

Il numero casuale massimo sperato qui è 1000. Min per questo schema è ancora 0 e Max è ora 999 e questi possono essere usati per convertire un numero restituito tra 0 e 1 - vedi sotto

Il primo numero casuale restituito è 7. È uguale a 2 x 3 + 1 = 7. 7 diventa il nuovo seme. Il prossimo numero casuale è 22, che è uguale a 7 x 3 + 1 = 22. 22 diventa il nuovo seme. Il prossimo numero casuale è 67, che è pari a 22 x 3 + 1 = 67. In questo modo, i numeri casuali successivi sono 202 e 607.

Il seguente codice utilizza la formula sopra per produrre un numero casuale tra 0 e 1, per questo motore:

linear_congruential_enginelce (2);
Unsigned int num = lce (); // Numero casuale normale
non firmato int min = lce.min ();
non firmato int max = lce.max ();
float random_number = ((float) (num - min))/((float) (max - min));
cout <

L'output è:

0.00700701

Qui, Num ha 7 anni e così

random_number = (7 - 0)/(999 - 0) = 7/999 = 0.00700701 arrotondata a 8 posti decimali.

linear_congruential_engine non è l'unico motore specializzato nella libreria casuale; Ce ne sono altri.

default_random_engine

Questo è come un motore per scopi generali. Produce numeri casuali. L'ordine di sequenza non è garantito per non essere determinato. Tuttavia, l'ordine probabilmente non è noto dal programmatore. Le seguenti due righe mostrano come è possibile utilizzare questo motore:

random_device rd;
default_random_engine eng (rd ());

random_device è una classe da cui è stata istanziata. Nota le parentesi per RD negli elenchi degli argomenti del motore. Un distributore ha bisogno di questo motore per il suo funzionamento - vedi sotto.

Classi di distribuzione dei numeri casuali
uniforme_int_distribution

uniforme_int_distribution
La probabilità che si verifichi qualsiasi numero è 1 divisa per il numero totale di numeri per questa classe. Ad esempio, se ci sono dieci possibili numeri di output, la probabilità di ciascun numero visualizzato è 1/10. Il seguente codice illustra questo:

random_device rd;
default_random_engine eng (rd ());
uniforme_int_distributiondist (3, 12);
cout <cout <

L'output dal computer dell'autore è:

9 8 3 5 12
7 4 11 7 6

Sfortunatamente, 7 è apparso due volte a spese di 10. Gli argomenti di dist sono i numeri 3 e 13 inclusi (dieci numeri interi consecutivi). Dist (Eng) è un operatore che restituisce il numero successivo. Utilizza il motore. Nota l'uso della specializzazione del modello INT.

Non è necessario cercare num, min e max per questo caso e quindi utilizzare la formula sopra per ottenere un numero tra 0 e 1. Questo perché c'è un float equivalente di questa classe che utilizza la specializzazione float. L'output non sarà la stessa per ogni corsa.

uniforme_real_distribution

uniforme_real_distribution è simile a uniform_int_distribution. Con esso, per ottenere un numero compreso tra 0 e 1, basta usare 0 e 1 come argomenti. Il seguente codice illustra questo:

random_device rd;
default_random_engine eng (rd ());
uniforme_real_distributiondist (0, 1);
cout <cout <

L'output dal computer dell'autore è:

0.384051 0.745187 0.364855 0.122008 0.580874
0.745765 0.0737481 0.48356 0.184848 0.745821

Nota l'uso della specializzazione del modello float. L'output non sarà la stessa per ogni corsa.

distribuzione binomiale

Con questa distribuzione, la probabilità per ciascun numero di output non è la stessa. binomial_distribution è stato illustrato sopra. Il seguente codice mostra come utilizzare Binomial_Distribution per produrre 10 numeri casuali:

random_device rd;
default_random_engine eng (rd ());
distribuzione binomialedist (10);
cout <cout <

L'output dal computer dell'autore è:

5 3 5 5 7
6 6 5 8 3

L'output non sarà la stessa per ogni corsa. La specializzazione del modello utilizzata qui è int.

Il seguente codice utilizza la formula sopra per produrre un numero casuale tra 0 e 1, per questa distribuzione:

random_device rd;
default_random_engine eng (rd ());
distribuzione binomialedist (10);
Unsigned int num = dist (eng); // Numero casuale normale
Insigned Int Min = Dist.min ();
Insigned int max = dist.max ();
cout <cout <cout <cout <float random_number = ((float) (num - min))/((float) (max - min));
cout <

L'output dal computer dell'autore è:

0
10
7
0.7

Migliore numero casuale

Il numero di secondi da quando Epoch Unix può essere usato come seme. Diventa difficile per l'hacker conoscere il seme. Il seguente programma lo illustra con Linear_Congruential_Engine:

#includere
#includere
#includere
Utilizzo dello spazio dei nomi std;
int main ()

const auto p1 = Chrono :: System_Clock :: Now ();
SEED INT non firmato = Chrono :: Duration_Cast(P1.time_since_epoch ()).contare();
linear_congruential_enginelce (seme);
cout <cout <cout <cout <restituzione 0;

L'output dal computer dell'autore è:

91 274 823 470 411
0
999

Si noti che la libreria Chrono è stata inclusa. L'output è diverso per ogni corsa.

Conclusione

Il modo più semplice per avere un numero casuale tra 0 e 1 è usare Random_Device, Default_random_Engine e Uniform_real_Distribution (con gli argomenti 0 e 1). Qualsiasi altro motore o distribuzione utilizzato può richiedere la formula, random_number = (num - min)/(max - min).