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

Secondo lo Stroustrup, l'algoritmo standard std::random_shuffle, 
accessibile includendo l'header <algorithm>, dovrebbe produrre una 
permutazione casuale della sequenza (individuata da due iteratori ad 
accesso casuale) passata come parametro.
Ho provato ad utilizzarla con il g++ 3 e, in effetti, ho notato che la 
sequenza prodotta dall'algoritmo puo' sembrare a prima vista "casuale", 
con il solo neo che la permutazione in uscita e' sempre la stessa!
Stroustrup non fornisce indicazioni sulle modalita' d'uso di 
random_shuffle, quindi mi chiedo: e' normale questo comportamento? E' 
forse necessario inizializzare qualche generatore di num casuali? Ho 
provato a chiamare std::srand( std::time(0) ) ma, ovviamente, non 
cambia nulla.
ciao Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.6, higher than 98% of all previous test takers.
C Language: 3.32, higher than 79% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

 forse necessario inizializzare qualche generatore di num casuali? 
la tipica implementazione del gcc era (prima del 3.0)
template <class RandomAccessIter>
inline void random_shuffle(RandomAccessIter first,
                           RandomAccessIter last) {
  if (first == last) return;
  for (RandomAccessIter i = first + 1; i != last; ++i)
    iter_swap(i, first + random_number((i - first) + 1));
}
il che ci porta a vedere come e' implementato random_number
che per gcc 2.95.3, mi da'
inline _Distance random_number(_Distance __n) {
#ifdef __STL_NO_DRAND48
  return rand() % __n;
#else
  return lrand48() % __n;
#endif
}
quindi dovresti vedere cosa devi inizialzzare, se rand o lrand48, 
quest'ultima con srand48(long seed)
dovresti vedere come e' sul tuo 3.0


In effetti anche io ho notato questo problema.
Ad ogni modo puoi usare la versione:
template<class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle(RandomAccessIterator first, RandomAccessIterator last,
                    RandomNumberGenerator& rand);
Cosi gli passi tu il generatore.
Dall'ultimo draft dello standard:
random_shuffle() can take a particular random number generating function
object rand such that rand(n) (where n is a positive argument of type
iterator_traits<RandomAccessIterator>::difference_type) returns a randomly
chosen value of type iterator_traits<RandomAccessIterator>::difference_type)
in the interval [0, n).
Ciao   Manlio Perillo

                     RandomNumberGenerator& rand);
ok, ti ringrazio. In effetti avevo notato anche io che esisteva questa 
versione di random_shuffle, ma non avevo notato che rand(n) dovesse 
ritornare un valore minore di n e mi andava in segfault.


 dovresti vedere come e' sul tuo 3.0
sono andato a controllare e l'implementazione e' immutata, quindi ho 
risolto con una chiamata a srand48. Pero' mi chiedo quanto sia standard 
questo approccio (dato che srand48 non e' standard): cosa specifica lo 
standard al proposito?


 specifica lo standard al proposito?
non dice nulla su quale funzione usare, definisce solo il comportamento 
che deve avere. Quindi e' implementation dependent come realizzarlo, e 
dato che permette di passare una funzione di randomizzazione, non mi 
sembra un punto rilevante. 
Se vuoi saperne di piu', puoi provare a chiedere su 
comp.std.c++.moderated

 comp.std.c++.moderated
vabe', ho fatto un mix: 
comp.std.c++ 
e' quello giusto