我想生成一个重复的随机序列,只使用每个数字一次。例如,给定0-9的范围,有2个不同的种子,你可能会得到
Seed 1: 7 3 5 9 0 8 1 2 6 4 | 7 3 5 9 0 8 1 2 6 4 | 7 3 5 9 0 8 1 2 6 4
Seed 2: 2 5 7 1 4 9 6 8 3 0 | 2 5 7 1 4 9 6 8 3 0 | 2 5 7 1 4 9 6 8 3 0
根据我的理解,线性同余随机数发生器或LCRNG或LCG可以给我这个http://en.wikipedia.org/wiki/Linear_congruential_generator
知道C#中是否存在实现,或者我是如何开始编写实现的。
Mersenne Twister与LCG有何不同?
不确定我的所有问题都得到了解答,但这是我最终使用的问题。因为我将样本大小限制在从max到min的值范围内,所以只要给出相同的初始种子,我就选择保持静态的不同素数。我这样做是因为我想要相同的序列给出相同的种子和相同的最小/最大界限,以确保测试的可重复性。
请批评我在这里做的任何事情,这正是我在一瞬间提出的:
using System;
using System.Collections.Generic;
namespace FULLCYCLE
{
public class RandomNumber
{
private int _value;
private int _prime;
private static List<int> primes = new List<int>()
{
11,
23,
47,
97,
797,
1597,
6421,
25717,
51437,
102877,
411527,
823117,
1646237,
3292489,
6584983,
13169977,
26339969,
52679969,
105359939,
210719881,
421439783,
842879579,
1685759167
};
public RandomNumber( int seed )
{
_prime = primes[seed%primes.Count];
_value = seed;
}
public int Next( int min, int max )
{
int maxrate = (max-min+1);
if (_value > maxrate)
{
_value = _value % maxrate;
}
_value = (_value + _prime) % maxrate;
return _value + min;
}
}
}
答案 0 :(得分:1)
为什么不在输入序列中使用现有的Random
类和Knuth shuffle?
答案 1 :(得分:1)
关于您的编辑,您的LCG作为随机数生成器有几个问题......
它可以产生明显的模式:
// generates 3, 4, 5, 6, 7, 8, 9, 0, 1, 2
var rng = new RandomNumber(42);
for (int i = 0; i < 10; i++) Console.WriteLine(rng.Next(0, 9));
它可以重演:
// generates 579, 579, 579, 579, 579, 579, 579, 579, 579, 579
var rng = new RandomNumber(123);
for (int i = 0; i < 10; i++) Console.WriteLine(rng.Next(456, 51892));
还有许多其他种子/最小/最大组合会产生有问题的结果。