Live data from Hacker News

The Fisher-Yates shuffle is backward

possiblywrong.wordpress.com

11–20 of 23 posts

Re: The Fisher-Yates shuffle is backward

#11
There are actually four variants:

• loop counts downwards vs upwards

• the processed part of the array is a uniform sample of the whole array, or it is a segment that has been uniformly shuffled

Knuth described only the downwards sampling version, which is probably why it’s the most common.

The variants are compared quite well on wikipedia https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

Re: The Fisher-Yates shuffle is backward

#12
post #3

Huh I didn't know the backwards version was more common, it seems odd. You could also call the last version the online version, as it will ensure the partial list is random at any point in time (and can be used for inputs with indeterminate length, or to extend a random list with new elements, sample k elements etc.) Not too sure if the enumerate is necessary. I usually dislike using it just to have an index to play…

enumerate() is just an awkward way to get len(a). In theory, you could somehow be in an environment where you have dynamically resizing arrays (vectors) that don't track their length internally. But in this case it's probably because OP doesn't have a firm grasp what's happening (which is why they wrote the blog post).

Re: The Fisher-Yates shuffle is backward

#13
`forward_shuffle` is the (GROUP) INVERSE of `fisher_yates_shuffle`.

`mirror_shuffle` is the (GROUP) CONJUGATE of `fisher_yates_shuffle` by the cyclic permutation (n-1,n-2,...,1,0). In group theory, CONJUGATEs are like changes of coordinates. In the present application, they reverse the index labels.

The article said it, but it's worth distilling it.

PS: Oh, here's another link. Denote by "S!", or less formally, the factorial of a set S, to mean the set of permutations of S. Fisher-Yates is equivalent to a bijection between (S+1)! and S! × (S+1).

Re: The Fisher-Yates shuffle is backward

#14
post #5

I find the backward version slightly more intuitive. Here’s why: Suppose I want to uniformly randomly shuffle a deck of cards in a single pass. I stick the deck on the table and call it the non-shuffled pile. My goal is to move the deck, one card at a time, into the shuffled pile. First I need to select a card, uniformly at random, to be the bottom card of the new pile, and I move it over. Then I select another card,…

[deleted]

Re: The Fisher-Yates shuffle is backward

#15
post #11

There are actually four variants: • loop counts downwards vs upwards • the processed part of the array is a uniform sample of the whole array, or it is a segment that has been uniformly shuffled Knuth described only the downwards sampling version, which is probably why it’s the most common. The variants are compared quite well on wikipedia https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

It's interesting that the two forward versions of the algorithm were added to Wikipedia just a few months ago. (The OP article is from 2020.)

Re: The Fisher-Yates shuffle is backward

#17
I guess the reason is that the most interesting part of the problem is implementing non-biased selection from 0 to n and once you have done it you just want to use the number so it's natural to choose from the beginning of the array and swap to the last position beyond that.

Re: The Fisher-Yates shuffle is backward

#18
post #5

I find the backward version slightly more intuitive. Here’s why: Suppose I want to uniformly randomly shuffle a deck of cards in a single pass. I stick the deck on the table and call it the non-shuffled pile. My goal is to move the deck, one card at a time, into the shuffled pile. First I need to select a card, uniformly at random, to be the bottom card of the new pile, and I move it over. Then I select another card,…

That's quite clean, thanks!

Re: The Fisher-Yates shuffle is backward

#20

That’s funny. I’ve always done it the forwards way. I didn’t even realise that wasn’t the usual way. I suppose one of the benefits of having a poor memory is that one sometimes improves things in the course of rederiving them from an imperfect recollection.

Same, I've implemented it a number of times and always done it forward, and can't recall ever seeing it backwards. I've looked at the wikipedia page for it more than once too, which, as the article mentions, shows it backwards.

Maybe it's because it's so easy to prove to yourself that Fisher-Yates generates every possible combination with the same probability[1], and so forwards or backwards just doesn't register as relevant.

[1]This of course makes the a hefty assumption about the source of random numbers which is not true in the vast majority of cases where the algorithm is put into practice as PRNGs are typically what's used. For example if you use a PRNG with a 64 bit seed then you cannot possibly reach the vast majority of states for a 52 card deck; you need 226 bits of state for that to even be possible. And of course even if you are shuffling with fewer combinations than the PRNG state can represent, you will always have some (extremely slight) bias if the state does not express an integer multiple of the number of permutations of your array size.

Post reply on HN