Search code examples
goshuffle

even distribution with naive shuffle?


I'm shuffling an array of 3 int, 6 millions times. I keep count of each permutation of the array in a map. Code is below using go.

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func randRange(min, max int) int {
    return rand.Intn(max-min+1) + min
}

func NaiveShuffle(arr *[3]int) {
    for i := 0; i < 3; i++ {
        e := randRange(0, 2)
        arr[e], arr[i] = arr[i], arr[e]
    }
}

func main() {
    rand.Seed(time.Now().UnixNano())
    m := make(map[[3]int]int, 6)
    arr := [3]int{-6,10,184}

    for i := 1; i <= 6000000; i++ {
        a := arr
        NaiveShuffle(&arr)
        m[a]++
    }

    for k, v := range m {
        fmt.Println(k, ":", v)
    }

}

Since I'm doing naive shuffle my understanding is it should not produce an even distribution of permutations. But this is what I get:

[184 -6 10] : 1000074
[184 10 -6] : 1000764
[-6 10 184] : 1000766
[10 184 -6] : 998090
[-6 184 10] : 1000479
[10 -6 184] : 999827

This shows each of the 6 possible permutations occurs about ~1M times. Why do I get what appears to be an even distribution ?

EDIT: changed code to only seed once. I now get:

[-6 184 10] : 999507
[184 -6 10] : 1000401
[10 -6 184] : 1002163
[10 184 -6] : 999236
[-6 10 184] : 999016
[184 10 -6] : 999677

EDIT2: Thanks to hobbs, I realized I made a silly mistake. I should shuffle a, not arr. I now get:

[10 -6 184] : 1111056
[-6 10 184] : 888442
[184 -6 10] : 888576
[10 184 -6] : 1109896
[-6 184 10] : 1113148
[184 10 -6] : 888882

Solution

  • You're shuffling arr over and over six million times without restoring it to its original state in between shuffles — in other words, your six million trials aren't independent. Even though each shuffle has an uneven distribution of permutations, composing those permutations on top of each other six million times results in a distribution that's quite close to uniform.