DEV Community

Cover image for Fisher–Yates shuffle
Manmeet
Manmeet

Posted on

Fisher–Yates shuffle

Prologue :

The Fisher–Yates shuffle is an algorithm for generating a random permutation of a finite sequence

Fisher and Yates' original method (Pencil-and-paper method)

  1. We'll start by writing the numbers out on a piece of scratch paper: Alt Text

2.Now we roll a random number k from 1 to 8—let's make it 3—and strike out the kth (i.e. third) number on the scratch pad and write it down as the result

Alt Text

3.Now we pick a second random number, this time from 1 to 7: it turns out to be 4. Now we strike out the fourth number not yet struck off the scratch pad—that's number 5—and add it to the result:

Alt Text

4.Now we pick the next random number from 1 to 6, and then from 1 to 5, and so on, always repeating the strike-out process as above:

Alt Text

Modern method (Durstenfeld's version )

this time, instead of striking out the chosen numbers and copying them elsewhere, we'll swap them with the last number not yet chosen.

1.We'll start by writing out the numbers from 1 to 8 as before

Alt Text

2.For our first roll, we roll a random number from 1 to 8: this time it is 6, so we swap the 6th and 8th numbers in the list:

Alt Text

3.The next random number we roll from 1 to 7, and turns out to be 2. Thus, we swap the 2nd and 7th numbers and move on:

Alt Text

4.The next random number we roll is from 1 to 6, and just happens to be 6, which means we leave the 6th number in the list (which, after the swap above, is now number 8) in place and just move to the next step. Again, we proceed the same way until the permutation is complete:

Alt Text

JS Code

function fisherYatesDrip(a) {
    var j, x, i;
    for (i = a.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = a[i];
        a[i] = a[j];
        a[j] = x;
    }
    return a;
}

Time Complexity

Fisher–Yates shuffle Algorithm works in O(n) time complexity. The assumption here is, we are given a function rand() that generates random number in O(1) time.
The idea is to start from the last element, swap it with a randomly selected element from the whole array (including last). Now consider the array from 0 to n-2 (size reduced by 1), and repeat the process till we hit the first element.

Potential source of Bias

A common error when implementing the Fisher–Yates shuffle is to pick the random numbers from the wrong range. The flawed algorithm may appear to work correctly, but it will not produce each possible permutation with equal probability, and it may not produce certain permutations at all. For example, a common off-by-one error would be choosing the index j of the entry to swap in the JS code above to be always strictly less than the index i of the entry it will be swapped with. This turns the Fisher–Yates shuffle into Sattolo's algorithm, which produces only permutations consisting of a single cycle involving all elements: in particular, with this modification, no element of the array can ever end up in its original position.

Top comments (0)