鉴于以下内容:
for(int seed = 0; seed < 100; seed++) {
var random = new Random(seed);
var roll = (random.Next() % 6) + 1;
Console.Write(roll + " ");
}
我在输出中看到一个清晰的模式:
1 1 2 2 3 3 4 4 5 5 6 6 1 1 1 2 2 3 3 4 4 5 5 6 6
1 1 2 2 3 3 4 4 5 5 5 6 6 1 1 2 2 3 3 4 4 5 5 6 6
1 1 2 2 3 3 4 4 4 5 5 6 6 1 1 2 2 3 3 4 4 5 5 6 6
1 1 2 2 3 3 3 4 4 5 5 6 6 1 1 2 2 3 3 4 4 5 5 6 6
我确实理解每次使用顺序种子重新创建一个新的Random
对象并不是使用该类的“正确”方式,严格来说我应该保留Random
实例周围,每次都在上面调用Next()
。
但是,我的用例是我需要能够退出程序并随时恢复状态,并继续编号。
我还需要用户能够手动设置种子,所以我希望能够做到这样的事情:
var random = new Random(userSeed + nextValueIndex);
var chosenValue = random.Next();
我也尝试过random.Next(min, max)
,它会给出不同的结果,但也会有明确的模式。
显然,我的方法不是使用Random
类的正确方法,但对于我的用例是什么?
我理解随机数生成是一个非常复杂的主题,所以虽然我有兴趣解释为什么会发生这种情况,但我最感兴趣的是一个实用的(简单?)解决方案; - )
答案 0 :(得分:0)
这是我的解决方案,它看起来效果很好。我只是将Random
的确切结果缓存为userSeed + index
,而不是将index
与Random
一起设置为previousRandom
。 {1}}。这样,我得到了很好的大数字作为种子,它避免了顺序模式。 (userSeed + previousRandom
初始化为零,但这不是问题。)
所以,这大致是我的代码:
previousRandom
我应该做的另一件事是确保var nextSeed = userSeed + this.previousRandom;
var randomObj = new Random(nextSeed);
var nextRandomValue = randomObj.Next ();
var chosenValue = (nextRandomValue % randomRange) + rangeMin;
this.previousRandom = nextRandomValue;
return chosenValue;
不会溢出(或可预测溢出),因为userSeed + previousRandom
可能非常接近previousRandom
&# 39; s上限(达到int
允许的任何范围)。