Newsgroup: it.comp.lang.c++
Titolo: Randomizzare

Come posso randomizzare entro certi range di valori?
Grazie


Per restituire un valore casuale, ad esempio da 0 a 256
<stdlib.h>
int valore = rand()%256
o, per restituire un valore casuale da 10 a 256
<stdlib.h>
int valore = 10+rand()%246
ciao ciao

>Come posso randomizzare entro certi range di valori?
umh... randomizzare non mi e' chiaro, vedi nota ***, credo tu intenda
"generare un numero random intero".
se e' cosi', ecco una forma che funziona:
(rand()%(abs(r1-r2)+1))+((r1<=r2)?(r1):(r2));
ora val contiene un numero compreso tra r1 e r2, dove l'ordine ed il segno
non sono importanti.
Questa soluzione va piu' che bene nella maggior parte dei casi, se pero' sei
uno di quelli che si lamentano che rand() da solo e' poco random nei
low-order-bits, allora e' possibile modificare la soluzione in modo che tale
problema venga minimizzato. Per il 99% dei casi questa soluzione va piu' che
bene, se non ti andasse bene, fammi sapere e ti mando una soluzione che in
teoria dovrebbe essere migliore... in pratica, se hai questo problema,
meglio lasciare stare rand() ed usare altro ;-) ).
(Se invece intendevi per numeri floating point allora fammi un fischio e ti
mando la soluzione anche per quelli...)
<CODE>
inline int RandomInRange(int r1,int r2)
{
    return (rand()%(abs(r1-r2)+1))+((r1<=r2)?(r1):(r2));
}
</CODE>
questa funzione, se chiamata con:
RandomInRange(33,45);     // ritorna un numero compreso tra 33 e 45 (estremi
inclusi).
RandomInRange(45,33);     // ritorna un numero compreso tra 33 e 45 (estremi
inclusi).
RandomInRange(-19,+28);  // ritorna un numero compreso tra -19 e +28
(estremi inclusi).
RandomInRange(+28,-19);  // ritorna un numero compreso tra -19 e +28
(estremi inclusi).
RandomInRange(-5,-15);    // ritorna un numero compreso tra -15 e -5
(estremi inclusi).
RandomInRange(2,2);         // ritorna il numero 2
// etc...
*** = Ricordati inoltre di "randomizzare" il generatore usando srand.
Ecco un programma test per la mia soluzione:
<CODE>
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<map>
using namespace std;
inline int RandomInRange(int r1,int r2)
{
    return (rand()%(abs(r1-r2)+1))+((r1<=r2)?(r1):(r2));
}
int main()
{
    // randomizziamo il generatore....
    srand((unsigned)time(NULL));
    // map per tenere i risultati:
    map<int,int> m;
    // generiamo 10000 numeri casuali usando la nostra funzione:
    for(int i=0; i<10000; ++i){
        int val = RandomInRange(18,-11);
        ++m[val]; // salviamo il risultato
    }
    // stampiamo i valori che sono stati scritti:
    cout << "start" << endl;
    for(map<int,int>::iterator p = m.begin();p!=m.end();++p){
        cout << p->first << "(" << p->second << " volte)" << endl;
    }
    cout << "end" << endl;
    return 0;
}
</CODE>
come vedi il test genera 10000 numeri casuali nel range 18..-11. Tali valori
vengono salvati (usando std::map) e poi dopo di che li stampiamo tutti.
Tutti i valori ritornati da RandomInRange(18,-11); vengono memorizzati e
sucessivamente visualizzati a schermo. Possiamo cosi' vedere se i valori
generati sono nel range desiderato e se essi vengono distribuiti equamente.
(sarebbe stato piu' semplice avere un "if" che controllava il valore di
ritorno e se fuori dal range avvisava l'utente. Ad ogni modo in questo modo
e' possibile mostrare un output un tantino piu' interessante:)
<OUTPUT>
start
-11(362 volte)
-10(329 volte)
-9(352 volte)
-8(307 volte)
-7(317 volte)
-6(311 volte)
-5(321 volte)
-4(321 volte)
-3(368 volte)
-2(341 volte)
-1(326 volte)
0(336 volte)
1(340 volte)
2(335 volte)
3(344 volte)
4(336 volte)
5(335 volte)
6(329 volte)
7(339 volte)
8(318 volte)
9(334 volte)
10(331 volte)
11(323 volte)
12(321 volte)
13(357 volte)
14(369 volte)
15(334 volte)
16(320 volte)
17(330 volte)
18(314 volte)
end
</OUTPUT>
Tommy

già che ci siamo: lo standard prevede una funzione random(int n) che
genera un numero tra 0 e n - 1?
in alcuni compilatori l'ho trovato (bcc32), in altri no (gcc), anzi,
ne ho trovata una versione completamente differente
-- 
]\/[ad]\/[age (
www.mindreamz.net
)
"Un Maestro insegue semplicemente la sua visione di Eccellenza in
qualunque cosa sta facendo e lascia agli altri decidere se sta 
lavorando o giocando. A lui sembra sempre di fare entrambe." - Anonimo

 ne ho trovata una versione completamente differente
Beh, ti sei quasi risposto da solo.... no, lo standard non prevede nulla del
genere. Ad ogni modo non e' un grosso limite visto che a mano e' banale
farlo.
Tommy



lo chiedevo perché nell'help on line di borland viene inserita come
funzione standard


 }
Grazie mille per la tua funzione! E' perfetta per il mio scopo. Una sola
cosa, da dove nasce? Nel senso, perchč si agisce propio cosě?
Grazie Ancora

 funzione standard
Veramente a me la random() la dà solo per Win32.
EMG
--
EMAG Software Homepage:     
http://www.emagsoftware.it
The EMG's ZX-Spectrum Page: 
http://www.emagsoftware.it/spectrum
The Best of Spectrum Games: 
http://www.emagsoftware.it/tbosg


E' vero, scusate :-) Ho scritto una cosa pensandone un'altra. Volevo scriver
tra 10 e 256 (e anche qui sbagliavo di uno ;-)
Ciao ciao

 Nel senso, perchè si agisce propio così?
questo non lo so ;-)
Tommy