Login

Tweet recenti ...

By A Web Design Company

Dices200x150Spesso è necessario generare dei numeri "casuali" durante l'esecuzione di un programma. Questo articolo tratta di come farlo in Java.

In primo luogo è opportuno chiarire che non si tratta di numeri completamente casuali ma pseudocasuali, ossia numeri generati da un apposito algoritmo che opera in maniera deterministica (cioè fornendo sempre lo stesso output a fronte di un identico input) ma che permette di generare una sequenza di numeri che ha caratteristiche statistiche analoghe a quelle di una sequenza estratta casualmente.

L'input di cui si parla è il cosiddetto seme (seed in inglese), ossia un parametro che indica il punto di partenza della sequenza. Se il seme è estratto in maniera casuale, essendo utilizzato una sola volta, si ottiene una sequenza a priori non prevedibile. Spesso il seme viene generato prendendo un numero ricavato dall'orologio di sistema: in questo modo, in due esecuzioni distinte del programma, eseguite manualmente, si ha una sua buona "casualità". E' opportuno prestare attenzione al caso in cui il software si avvii automaticamente perché potrebbero nascere dei meccanismi di sincronizzazione che, a fronte di esecuzioni differenti, potrebbero portare alla generazione della stessa sequenza perché si è generato lo stesso seme.

E' utile osservare che, in alcuni casi, è molto comodo poter ripetere la sequenza pseudocasuale più volte, ossia avviare il software con gli stessi numeri. Per farlo è in genere sufficiente utilizzare lo stesso seme.

Nel linguaggio Java si può utilizzare la classe java.lang.Math che fornisce il metodo random(). Quando viene invocato la prima volta genera un nuovo generatore (ossia genera il seme) e ritorna un numero pseudocasuale double tra 0 e 1. Le successive chiamate consentono di ottenere altri numeri pseudocasuali, sempre double compresi tra 0 e 1.

Un'altra maniera è quella di utilizzare la classe java.util.Random. Come nella maggior parte dei generatori di numeri pseudocasuali, la classe Random ha due costruttori: uno privo di argomenti e uno che accetta un seme long. Il primo si comporta come il metodo random() di Math, il secondo accetta il seme long (ottenuto, ad esempio, dall'orologio di sistema) e lo utilizza per inizializzare il generatore pseudocasuale. In quest'ultima maniera è possibile riottenere la stessa sequenza in successive esecuzioni del codice fornendo lo stesso seme. Inoltre con Random è possibile generare numeri casuali con distribuzione uniforme o gaussiana.

Vediamo ora un esempio di generazione di numeri casuali con le due classi:

import java.util.Random;

 

import java.lang.Math;

 

public class RandomMath2 {

 

public static void main(String[] args) {

 

// ------------ Utilizzo della classe Math

 

// inizializza il generatore e genera il primo numero casuale

 

double x = Math.random();

 

for (int i = 0; i < 10; i++) {

 

System.out.println("Math.random() = " + x);

 

x = Math.random();

 

}

 

 

 

// ------------ Utilizzo della classe Random

 

// inizializza il generatore e genera il primo numero casuale

 

Random mystery = new Random();

 

x = mystery.nextDouble();

 

for (int i = 0; i < 10; i++) {

 

System.out.println("Random.nextDouble() = " + x);

 

x = mystery.nextDouble();

 

}

 

// ------------ Utilizzo della classe Random con seed fisso

 

// inizializza il generatore e genera il primo numero casuale

 

// ma sempre con lo stesso seed

 

mystery = new Random(12345L);

 

x = mystery.nextDouble();

 

// l'output sarà sempre lo stesso ad ogni esecuzione

 

for (int i = 0; i < 10; i++) {

 

System.out.println("Seed Non Casuale: Random.nextDouble() = " + x);

 

x = mystery.nextDouble();

 

}

}

 

}

 

Dopo aver generato numeri casuali double compresi tra 0 e 1, per ottenere numeri interi, ad esempio, compresi tra 1 e n è sufficiente moltiplicare il numero casuale tra 0 e 1 per n, rendere il tutto intero e sommarci 1.

Ad esempio, per generare numeri casuali tra 1 e 5:

 

for (int i = 0; i < 10; i++) {

x = Math.floor(Math.random() * 5) + 1;

System.out.println("Numeri interi da 1 a 5 = " + x);

}