使用顺序种子时C#的随机生成可识别模式

时间:2016-09-11 16:16:03

标签: c# random

鉴于以下内容:

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类的正确方法,但对于我的用例是什么?

我理解随机数生成是一个非常复杂的主题,所以虽然我有兴趣解释为什么会发生这种情况,但我最感兴趣的是一个实用的(简单?)解决方案; - )

1 个答案:

答案 0 :(得分:0)

这是我的解决方案,它看起来效果很好。我只是将Random的确切结果缓存为userSeed + index,而不是将indexRandom一起设置为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允许的任何范围)。