2 ms·
Right. The subtle difference being that because you only sample from position i to n you only ever exchange each card exactly once. In my algo you sample from
by seanhunter 4y ago
Right. The subtle difference being that because you only sample from position i to n you only ever exchange each card exactly once. In my algo you sample from 0 to n-1 so a card exchanged in a previous round can be exchanged again. This generalises into cards early in the shuffle being exchanged more than later cards, which changes the distribution of possible outcomes.
Nerd sidenote: Because generating random numbers tends to be expensive, I had an idea once where you generate the full permutation with only a single random sample. Basically you could use something which fully enumerates a space like Gray codes[1] (you want one with a closed form solution which can arbitrarily you the nth code) then you generate one random number, multiply by the number of combinations, look up that code and decode that into the sequence of cards. I never actually got around to implementing it, but I suspect if your code lookup was fast it would be much faster than Fisher-Yates.
The use case was if you wanted to make a Monte Carlo algorithm to evaluate strategies in a card game for instance.
[1] https://en.wikipedia.org/wiki/Gray_code https://en.wikipedia.org/wiki/Gray_code
- 6keZbCECT2uB 4y agoI've wondered about the same thing of generating a permutation with a minimum number of samples. I'm not sure how Gray codes helps you here, and the multiplication sounds wrong since many outputs aren't reachable from any input.
- seanhunter 4y agoThe idea is just a closed form solution that gets you from a number in 1...nPermutations to a single specific permutation. I was using Gray codes as an example of a sequence that exhausts all permutations with a closed form that gets you to a specific point in the sequence. Might not work - as I say I never actually got around to implementing it.
- erikstrand 4y agoI think you're looking for a factorial number system [1] and/or Lehmer code [2]. [1] https://en.wikipedia.org/wiki/Factorial_number_system https://en.wikipedia.org/wiki/Factorial_number_system [2] https://en.wikipedia.org/wiki/Lehmer_code https://en.wikipedia.org/wiki/Lehmer_code
- seanhunter 4y agoThanks!
- Someone 4y agoYou’ll find that the number of ways to shuffle a card pack (52!) is about 8 × 10⁶⁷, so even if your RNG returns 64 bits, you can’t use a single call. Also, you’ll have to make sure you pick each permutation is picked with equal probability. random() % factorial(52) likely won’t work because your RNG won’t return integers in a range k × 52! for some k > 1 (https://stackoverflow.com/questions/10984974/why-do-people-say-there-is-modulo-bias-when-using-a-random-number-generator https://stackoverflow.com/questions/10984974/why-do-people-s...)
- Adverblessly 4y agoI wrote that code for fun 15-20 years ago (code definitely lost in the mists of time). You can think of it as rolling one random number up to n!, then use x%n to pick the first element and then x/n to pick the next (n-1) elements (so the next step is then to pick the second element with (x/n)%(n-1) and use (x/n)/(n-1) for the remaining (n-2) elements). Though as a sibling comment points out, since you need a random number up to n!, even 64 bits of randomness only get you so far (I think up to 20, but didn't check my math).