It shuffles an array of size so that possible permutations are equiprobable.
Require: array A made of n elements indexed from 0 to n − 1
1: for i = (n − 1)..1 do
2: j ← random integer in [0, i]
3: exchange A[i] and A[j]
4: end for
- We count
i
down because we need a new seed every time we callrand
Proof
- We start with an array
x = [1, 2. ..., N]
- There are possible permutation.
- We consider an arbitrary array
x' = [b1, b2, ..., bN]
, whereb1, ..., bN]
are distinct integers between 1 and n.- Intuition: Every element gets shuffled
- What’s the Probability that x transferred to x’ ?
- QED
Optimize?
It’s a nicer? simpler? solution to the shuffling problem:
- Loop through each card in the deck.
- Swap the current card with another randomly chosen card.
// CAVET: BIASED
for (int i = 0; i < cards.Length; i++)
{
int n = rand.Next(cards.Length);
Swap(ref cards[i], ref cards[n]);
}
The evil lies in rand.Next
, where it is always rand.Next(3)
, giving us results. But it should only have results.
Compared to the original method.
for (int i = cards.Length - 1; i > 0; i--)
{
int n = rand.Next(i + 1);
Swap(ref cards[i], ref cards[n]);
}