gpt4 book ai didi

go - 在时间种子后按顺序生成相同的随机数? (在我的机器上运行)

转载 作者:IT王子 更新时间:2023-10-29 01:20:47 25 4
gpt4 key购买 nike

我试图准确理解为什么当从外部函数调用时,我的时间种子随机数生成器会返回相同数字的序列。

问题的最小工作示例:

package main

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

//Generates random int as function of range
func getRand(Range int) int {
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
return r1.Intn(Range)
}

//Print 100 random ints between 0 and 100
func main() {
for i := 0; i < 100; i++ {
fmt.Print(getRand(100), ", ")
}
}

这个的输出是

Out[1]: 40, 40, 40, 40, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 34,
34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47,47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99,

我想知道为什么我自己的教育会发生这种情况。我也乐于接受解决方案的建议。

详细信息:我需要在我的代码的许多外部函数中调用随机数,但是,就像这个 MWE,当在 main 以外的函数中播种时,它们会重复返回相同的数字。此外,我需要动态更新范围,因此无法先验生成列表。我宁愿不必在 main() 中生成数字并将它们传递给每个函数——范围是在这些函数中计算的,这会使事情复杂化

最佳答案

这是因为time.Time有一个粒度(1 纳秒)就像你的系统时钟(甚至可能是几毫秒——取决于很多事情),如果你调用 time.Now()在这些粒度中的较大者中多次,返回的 time.Time 可能是相同的,这意味着它的 Time.UnixNano()方法将返回相同的纳秒(相同的数字)。

如果您使用与种子相同的数字,则随机数生成器应该返回相同的数字。

您只需在应用程序启动时为 RNG 播种一次,而不是在每次使用之前。您可以为此使用包 init() 函数,或在变量声明中:

var r = rand.New(rand.NewSource(time.Now().UnixNano()))

//Generates random int as function of range
func getRand(Range int) int {
return r.Intn(Range)
}

//Print 100 random ints between 0 and 100
func main() {
for i := 0; i < 100; i++ {
fmt.Print(getRand(100), ", ")
}
}

示例输出(在 Go Playground 上尝试):

0, 28, 27, 62, 63, 89, 24, 27, 88, 84, 82, 55, 49, 35, 2, 32, 84, 58, 78, 28, 26, 58, 30, 28, 74, 6, 39, 24, 40, 47, 49, 39, 61, 62, 67, 7, 94, 87, 37, 99, 90, 80, 93, 83, 27, 69, 25, 45, 99, 12, 44, 39, 34, 86, 18, 42, 76, 40, 44, 12, 70, 3, 70, 99, 57, 43, 90, 65, 97, 64, 68, 60, 65, 56, 3, 81, 54, 56, 43, 57, 92, 93, 54, 92, 9, 86, 16, 72, 29, 12, 97, 87, 55, 42, 87, 41, 94, 53, 23, 64,

这里要注意一件事:rand.NewSource()返回并发使用不安全的源。如果需要从多个goroutine调用getRand(),需要同步访问r,或者使用单独的rand.Rand在每个 goroutine 中。

关于go - 在时间种子后按顺序生成相同的随机数? (在我的机器上运行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52276548/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com