Go语言 用简单的 Shuffle 来平均分配吗

eoigrqb6  于 2023-02-17  发布在  Go
关注(0)|答案(2)|浏览(179)

我正在对一个3int的数组进行600万次的 Shuffle ,我在一个map中记录了数组的每一次排列,代码如下。

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)
    }

}

因为我是在做简单的 Shuffle ,我的理解是它应该产生一个均匀的排列分布,但这是我得到的结果:

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

这表明6种可能的排列中的每一种都发生了大约1M次。为什么我得到的似乎是均匀分布?
编辑:将代码更改为仅播种一次。我现在得到:

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

编辑2:多亏了霍布斯,我意识到我犯了一个愚蠢的错误。我应该 Shuffle a,而不是arr。我现在得到:

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

ldfqzlk81#

你对arr进行了600多万次 Shuffle ,而在两次 Shuffle 之间没有将其恢复到初始状态--换句话说,你的600万次尝试并不是“独立的”,即使每次 Shuffle 的排列分布不均匀,但将这些排列组合600万次,会得到一个非常接近均匀的分布。

brccelvz

brccelvz2#

即使你把它恢复到原来的状态。这不是一个随机事件:
让我们列举所有案例:

m := map[string]int{}
    for i := 0; i < 3; i++ {
        for j := 0; j < 3; j++ {
            for k := 0; k < 3; k++ {
                a := []string{"a", "b", "c"}
                a[i], a[0] = a[0], a[i]
                a[j], a[1] = a[1], a[j]
                a[k], a[2] = a[2], a[k]
                m[a[0]+a[1]+a[2]]++
                fmt.Printf("%v\n", a)
            }
        }
    }
    fmt.Printf("%v\n", m)

结果:

map[abc:4 acb:5 bac:5 bca:5 cab:4 cba:4]

它有所有3*3*3 = 27的情况,但只有C(3,1)= 6的结果,它一定不等于(4:5)。

相关问题