Randomizing order of if-else statements

The purpose of doing this is so that the top of the if statements is not preferred over the bottom. I tried assigning enum values to each case. Then choose a random integer r from 0 to the size of the std::list myList containing those enum elements. The enum value is found using it = std::next (myList, r). Then if the if statement corresponding to that enum value is false, then myList.erase (it), and repeat the process with the newly reduce myList. It works, and everything seems nicely randomized. But it is disappointing much slower than when I used the original if-else statements (it is being applied hundreds of times). Any suggestions on a faster method?

Here is a snippet of my code (I decided not to use switch statements because it looked too clumsy):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
	std::list<FacingDirection> guyFacingDirections = {Positive_x, Negative_x, Positive_y, Negative_y, Positive_xPositive_y, Positive_xNegative_y, Negative_xPositive_y, Negative_xNegative_y};
	while (true) 	{
		const int r = rand() % guyFacingDirections.size();
 		std::list<FacingDirection>::iterator it = std::next(guyFacingDirections.begin(), r); 		
                const FacingDirection facingDirectionChoice = *it;
		if (facingDirectionChoice == Positive_x)  // I decided that using switch (facingDirectionChoice) {case Positive_x: if (... was too clumsy in code and probably no more efficient.
		{  
			if (mainArea.locationAvailable (xChoice - 1, yChoice, zChoice))
				{guy->movesToNewLocation (xChoice - 1, yChoice, zChoice);  break;} 
			else
				guyFacingDirections.erase (it);  // more efficient than 'guyFacingDirections.remove (Positive_x);'
		}
		else if (facingDirectionChoice == Negative_x)
		{  
			if (mainArea.locationAvailable (xChoice + 1, yChoice, zChoice))
				{guy->movesToNewLocation (xChoice + 1, yChoice, zChoice);  break;} 
			else
				guyFacingDirections.erase (it);
		}
		else if (facingDirectionChoice == Positive_y)
		{  
			if (mainArea.locationAvailable (xChoice, yChoice - 1, zChoice))
				{guy->movesToNewLocation (xChoice, yChoice - 1, zChoice);  break;} 
			else
				guyFacingDirections.erase (it);
		}
		else if (facingDirectionChoice == Negative_y)
		{  
			if (mainArea.locationAvailable (xChoice, yChoice + 1, zChoice))
				{guy->movesToNewLocation (xChoice, yChoice + 1, zChoice);  break;} 
			else
				guyFacingDirections.erase (it);
		}
		else if (facingDirectionChoice == Positive_xPositive_y)
		{  
			if (mainArea.locationAvailable (xChoice - 1, yChoice - 1, zChoice))
				{guy->movesToNewLocation (xChoice - 1, yChoice - 1, zChoice);  break;} 
			else
				guyFacingDirections.erase (it);
		}
		else if (facingDirectionChoice == Positive_xNegative_y)
		{  
			if (mainArea.locationAvailable (xChoice - 1, yChoice + 1, zChoice))
				{guy->movesToNewLocation (xChoice - 1, yChoice + 1, zChoice);  break;} 
			else
				guyFacingDirections.erase (it);
		}
		else if (facingDirectionChoice == Negative_xPositive_y)
		{  
			if (mainArea.locationAvailable (xChoice + 1, yChoice - 1, zChoice))
				{guy->movesToNewLocation (xChoice + 1, yChoice - 1, zChoice);  break;} 
			else
				guyFacingDirections.erase (it);
		}
		else if (facingDirectionChoice == Negative_xNegative_y)
		{  
			if (mainArea.locationAvailable (xChoice + 1, yChoice + 1, zChoice))
				{guy->movesToNewLocation (xChoice + 1, yChoice + 1, zChoice);  break;} 
			else
				guyFacingDirections.erase (it);
		}
        }


There is a crowd of girls. Each guy will choose a girl, and then choose a facing direction to dance with his chosen girl. But not all facing directions are possible if someone is standing at the spot he wants to stand at to get his desired facing direction. Without randomizing the if-else statements, most of the guys will end up facing the same direction, which I don't like.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
struct direction
{
    FacingDirection dir ;
    int delta_x ;
    int delta_y ;
};

static std::vector<direction> directions =
{
    { Positive_x, 1, 0 },
    { Negative_x, -1, 0 },
    { Positive_y, 0, 1 },
    { Negative_y, 0, -1 },
    { Positive_xPositive_y, 1, 1 },
    { Positive_xNegative_y, 1, -1 },
    { Negative_xPositive_y, -1, 1 },
    { Negative_xNegative_y,  -1, -1 }
};

std::random_shuffle( std::begin(directions), std::end(directions) ) ;
FacingDirection chosen_direction ;

for( const direction& d : directions )
{
    const int x = xChoice + d.delta_x ;
    const int y = yChoice + d.delta_y ;

    if( mainArea.locationAvailable( x, y, zChoice ) )
    {
        guy->movesToNewLocation( x, y, zChoice ) ;
        chosen_direction = direction.dir ;
        break ;
    } 
}
Forgetting my code example for now, what is the most efficient way to randomize the ordering of the if statements:

1
2
3
4
5
6
7
8
9
10
11
if (statement_1)
    {action_1}
else if (statement_2)
    {action_2}
else if (statement_3)
    {action_3}
else if (statement_4)
.....

else if (statement_n)
    {action_n}


This way action_n will be executed just as often as action_1, action_2, action_3, even if statement_1 is usually true.

Edit: JLBorges response above appeared after I posted this (somehow). Thank you JLBorges, as always.
Last edited on
Ok, I used JLBorges suggested method. Here are my findings.

Compared to my original method (if-else statements not randomized), it is definitely slower. Compared to my std::list method above for randomizing the if-else statements, the performance is pretty much the same--choppy during the generation of the hundreds of guys' positions. However, thumbs up to his code because it tackles the problem of handling arbitrary large number of if-else statements (I didn't pay attention to that issue because I knew that I won't go past 8 if-statements).

It appears that there is currently no way to randomize the ordering of if-else statements while getting the performance to almost match that of an un-randomized set of if-else statements. It should be something for the C++14 committee to work on.
Last edited on
One last attempt at optimization, modifying JLBorges suggestion a bit:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
	struct Direction {
	    int delta_x;
	    int delta_y;
	    // FacingDirection dir;  // if this information is also desired
	    bool canFace (Guy* guy, int x, int y, int z) const {  
			if (guy->LocationSituated()->locationAvailable (x + delta_x, y + delta_y, z))
			{
				guy->movesToNewLocation (x + delta_x, y + delta_y, z);
				return true;  // return std::make_pair (true, dir); if FacingDirection information is needed (currently it is not)
			}
			return false;	
		}
	};
	static std::vector<Direction> directions = { {1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1} }; // static so initialization only once
	std::random_shuffle (std::begin (directions), std::end (directions));
	for (const Direction& d: directions)  // Range-based for-loop MIGHT give faster performance 
	    if (d.canFace (guy, xChoice, yChoice, zChoice))  
	    	break;
// (xChoice, yChoice, zChoice) is the position of the girl he wants to dance with 


But still no improvement in performance over my first method. But the code is now much more elegant and flexible.
Last edited on
> It appears that there is currently no way to randomize the ordering of if-else statements
> while getting the performance to almost match that of an un-randomized set of if-else statements.
> It should be something for the C++14 committee to work on.

Randomizing any sequence has an associated overhead; what do you expect the committee to do about it? Especially if this holds:
even if action_1 is usually true.


It can be made somewhat faster by shuffling just the order in which the if-else-if is accessed instead of shuffling the objects themselves. For instance:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <algorithm>
#include <iterator>

void random_if_else_if( int v )
{
    static const std::function< bool(int) > predicate_and_action[] =
    {
        []( int v )->bool { return v%2 ? std::cout << "odd\n" : false ; },
        []( int v )->bool { return v%2==0? std::cout << "even\n" : false ; },
        []( int v )->bool { return v%3==0 ? std::cout << "divisible by 3\n" : false ; },
        []( int v )->bool { return v%5==0 ? std::cout << "divisible by 5\n" : false ; },
        []( int v )->bool { return v%6==0 ? std::cout << "divisible by 6\n" : false ; },
        []( int v )->bool { return v < 10 ? std::cout << "less than 10\n" : false ; },
        []( int v )->bool { return v < 15 ? std::cout << "less than 15\n" : false ; },
        []( int v )->bool { return v < 20 ? std::cout << "less than 20\n" : false ; },
        []( int v )->bool { return v < 25 ? std::cout << "less than 25\n" : false ; },
        []( int v )->bool { return v < 30 ? std::cout << "less than 30\n" : false ; }
    };

    static std::size_t sequence[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } ;

    std::random_shuffle( std::begin(sequence), std::end(sequence) ) ;
    for( auto pos : sequence ) if( predicate_and_action[pos](v) ) break ;
}

int main()
{
    std::srand( std::time(nullptr) ) ;

    for( int i = 0 ; i < 20 ; ++i )
    {
        std::cout << i << ' ' ;
        random_if_else_if(i) ;
    }
}

http://coliru.stacked-crooked.com/a/f0f0bd680aed23d4

Remove the static storage duration specifiers, and it would be somewhat slower.
I will try shuffling lambda functions for my routine and report if it is any faster.
> I will try shuffling lambda functions for my routine and report if it is any faster.

No, it won't be any faster than the earlier code. It is more general, though.
Ok, I think the following shall be the latest word on randomizing general if-else statements. The recipe: list out all the if-conditions as lambda functions, shuffle the lambda functions, and then check each one. Credit to JLBorges. Anyone who can improve on its efficiency, please post your suggestions.
The function random_if_else_if can be used on any list of if-conditions, once you've listed them all once, as shown in the example in main. The argument of the if-conditions can be more than just one variable or type.
Last edited on
Here it is using variadic templates.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <algorithm>
#include <iterator>

std::vector<int> wholeNumbers (int n) {
	std::vector<int> v;
	for (int i = 0; i < n; i++)
		v.emplace_back (i);
	return v;
}

template <typename...T>
void random_if_else_if (const std::vector<std::function<bool(T...)>>& predicate_and_action, T...t) {
    static std::vector<int> sequence = wholeNumbers (predicate_and_action.size());  
    // initialize sequence just once for the entire program (and move constructor is called here)
    std::random_shuffle (std::begin (sequence), std::end (sequence));
    for (int pos : sequence)  // range-based for-loop might be faster than pre-C++11 for-loop
		if (predicate_and_action[pos](t...)) 
			break;
}

int main() {  // Example use of random_if_else_if
    std::srand (std::time (nullptr));
    const std::vector<std::function<bool(int, int, int, double, double, std::string)>> predicate_and_action = {
        [](int a, int b, int c, double d, double e, std::string s)->bool {return (a + b + c + (int)std::round(d + e) + s.length()) % 2 ? std::cout << "odd\n" : false ;},
        [](int a, int b, int c, double d, double e, std::string s)->bool {return (a + b + c + (int)std::round(d + e) + s.length()) % 2 == 0 ? std::cout << "even\n" : false ;},
        [](int a, int b, int c, double d, double e, std::string s)->bool {return (a + b + c + (int)std::round(d + e) + s.length()) % 3 == 0 ? std::cout << "divisible by 3\n" : false ;},
        [](int a, int b, int c, double d, double e, std::string s)->bool {return (a + b + c + (int)std::round(d + e) + s.length()) % 5 == 0 ? std::cout << "divisible by 5\n" : false ;},
        [](int a, int b, int c, double d, double e, std::string s)->bool {return (a + b + c + (int)std::round(d + e) + s.length()) % 6 == 0 ? std::cout << "divisible by 6\n" : false ;},
        [](int a, int b, int c, double d, double e, std::string s)->bool {return a + b + c + (int)std::round(d + e) + s.length() < 10 ? std::cout << "less than 10\n" : false ;},
        [](int a, int b, int c, double d, double e, std::string s)->bool {return a + b + c + (int)std::round(d + e) + s.length() < 15 ? std::cout << "less than 15\n" : false ;},
        [](int a, int b, int c, double d, double e, std::string s)->bool {return a + b + c + (int)std::round(d + e) + s.length() < 20 ? std::cout << "less than 20\n" : false ;},
        [](int a, int b, int c, double d, double e, std::string s)->bool {return a + b + c + (int)std::round(d + e) + s.length() < 25 ? std::cout << "less than 25\n" : false ;},
        [](int a, int b, int c, double d, double e, std::string s)->bool {return a + b + c + (int)std::round(d + e) + s.length() < 30 ? std::cout << "less than 30\n" : false ;}
    };
    const double PI = 3.14159;
    const std::string JLBorges = "JLBorges";
    for (int i = 0; i < 5; ++i)
    	for (int j = 0; j < 5; ++j)
    		for (int k = 0; k < 5; ++k)
		{
		        std::cout << i + j + k + int(std::round (4.1+PI)) + JLBorges.length() << ' ';
		        random_if_else_if (predicate_and_action, i, j, k, 4.1, PI, JLBorges);
		}        
} 


Tested with GCC 4.8.1. But when I change the parameter std::string to const std::string& it doesn't compile. I'm too new with parameter packs to see why that is. Can anyone shed some light on this?
Last edited on
No one has noticed that it seems a lot of work to randomize program flow over just randomizing choice of remaining locations...
Well, the thread is no longer about my specific example, but how best to randomize the order of if-statements in general. And I think the above code is one of the best ways to do it at the moment.
Last edited on
If we are generalizing it, this is not ideal; it assumes that the number of if-else-if clauses are always the same.
static std::vector<int> sequence = wholeNumbers (predicate_and_action.size());

Something like this would be more flexible:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <algorithm>
#include <iterator>
#include <numeric>

template< typename SEQ >
std::vector<std::size_t> shuffled_positions( const SEQ& seq )
{
	std::vector<std::size_t> v( seq.size() ) ;
	std::iota( std::begin(v), std::end(v), 0 ) ;
        std::random_shuffle( std::begin(v), std::end(v) ) ;
	return v ;
}

template < typename CALLABLE, typename... ARGS >
void random_if_else_if( const std::vector<CALLABLE>& predicate_and_action, ARGS&&... args  )
{
    for( auto pos : shuffled_positions(predicate_and_action) )
		if( predicate_and_action[pos]( args... ) ) break;
}

int main()
{
    std::srand( std::time (nullptr) ) ;

    std::vector< std::function< bool(int) > > predicate_and_action =
    {
        []( int v )->bool { return v%2 ? std::cout << "odd\n" : false ; },
        []( int v )->bool { return v%2==0? std::cout << "even\n" : false ; },
        []( int v )->bool { return v%3==0 ? std::cout << "divisible by 3\n" : false ; },
        []( int v )->bool { return v%5==0 ? std::cout << "divisible by 5\n" : false ; },
        []( int v )->bool { return v%6==0 ? std::cout << "divisible by 6\n" : false ; }
    };

    for( int i = 0 ; i < 15 ; ++i ) random_if_else_if( predicate_and_action, i ) ;
    std::cout << "----------------------\n" ;

    predicate_and_action.insert( predicate_and_action.end(),
    {
        []( int v )->bool { return v < 10 ? std::cout << "less than 10\n" : false ; },
        []( int v )->bool { return v < 15 ? std::cout << "less than 15\n" : false ; },
        []( int v )->bool { return v < 20 ? std::cout << "less than 20\n" : false ; },
    } );

    for( int i = 0 ; i < 15 ; ++i ) random_if_else_if( predicate_and_action, i ) ;
}

http://coliru.stacked-crooked.com/a/1911b2a834ebd619
So the static keyword won't be used even if the number of if-statements remains constant throughout an entire loop of random_if_else_if calls? std::iota needs to be called for every iteration of the loop even if the number of if-statements remains constant? Perhaps there should be two versions of random_if_else_if (but with two different names because the parameters are the same)?

Last edited on
Forgetting my code example for now, what is the most efficient way to randomize the ordering of the if statements:
1
2
3
4
5
6
7
8
9
10
11
if (statement_1)
    {action_1}
else if (statement_2)
    {action_2}
else if (statement_3)
    {action_3}
else if (statement_4)
.....

else if (statement_n)
    {action_n}

This way action_n will be executed just as often as action_1, action_2, action_3, even if statement_1 is usually true.

I'm out of my league here (what's a lambda function?) but assuming all the if-elses test the same type(s) here's what I'd do:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool func_1(*type(s) to test*) {definition here} //uses if (statement_1)
bool func_2(*type(s) to test*) {definition here} //uses if (statement_2)
etc.

bool (*pFuncs[num_of_tests])(*type(s) to test*) = {&func_1, &func_2, etc.}
while(something)
{
   //stuff
   shuffle pFuncs
   for (int i = 0; i < num_of_tests; ++i)
   {
      if (pFuncs[i](*thing(s) to test*))
         break;
   }
   //stuff
}


Note that the likelihood of action_n being executed also depends on how often statement_n is true, not just the order of the if-elses. If statement_n were never true, action_n would never be executed.
> what's a lambda function?

See: http://www.stroustrup.com/C++11FAQ.html#lambda


> here's what I'd do:

The code posted earlier is a generalised version of the very same idea.


> Perhaps there should be two versions of random_if_else_if
> (but with two different names because the parameters are the same)

Typically, the parameters won't be the same. With the size known at compile-time, the sequence would normally be a std::array<> or a c-style array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <algorithm>
#include <iterator>
#include <numeric>
#include <array>

template< typename SEQ >
std::vector<std::size_t> shuffled_positions( const SEQ& seq )
{
	std::vector<std::size_t> v( seq.size() ) ;
	std::iota( std::begin(v), std::end(v), 0 ) ;
        std::random_shuffle( std::begin(v), std::end(v) ) ;
	return v ;
}

template< std::size_t N > std::array< std::size_t, N >& shuffled_positions()
{
	static std::array< std::size_t, N > positions ;
	static int not_used = ( std::iota( std::begin(positions), std::end(positions), 0 ), 0 ) ;
        std::random_shuffle( std::begin(positions), std::end(positions) ) ;
	return positions ;
}

template < typename CALLABLE, typename... ARGS >
void random_if_else_if( const std::vector<CALLABLE>& predicate_and_action, ARGS&&... args  )
{
    for( auto pos : shuffled_positions(predicate_and_action) )
		if( predicate_and_action[pos]( args... ) ) break;
}

template < std::size_t N, typename CALLABLE, typename... ARGS >
void random_if_else_if( const std::array<CALLABLE,N>& predicate_and_action, ARGS&&... args  )
{
    for( auto pos : shuffled_positions<N>() )
		if( predicate_and_action[pos]( args... ) ) break;
}

template < std::size_t N, typename CALLABLE, typename... ARGS >
void random_if_else_if( CALLABLE (&predicate_and_action)[N], ARGS&&... args  )
{
    for( auto pos : shuffled_positions<N>() )
		if( predicate_and_action[pos]( args... ) ) break;
}

int main()
{
    std::srand( std::time (nullptr) ) ;

    const std::function< bool(int) > const_if_else_if[] =
    {
        []( int v )->bool { return v%2 ? std::cout << "odd\n" : false ; },
        []( int v )->bool { return v%2==0? std::cout << "even\n" : false ; },
        []( int v )->bool { return v%3==0 ? std::cout << "divisible by 3\n" : false ; },
        []( int v )->bool { return v%5==0 ? std::cout << "divisible by 5\n" : false ; },
        []( int v )->bool { return v%6==0 ? std::cout << "divisible by 6\n" : false ; }
    };

    std::vector< std::function< bool(int) > > if_else_if
    {
        []( int v )->bool { return v < 10 ? std::cout << "less than 10\n" : false ; },
        []( int v )->bool { return v < 15 ? std::cout << "less than 15\n" : false ; },
        []( int v )->bool { return v < 20 ? std::cout << "less than 20\n" : false ; },
    };

    for( int i = 0 ; i < 10 ; ++i )
    {
        std::cout << i << ' ' ;
        random_if_else_if( const_if_else_if, i ) ;
        std::cout << i << ' ' ;
        random_if_else_if( if_else_if, i ) ;
    }
}

http://coliru.stacked-crooked.com/a/abc9134a410a8a03
Read below.
Last edited on
What about a fourth overload of random_if_else_if that handles the case where the number of if-clauses is fixed but the number is unknown at compile time? Thus the vector is obtained by calling .emplace_back several times during the program, and then eventually random_if_else_if is called (with the aim to call shuffled_positions<N>() so that std::iota is called only once for this value of N). You know for certain that after random_if_else_if is called, the vector will not be modified. The current random_if_else_if version that uses std::vector as parameter calls std::iota every time.

I ALMOST got it working with
1
2
3
4
5
6
template <std::size_t N, typename CALLABLE, typename... ARGS>
void random_if_else_if (const std::vector<CALLABLE>& predicate_and_action, ARGS&&... args) {
	for (auto pos : shuffled_positions<N>()) 
		if (predicate_and_action[pos](args...)) 
			break;
}


And the test line
1
2
for (int i = 0; i < 10; ++i)
	random_if_else_if<5>(if_else_if, i);

works, but
1
2
3
const std::size_t k = if_else_if.size();
for (int i = 0; i < 10; ++i)
	random_if_else_if<k>(if_else_if, i);

does not compile. So close! How to fix this? I guess the problem is that k is not known at compile time, right?
Last edited on
> I guess the problem is that k is not known at compile time, right?

Yes.


> What about a fourth overload of random_if_else_if ...
> where the number of if-clauses is fixed but the number is unknown at compile time?
> so that std::iota is called only once

Such a function can be written quite easily (would require run-time checks if it is to be robust) as an academic exercise; but it would have little practical value.
The time taken by std::random_shuffle<>() would completely dominate the time taken for std::iota<>()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <random>
#include <ctime>
#include <cstdlib>
#include <algorithm>

struct cpu_timer
{
    ~cpu_timer()
    {
        auto end = std::clock() ;
        std::cout << double( end - begin ) / CLOCKS_PER_SEC << " secs.\n" ;
    };

    const std::clock_t begin = std::clock() ;
};

int main()
{
    constexpr int N = 128 ;
    static volatile std::size_t a[N] ;

    constexpr int M = 1024*1024 ;

    std::srand( std::time(nullptr) ) ;

    {
        std::cout << "std::iota: " ;
        cpu_timer timer ;
        for( int i = 0 ; i < M ; ++i ) std::iota( a, a+N, 0 ) ;
    }

    {
        std::cout << "std::random_shuffle: " ;
        cpu_timer timer ;
        for( int i = 0 ; i < M ; ++i ) std::random_shuffle( a, a+N ) ;
    }

    {
        std::cout << "std::shuffle (mt19937): " ;
        std::mt19937 twister( std::time(nullptr) ) ;
        cpu_timer timer ;
        for( int i = 0 ; i < M ; ++i ) std::shuffle( a, a+N, twister ) ;
    }
}

http://coliru.stacked-crooked.com/a/b4dd6899883bd441
Topic archived. No new replies allowed.