在时间种子之后按顺序生成相同的随机数?(在我的机器上运行) [英] Generating identical random numbers in sequence after time seed? (Running on my machine)

查看:56
本文介绍了在时间种子之后按顺序生成相同的随机数?(在我的机器上运行)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to understand precisely why, when called from an external function, my time seeded random number generator returns sequences of identical numbers.

问题的最小工作示例:

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,

我想知道为什么这种情况发生在我自己的教育中.我也欢迎提出解决方案的建议.

I'd like to know why this is happening for my own education. I'm also open to suggestions for a solution.

详细信息:我需要在代码的许多外部函数中调用随机数,但是像MWE一样,当将其植入main函数之外的函数中时,它们会反复返回相同的数字.此外,我需要动态更新范围,因此优先选择生成列表不是一种选择.我宁愿不必在main()中生成数字并将其传递给每个函数-范围是在这些函数内部计算的,这会使事情复杂化

Details: I need to call random numbers in lots of external functions of my code but, like this MWE, when seeded within a function other than main they repeatedly return the same numbers. Additionally, I need to dynamically update the range, so generating lists a priori is not an option. I would rather not have to generate the numbers in main() and pass them into each function-- ranges are calculated inside these and it would complicate things

推荐答案

这是因为 time.Time 具有与系统时钟一样的粒度(1纳秒)(可能甚至是几毫秒,取决于许多情况),并且如果您调用 Time.UnixNano() 方法将为您返回相同的纳秒(相同的数字).

This is because time.Time has a granularity (which is 1 nanosecond) just like your system clock (which might even be multiple milliseconds–depends on many things), and if you call time.Now() multiple times within the greater of these granularities, chances are the returned time.Time will be the same, meaning its Time.UnixNano() method will return you the same nanoseconds (the same number).

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

And if you use the same number as the seed, the random number generator is ought to return the same numbers.

您只需在应用启动时为RNG播种一次,而无需在每次使用前播种.您可以为此使用包 init()函数,也可以在变量声明中使用它:

You only need to seed the RNG once, on app startup, not before each use. You may use a package init() function for that, or in the variable declaration:

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

示例输出(在游乐场上尝试):

Example output (try it on the 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,

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 的访问,或者使用单独的

One thing to note here: rand.NewSource() returns a source which is not safe for concurrent use. If you need to call getRand() from multiple goroutines, you need to synchronize access to r, or use a separate rand.Rand in each goroutine.

这篇关于在时间种子之后按顺序生成相同的随机数?(在我的机器上运行)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆