Did you look at this part of the Wikipedia article? ...k_c said:I think the algorithm is OK. The assumption, of course, is that random numbers are generated by rand() in C++.
Care needs to be taken in implementing the Knuth shuffle; even slight deviations from the correct algorithm will produce biased shuffles. For example, working your way through the pack swapping each card in turn with a random card from any part of the pack is an algorithm with n^n different possible execution paths, yet there are only n! permutations, and a counting argument based on using the pigeonhole principle on assignments of execution paths to outcomes shows that this algorithm cannot produce an unbiased shuffle, unlike the true Knuth shuffle, which has n! execution paths which match up one-to-one with the possible permutations.
For an example of how this pigeonhole argument works on the n^n shuffle, consider the simple case of shuffling only three cards, so that n=3. Then there are n^n = 27 different possible execution paths (these are the 27 things to put in the pigeonholes). But there are only 3! = 6 ways to permute three cards (these are the 6 pigeonholes to put the things in). 27 is odd, and 6 is even, so 27 things cannot be divided evenly into 6 pigeonholes. Therefore, if we assume that the execution paths are equiprobable, then the outcomes cannot be, since at least two of the different outcomes must have different probabilities. Therefore the n^n shuffle cannot be unbiased for n=3. Similar reasoning can be applied for other values of n > 2.
Indeed. The purpose of my randint(n) function is to produce an unbiased, random number in the range 0..n-1. This is needed for use by the Knuth (aka Fisher-Yates) shuffle ...k_c said:The other problem is that even if it is guaranteed that the numbers are random, if the number of possible random numbers is not a multiple of 52 then a bias will exist. For example if we wanted to generate a random number in the range 0 to 51 and we are given a guaranteed random number from the range 0 to 77 instead of 0 to 32767:
Define r() = random number 0 to 77
num = r() % 52 is always a number 0-51
Here the bias is more obvious though. Since r() is in the range 0-77, num is twice as likely to be 0-25 when compared to 26-51. The problem would be fixed if we could somehow redefine r() to be a guaranteed random number in the range 0-51, but that would solve the problem without having to do anything else. :laugh:
For a 52-card deck, cards[0] to cards[51] -
- swap cards[51] with a random card from cards[0 to 51]
- swap cards[50] with a random card from cards[0 to 50]
- ....
- swap cards[01] with a random card from cards[0 to 01]