Srand + random_shuffle in macro

Dear rooters,

I was using a combination

srand(time(NULL)); 
random_shuffle(v.begin(), v.end()); 

for a while in a macro and now I have discovered that it produces always the same sequences of elements. Try to run this example in an interactive session

#include<algorithm>
void random(){
  srand(time(NULL));
  vector<int> v;
  for (int i=0; i<20; i++) v.push_back(i);
  random_shuffle(v.begin(),v.end());
  for (int i=0; i<20; i++) cout << v[i] << endl;
}

In a compiled code random_shuffle works as expected giving different sequences every time (the code is the same as above)

#include<algorithm>
#include<iostream>
#include<vector>

using namespace std;

int main(){
  srand(time(NULL));
  vector<int> v;
  for (int i=0; i<20; i++) v.push_back(i);
  random_shuffle(v.begin(),v.end());
  for (int i=0; i<20; i++) cout << v[i] << endl;
}

The workaround can be easily found (e.g. using random_shuffle with 3 arguments), but if it is possible I think that it would be better to make srand+random_shuffle with 2 arguments work correctly also in a macro or to document this problem in some way. Sorry if this was already discussed.

I am using ROOT 5.30/02 (tags/v5-30-02@40973, Sep 22 2011, 10:55:04 on linuxx8664gcc) and
g++ (SUSE Linux) 4.5.1 20101208 [gcc-4_5-branch revision 167585].

Thanks a lot!

Cheers,
Alexey

P.S. Could you, please, give me an advice on my previous topic [url]TFractionFitter strange fit would not it be better to contact the authors of TFractionFitter (Frank Filthaut or Bran Wijngaarden) directly?

This is a CINT’s “bug” (or a “feature”, whatever you prefer -> “random_shuffle” uses CINT’s own simple “G__random_generator” class, “unrelated” to the “stdlib”, so the call to “srand” has no effect on it).
Of course, I’m sure that this problem has been “fixed” in the ROOT trunk. :wink:

Thanks, Wile! I believe that I spoke too soon saying that one can use random_shuffle with three parameters in a macro as a workaround to the problem. An example from cplusplus.com/reference/algo … m_shuffle/ compiles and runs without problems, but in an interactive session gives an error.

// random_shuffle example
#include <iostream>     // std::cout
#include <algorithm>    // std::random_shuffle
#include <vector>       // std::vector
#include <ctime>        // std::time
#include <cstdlib>      // std::rand, std::srand

// random generator function:
int myrandom (int i) { return std::rand()%i;}

void random () {
  std::srand ( unsigned ( std::time(0) ) );
  std::vector<int> myvector;

  // set some values:
  for (int i=1; i<10; ++i) myvector.push_back(i); // 1 2 3 4 5 6 7 8 9

  // using built-in random generator:
  std::random_shuffle ( myvector.begin(), myvector.end() );

  // using myrandom:
  std::random_shuffle ( myvector.begin(), myvector.end(), myrandom);

  // print out content:
  std::cout << "myvector contains:";
  for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
    std::cout << ' ' << *it;

  std::cout << '\n';
}

The error is “Warning: rand() expects 0 parameters, 1 parameters given algo.h:562:” and in algo.h one sees

iter_swap(i, first + rand((i - first) + 1));

i.e. rand here seems to come in conflict with the stdlib function rand(void). Since I need only few randomly shuffled trees so for the moment I will simply put random_shuffle in a loop with a manually ‘random’ number of iterations :slight_smile: