Generazione di numeri casuali

generazione di numeri casuali
Richiami sulla teoria elementare dei sistemi.
Un sistema si classifica come deterministico quando, sollecitandolo con una funzione di ingresso, si può determinare la sua evoluzione. Ad esempio, imprimendo ad un pallone una funzione Impulso di una certa durata (in questo caso l'impulso è di natura vettoriale, cioè ha un’intensità, un'inclinazione e un verso) si può prevedere quale sarà la sua traiettoria, dove cadrà, quale altezza massima raggiunge, per quanto tempo resta in volo, ecc.

Questa previsione si formula applicando le leggi della fisica.

I sistemi stocastici manifestano un comportamento regolato dal caso (dal greco stocas). Ad esempio il vento potrebbe introdurre una componente aleatoria che fa deviare il pallone dalla sua traiettoria.

Lo scopo di simulare il comportamento di un sistema stocastico è quello di dimensionarlo per ottimizzarne il funzionamento.

Esempi di sistemi stocastici: guasti a un macchinario, coda ad uno sportello, …

I numeri casuali.
Per simulare il verificarsi di un evento casuale occorre avere una sorgente che emetta dei valori casuali che riproducano una possibile successione di valori realmente osservabili.

La base per costruire i vari comportamenti statistici è la variabile casuale distribuita uniformemente.

Una variabile casuale x distribuita uniformemente è definita nel seguente modo:
∀ x ∈ [0, 1[ → p(x) = k
(con k costante)
Ogni numero ha la stessa probabilità k di essere estratto.

In termini pratici si ipotizza di disporre, all’interno di un’urna, di tutti i numeri reali compresi tra 0 e 1 (1 escluso). Si trova che nessun numero ha una preferenza di essere estratto rispetto agli altri, quindi, dopo un numero elevatissimo di estrazioni, ogni numero sarà stato scelto la stessa quantità di volte come gli altri.

Il grafico di una distribuzione uniforme è una retta, nell’intervallo [0, 1[ e la funzione non è definita all’esterno di tale intervallo.

Negli anni ’20 un matematico americano pubblicò un libro dal titolo: "un milione di numeri casuali". A chi potevano interessare i numeri generati dal caso? Quanto tempo aveva perso costui per ottenerli? Per quale ragione ci si poteva fidare che i numeri erano realmente casuali e che non esistesse una regola per passare dall’uno altro in successione?

L’algoritmo per generare numeri a caso consiste nello scegliere un numero iniziale e dividerlo per un numero primo molto grande, il resto della divisione è il numero casuale generato.

Il numero casuale generato viene usato per determinarne un altro: viene diviso per il numero primo.

Si trova che, con una opportuna scelta del numero primo, si ottengono, con la stessa frequenza, tutti i numeri compresi tra 0 e il numero primo-1.

I numeri sono pseudocasuali perché esiste una regola per passare da un numero al successivo.

Esempio:
   
A
B
1
17
  
2
25
=RESTO(A2;A$1)
3
=31*B2
=RESTO(A3;A$1)
Osservare i numeri nella colonna B. Si può notare che a un certo punto la sequenza si ripete.

Un attento osservatore potrebbe scoprirla e la natura casuale dei numeri verrebbe confutata.

Per verifica si calcoli la frequenza dei numeri casuali generati.

Si deve contare quante volte viene estratto 0, quante volte viene estratto 1, …, quante volte viene estratto 16.

Se si ottiene un conteggio uguale per tutti i numeri allora la successione è distribuita uniformemente.

Preparare l'elenco di numeri 0÷16 e calcolare la frequenza: Il conteggio è uguale per tutti i numeri?

La funzione random.
La formula proposta per generare un numero casuale, attribuita al matematico Lehmer, si può scrivere nella forma:
X(successivo) = [X(corrente) * p] mod q
In un linguaggio di programmazione una variante di questa formula è impiegata per la funzione random().

Richiamando la funzione random() si ottiene un numero casuale compreso tra 0 e 1 (1 escluso).

I numeri generati dalla funzione random() appartengono a una distribuzione uniforme.

Come si può ottenere un numero casuale nell’intervallo [180, 250[? L’intervallo è ampio 250-180, cioè 70.

Il minimo valore prodotto dalla funzione random() è 0, e moltiplicando 0 per 70 (=250-180) si ha 0.

Il massimo valore prodotto dalla funzione random è 0.9999999, e moltiplicandolo per 70 si ottiene 69.9999. Allora moltiplicando un numero compreso tra 0 e 1 per 70 e prendendo la parte intera si ottiene un numero compreso tra 0 e 69. Aggiungendo 180 si ottiene un numero compreso tra 180 e 249.

In generale data una funzione che produce un numero compreso tra 0 e 1, per ottenere un numero nell’intervallo [a, b[:
x = a + (b - a) * random()


Per generare un numero intero compreso tra 1 e 6, con il 6 compreso nel risultato, la formula è:
x = 1 + 6*random()
Contare quante volte si ha esito 1, quante volte si ha esito 2, ecc.

Nell’intervallo A3…A8 scrivere i numeri 1, 2, …, 6.

Accanto a ciascun numero scrivere un’espressione per contare quante volte è stato estratto ciascuno di essi.
   
Istruzione
1
For i = 1 to 100
2
Cells(1, 1) = Int(Rnd() * 6) + 1
3
dado1 = Cells(1, 1)
3
Cells(dado1 + 2, 2) = Cells(dado1 + 2, 2) + 1
3
Next

Linea 1: Si suppone di lanciare il dado 100 volte.
Linea 2: Si genera un numero casuale compreso tra 1 e 6 e lo si scrive nella cella, del foglio attivo, in riga 1, colonna 1.
Linea 3: Il valore del dado viene scritto nella variabile Dado1.
Linea 4: Il valore del dado viene utilizzato come coordinata di riga per contare (nelle celle B3÷B8) il numero di volte che si è verificato questo valore.
L’istruzione descrive l’accesso ad un array bidimensionale. L’elemento riferito si trova nella riga ottenuta sommando 2 (perché si sono lasciate due righe vuote) al numero uscito sul dado.
Se è uscito 1 allora l’elemento si trova nella riga 3.
il secondo parametro dentro la parentesi (2) specifica la colonna 2 del foglio, cioè la colonna B.
il ciclo For termina con l’istruzione Next

Eseguire la macro numerose volte e verificare se i numeri hanno tutti la stessa frequenza. Lo si verifichi anche con un grafico.

Costruire l’istrogramma dei dati contenuti nell’intervallo B3:B8, assumendo come "Etichette asse categorie" l’intervallo A3:A8.

Eseguire la macro e osservare che l’uniformità della frequenza dei valori estratti non è proprio regolare ma i valori sono comunque dello stesso ordine di grandezza.

Esercizi:
Per ognuna delle operazioni seguenti verificare il funzionamento del programma prima di passare alla successiva.
  1. Simulare il lancio di due dadi mostrando, con un solo Message Box, i due numeri estratti.
  2. Se i due numeri estratti sono diversi effettuare un altro lancio, se invecei due numeri sono uguali termianre il programma.
  3. Chiedere al giocatore di tentare di indovinare il numero e, dopo il lalncio, comunicare l’esito: Indovinato oppure sbagliato.
  4. Se si inserisce un numero esterno all’intervallo [2,12] bisogna ripetere la domanda del punto 3.
  5. Contare il numero di lanci e il numero di risultati indovinati.
  6. Terminare il programma se i numeri sui due dadi sono uguali oppure se si sono superati 20 tentativi.
  7. Calcolare la percentuale di tentativi indovinati (Numero esiti indovinati / Lanci totali) e mostrarne il risultato.

soluzione: Lancio di 2 dadi
Lancio di 2 dadi
Con due dadi si possono ottenere i punteggi compresi tra 2 e 12.

Le probabilità dei singoli punteggi non sono più uguali tra loro. Infatti con due dadi si possono presentare 36 casi, corrispondenti al prodotto dei 6 casi che si possono presentare su un dado e ai 6 casi che si possono abbinare sull'altro.

La probabilità che si ottenga il punteggio 2 quindi è 1/36, perchè dei 36 possibili abbinamenti dei punteggi sui singoli dadi, solo uno può dare la somma 2: Uno sul primo e Uno sul secondo dado.

Per ottenere 3 ci sono 2 casi possibili: Uno sul primo dado e Due sul secondo e Viceversa. Quindi la probabilità di ottenere 3 è 2/36. Per una spiegazione più dettagliata si può consultare un approfondimento.

La tabella seguente riepiloga le probabilità dei vari punteggi.
Punteggio
Probabilità
2
1/36
3
2/36
4
3/36
5
4/36
6
5/36
7
6/36
8
5/36
9
4/36
10
3/36
11
2/36
12
1/36
Scegliere un intervallo del foglio, ad esempio A2:A12, ed inserirvi la numerazione da 2 a 12, corrispondente ai possibili punteggi che si possono ottenere sommando i punti su ciascuna faccia del dado, dopo un lancio.

Scrivere la macro che simula il lancio dei due dadi e calcola la frequenza dei punteggi:
Nr. riga
Istruzione
1
Sub DueDadi()
2
For i = 1 To 100
3
dado1 = Int(Rnd() * 6 + 1)
4
dado2 = Int(Rnd() * 6 + 1)
5
somma = dado1 + dado2
6
Cells(somma, 2) = Cells(somma, 2) + 1
7
Next
8
End Sub
Esercizi:
  1. Confrontare le probabilità attese (1/36, 2/36, …) con le frequenze ottenute.
  2. Rappresentare l'istogramma della frequenza dei punteggi