首頁  >  文章  >  後端開發  >  均勻分佈與天真的洗牌?

均勻分佈與天真的洗牌?

王林
王林轉載
2024-02-09 08:30:09861瀏覽

均勻分佈與天真的洗牌?

php小編小新將為大家揭秘"均勻分佈與天真的洗牌"之間的關係。在計算機科學中,洗牌是一種重要的操作,常用於隨機化資料或集合。而均勻分佈是指在一定範圍內的隨機數分佈是平均的。那麼,洗牌是否能保證均勻分佈呢?答案並不簡單,讓我們一起來探討這個問題。

問題內容

我正在對一個 3 int 陣列進行 600 萬次洗牌。我在地圖中記錄數組的每個排列。下面是使用 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)
    }

}

由於我正在進行簡單的洗牌,我的理解是它不應該產生均勻分佈的排列。但這就是我得到的:

[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 種可能的排列中的每一種都發生大約 100 萬次。為什麼我得到的分佈看起來是均勻的?

編輯:將程式碼變更為僅種子一次。我現在得到:

[-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:感謝霍布斯,我意識到我犯了一個愚蠢的錯誤。我應該洗牌 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

解決方法

您對arr 進行了超過600 萬次洗牌,而沒有在兩次洗牌之間將其恢復到其原始狀態-換句話說,您的600 萬次試驗並不是獨立的。儘管每次洗牌的排列分佈不均勻,但將這些排列相互疊加 600 萬次會產生非常接近均勻的分佈。

以上是均勻分佈與天真的洗牌?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除