The classic Fisher Yates looks something like this:
void shuffle1(std::vector<int>& vec)
{
int n = vec.size();
for (int i = n - 1; i > 0; --i)
{
std::swap(vec[i], vec[rand() % (i + 1)]);
}
}
Yesterday, I implemented the iteration "backwards" by mistake:
void shuffle2(std::vector<int>& vec)
{
int n = vec.size();
for (int i = 1; i < n; ++i)
{
std::swap(vec[i], vec[rand() % (i + 1)]);
}
}
Is this version in any way worse (or better) than the first? Does it skew the resulting probabilities?
Yes it's even distribution assuming
rand()
is. We will prove this by showing that each input can generate each permutation with equal probability.N=2 can be easily proven. We will draw it as a tree where the the children represent each string you can get by inserting the character after comma into the leftmost string.
For N, we will have every permutations for N-1, and randomly swapping the last character for N
This shitty induction should lead you to it having even distribution.
Example:
N=2:
N=3:
N=4: (curved to aid reading)
etc