问题:如何在Go中生成唯一的随机数流?
即,我想保证a使用math/rand和/或标准Go库实用程序的数组中没有重复。
func RandomNumberGenerator() *rand.Rand {
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
return r1
}
rng := RandomNumberGenerator()
N := 10000
for i := 0; i < N; i++ {
a[i] = rng.Int()
}
Run Code Online (Sandbox Code Playgroud)
有关如何在Go中生成一系列随机数的问题和解决方案,例如,在此处。
但是现在我想生成一系列随机数,这些随机数不会与以前的值重复。Go中是否有标准/推荐的方法?
我的猜测是(1)使用置换或(2)跟踪先前生成的数字并重新生成一个值(如果该值之前已生成)。
但是,如果我只想要几个数字,解决方案(1)听起来像是一个过大的杀伤力;如果由于碰撞而最终生成一连串的随机数,则解决方案(2)听起来很耗时,而且我猜想它也非常消耗内存。
用例:用没有重复的10K,100K,1M伪随机数对Go程序进行基准测试。
基于 @joshlf 的回答的临时解决方法
type UniqueRand struct {
generated map[int]bool //keeps track of
rng *rand.Rand //underlying random number generator
scope int //scope of number to be generated
}
//Generating unique rand less than N
//If N is less or equal to 0, the scope will be unlimited
//If N is greater than 0, it will generate (-scope, +scope)
//If no more unique number can be generated, it will return -1 forwards
func NewUniqueRand(N int) *UniqueRand{
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
return &UniqueRand{
generated: map[int]bool{},
rng: r1,
scope: N,
}
}
func (u *UniqueRand) Int() int {
if u.scope > 0 && len(u.generated) >= u.scope {
return -1
}
for {
var i int
if u.scope > 0 {
i = u.rng.Int() % u.scope
}else{
i = u.rng.Int()
}
if !u.generated[i] {
u.generated[i] = true
return i
}
}
}
Run Code Online (Sandbox Code Playgroud)
客户端代码
func TestSetGet2(t *testing.T) {
const N = 10000
for _, mask := range []int{0, -1, 0x555555, 0xaaaaaa, 0x333333, 0xcccccc, 0x314159} {
rng := NewUniqueRand(2*N)
a := make([]int, N)
for i := 0; i < N; i++ {
a[i] = (rng.Int() ^ mask) << 1
}
//Benchmark Code
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5824 次 |
| 最近记录: |