View Full Version : Problema col Numero Random in c++
virtual89
05-11-2006, 11:03
Salve, devo generare 4 numeri diversi tra loro e compresi tra 1 e 9, allora ho usato il codice:
a = rand() % 1 + 8;
b=rand() % 2 + 7;
while (b==a)
{
b=rand() % 2 + 7;
}
c=rand() % 3 + 6;
while (c==a || c==b)
{
c=rand() % 3 + 6;
}
d=rand() % 4 + 5;
while (d==a || d==b || d==c)
{
d=rand() % 4 + 5;
}
E le variabili a,b,c,d vengono sempre generate con lo stesso valore, cioè a=8;b=7;c=6;d=5 . Come posso risolvere questo problema e avere i valori delle variabili diversi?
virtual89
05-11-2006, 11:08
Questo è proprio il codice completo:
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
srand((unsigned)time(NULL));
int a,b,c,d;
a = rand() % 1 + 8;
b=rand() % 2 + 7;
while (b==a)
{
b=rand() % 2 + 7;
}
c=rand() % 3 + 6;
while (c==a || c==b)
{
c=rand() % 3 + 6;
}
d=rand() % 4 + 5;
while (d==a || d==b || d==c)
{
d=rand() % 4 + 5;
}
cout<<"A " <<a;
cout<<endl<<"B "<<b;
cout<<endl<<"C "<<c;
cout<<endl<<"D "<<d<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}
E mi genera sempre
A=8
B=7
C=6
D=5
l'istruzione corretta per generare un numero random tra 1 e 9 è
rand()%9 + 1 visto che rand() torna un numero casuale fra 0 e RAND_MAX e applicando l'operatore modulo 9 si ottiene un valore fra 0 e 8
mad_hhatter
05-11-2006, 11:14
posto che non ho ben capito che elaborazioni fai su a,b,c,d (ma ho letto due secondi :) ), che cosa fa il metodo time(NULL)?
te lo chiedo perchè se tale metodo torna sempre lo stesso valore allora è logico che il tuo programma genererà sempre gli stessi numeri pseudocasuali
virtual89
05-11-2006, 11:32
l'istruzione corretta per generare un numero random tra 1 e 9 è
rand()%9 + 1
Scusa ma con questo codice ottengo un numero tra 1 e 9 ?
E allora per generare tra 2 e 9 ci vuole questo codice:
rand()%9 + 2
E' così?
leox@mitoalfaromeo
05-11-2006, 11:51
nono fermo... che pasticcio!
il metodo rand() genera una sequenza di numeri casuali secondo una funzione generatrice.
quindi se tu fai 4 volte rand()%<n> otterrai sempre gli stessi 4 numeri.
come cambiare?
prima di generare i numeri definisci:
int seed;
cout << "inserire il seed"<< endl;
cin >> seed;
srand(seed);
ora ogni volta che cambierai il seed cambierà la sequenza...
virtual89
05-11-2006, 11:53
leox@mitoalfaromeo ti puoi spiegare meglio... non ho capito bene!
leox@mitoalfaromeo
05-11-2006, 11:54
leox@mitoalfaromeo ti puoi spiegare meglio... non ho capito bene!
ho editato
leox@mitoalfaromeo
05-11-2006, 11:59
ho anche visto meglio ora... avevi già usato srand() ma lo usavi in maniera non corretta.
in primo luogo non è necessario cambiare ogni volta la formula che ti genera il numero casuale...
dovrai sempre usare
x=rand()%9+1;
è già rand che ti garantisce che saranno diversi...
poi ovviamente nell'estrarre 4 numeri casuali su 9 disponibili è facile che si ripetano tra loro...ma il tuoi cicli while lo evitano...
però otterrai sempre la stessa sequenza se non cambierai il contenuto di srand().
TuLKaS85
05-11-2006, 12:09
i valori casuali una volta posto il seed con il time è impossibili che escano sempre uguali....
prova con srand((unsigned) time(0))
come diceva leox ti conviene usare sempre la stessa formula e poi magari controlli se il numero non sia già uscito in tal caso ripeti la generazione...
mad_hhatter
05-11-2006, 12:27
ciao, ho appena letto la documentazione sul metodo time() e andava bene come lo avevi scritto tu, passandogli NULL: pensavo fosse un paramentro che time utilizzasse in qualche modo, invece è solo un puntatore per farsi tornare il current_time.
però, stanti così le cose, il tuo codice andava bene, il problema sta da un'altra parte (probabilmente dipende da come usi il rand())
virtual89
05-11-2006, 12:28
Il problema l'ho risolto mettendo :
x=rand()%9+1;
Ma posso sapere più in specifico in base a cosa vengono generati i numeri, cioè quell'1 e 9 che significato hanno?
mad_hhatter
05-11-2006, 12:33
Il problema l'ho risolto mettendo :
x=rand()%9+1;
Ma posso sapere più in specifico in base a cosa vengono generati i numeri, cioè quell'1 e 9 che significato hanno?
rand torna numeri casuali da 0 a 2^32 - 1
il %9 torna il resto della divisione intera "rand() / 9 ". tale resto è ovviamente compreso tra 0 e 8
ora per avere numeri da 1 a 9 devi aggiungere 1
se non ti è chiaro ne parliamo ancora
Ziosilvio
05-11-2006, 12:34
Salve, devo generare 4 numeri diversi tra loro e compresi tra 1 e 9, allora ho usato il codice:
a = rand() % 1 + 8;
b=rand() % 2 + 7;
while (b==a)
{
b=rand() % 2 + 7;
}
c=rand() % 3 + 6;
while (c==a || c==b)
{
c=rand() % 3 + 6;
}
d=rand() % 4 + 5;
while (d==a || d==b || d==c)
{
d=rand() % 4 + 5;
}
E le variabili a,b,c,d vengono sempre generate con lo stesso valore, cioè a=8;b=7;c=6;d=5 . Come posso risolvere questo problema e avere i valori delle variabili diversi?
Errore numero zero: il generatore va inizializzato ogni volta in maniera diversa per evitare di ripetere sempre la stessa sequenza.
Il modo classico è una chiamata a srand(time(NULL)).
Errore numero uno: qualunque intero modulo uno dà 0, quindi il primo valore sarà in ogni caso 8.
Errore numero due: qualunque intero modulo due è 0 oppure 1, quindi il secondo intero sarà sempre o 7 o 8.
Dato che ogni volta fai il confronto col numero precedente, il secondo numero sarà sempre 7.
Errore numero tre: qualunque intero modulo tre è 0 oppure 1 oppure 2, quindi il secondo intero sarà sempre o 6 o 7 o 8.
Dato che ogni volta fai il confronto coi numeri precedenti, il terzo numero sarà sempre 6.
Errore numero quattro: qualunque intero modulo quattro è 0 oppure 1 oppure 2 oppure 3, quindi il secondo intero sarà sempre o 5 o 6 o 7 o 8.
Dato che ogni volta fai il confronto coi numeri precedenti, il quarto numero sarà sempre 5.
Trovi risposte più dettagliate QUI (http://www.hwupgrade.it/forum/showthread.php?t=1196677).
Ziosilvio
05-11-2006, 12:36
l'istruzione corretta per generare un numero random tra 1 e 9 è
rand()%9 + 1 visto che rand() torna un numero casuale fra 0 e RAND_MAX e applicando l'operatore modulo 9 si ottiene un valore fra 0 e 8
Il valore così generato sarà tra 1 e 9, ma avrà distribuzione non uniforme e/o sarà facile da prevedere.
Trovi più informazioni QUI (http://www.hwupgrade.it/forum/showthread.php?t=1196677)
Ziosilvio
05-11-2006, 12:38
rand torna numeri casuali da 0 a 2^32 - 1
rand restituisce valori pseudorandom tra 0 e RAND_MAX, che non è obbligata ad essere il valore che hai detto tu.
Trovi più informazioni QUI (http://www.hwupgrade.it/forum/showthread.php?t=1196677).
mad_hhatter
05-11-2006, 12:41
hai ragione. grazie per il tutorial :)
tomminno
05-11-2006, 13:43
Nessuno però si è preoccupato di dire che rand() non è un buon generatore di numeri casuali, assolutamente da evitare ovunque il numero casuale sia cruciale per l'applicativo come ad esempio la generazione di dithering.
leox@mitoalfaromeo
05-11-2006, 14:13
Nessuno però si è preoccupato di dire che rand() non è un buon generatore di numeri casuali, assolutamente da evitare ovunque il numero casuale sia cruciale per l'applicativo come ad esempio la generazione di dithering.
bè ma se allora lo vogliamo affossare del tutto diciamo anche che la generazione dipende dal compilatore e dalla macchina sul quale viene eseguito, cosa che invece non succede in java col metodo Random(). (infatti per una questione di ripetibilità ho dovuto fare un generatore di istanze in java quando il programma che sto scrivendo per la tesi è in c++)
virtual89
05-11-2006, 15:08
Grazie a tutti...
A me il Random serviva per realizzare il Master Mind che devo portare a scuola domani...E l'ho finito...
Se volete dare un'occhiata andate QUI (http://aterzfinf.altervista.org/master%20mind.zip)
vi scaricherà direttamente il gioco!
Buon divertimento! :D
leox@mitoalfaromeo
05-11-2006, 16:19
Grazie a tutti...
A me il Random serviva per realizzare il Master Mind che devo portare a scuola domani...E l'ho finito...
Se volete dare un'occhiata andate QUI (http://aterzfinf.altervista.org/master%20mind.zip)
vi scaricherà direttamente il gioco!
Buon divertimento! :D
crea una pagina html col link perchè altervista non permette di linkare file da siti esterni..
alternativamente devi metterlo in una directory che chiami /_altervista_ht/
Ziosilvio
05-11-2006, 23:27
Nessuno però si è preoccupato di dire che rand() non è un buon generatore di numeri casuali, assolutamente da evitare ovunque il numero casuale sia cruciale per l'applicativo come ad esempio la generazione di dithering.
Più che altro: diciamo che lo standard C/C++ non prevede che rand abbia buone proprietà statistiche, per cui non ci si può fidare ciecamente del suo output.
tomminno
06-11-2006, 08:33
bè ma se allora lo vogliamo affossare del tutto diciamo anche che la generazione dipende dal compilatore e dalla macchina sul quale viene eseguito, cosa che invece non succede in java col metodo Random(). (infatti per una questione di ripetibilità ho dovuto fare un generatore di istanze in java quando il programma che sto scrivendo per la tesi è in c++)
Guarda che di generatori random che soddisfano i requistiti di Park e Miller in C ne trovi quanti ne vuoi, alla fine si tratta di una 30ina di righe di codice.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.