Is there something wrong with this shuffling algorithm?

I do a little fun computing. My mini-project was a simulation of the Italian game "tomboli". A key building block was the simulation of the following process:

The game is controlled by a person with a bag of 90 marbles with numbers from 1 to 90. He draws balls one after another randomly from the bag, each time calling the marble number to the players.

After a little thought, I wrote the following code for this building block:

// NBR marbles, numbered 1...NBR are in a bag. Simulate randomly
//  pulling them from the bag, one by one, until the bag is empty
void bag( int random_sequence[NBR] )
{
    int i;

    // Store each marble as it is pulled out
    int *store = random_sequence;

    // Array of marbles still in the bag
    int not_yet_pulled[NBR];
    for( i=0; i<NBR; i++ )
        not_yet_pulled[i] = i+1;    // eg NBR=90; 1,2,3 ... 90

    // Loop pulling marbles from the bag, one each time through
    for( i=NBR; i>=1; i-- )
    {
        int x = rand();
        int idx = x%i;  // eg i=90 idx is random in range 0..89
                        // eg i=89 idx is random in range 0..88
                        //            ...
                        // eg i=1  idx is random in range 0..0
                        //    (so we could optimize when i=1 but not worth the bother)
        *store++  = not_yet_pulled[idx];

        // Replace the marble just drawn (so it cannot be pulled again)
        //     with the last marble in the bag. So;
        //     1) there is now one less marble in the bag
        //     2) only marbles not yet pulled are still in the bag
        // If we happened to pull the last marble in the *current subarray*, this is
        //    not required but does no harm.
        not_yet_pulled[idx] = not_yet_pulled[i-1];
    }
}

I know that while modeling games with random numbers there are subtleties and traps, therefore, although I am very pleased with my code, my confidence is slightly less than 100%. So my questions are:

1) Is there something wrong with my code?

2) [if the answer is 1) no] Am I unconsciously using the standard shuffling algorithm?

3) [ 2) ] ?

, . , , -, . , , , . , , . , , , . , , , , , .

, , , , rand()% N 0..N- 1.

, Fisher-Yates , . , .

+4
8
+7

Fisher-Yates-Knuth shuffle:

public static void shuffle(int[] array) 
{
    Random rng = new Random();       // java.util.Random.
    // n is the number of items left to shuffle
    for (int n = array.length; n > 1; n--) 
    {
        // Pick a random element to move to the end
        int k = rng.nextInt(n);  // 0 <= k <= n - 1.
        // Simple swap of variables
        int tmp = array[k];
        array[k] = array[n - 1];
        array[n - 1] = tmp;
    }
}

, , . , .

+11
int idx = x%i;  // eg i=90 idx is random in range 0..89

, , 90 ( NBR) max (rand()). 2- , , . idx, , 0, 89. ,

+7

, , , .
(, , ), , .

, .
std:: random_shuffle()?

 void bag( int random_sequence[NBR] )
 {
     for(int i=0; i<NBR; ++i) 
     {    random_sequence[i] = i+1;
     }
     std::random_shuffle(random_sequence,random_sequence + NBR);
 }

std:: random_shuffle():

3.4.2 (D. E. Knuth, The Art of Computer Programming, 2: , . Addison-Wesley, 1981). (1963) (1964). , N! N . Random_shuffle ; .. 1/N!. , , , , , N! . , .

+2

rand() % i, ( ), (int) ((rand() / (double) (RAND_MAX+1)) * i).

, , Mersenne twister.

+2

:

  • , IDX. .
  • , , , marblesRemaining, , . , .
+1

, .

, : , . , .

+1

, .

, C/++ .

, , . . ., , Pokerstars .

Earlier versions of Netscape encryption were compromised because hackers were able to predict the "random" number used, since the pseudo-random number generator was populated by the current time. See the Wikipedia entry .

0
source

All Articles