把它定义在方法外部,例如private static Random random = new Random();"
可以看一下 Random 类的源代码 public Random() : this(Environment.TickCount) { } public Random(int Seed) { int seedArray = 161803398 - Math.Abs(Seed); this.SeedArray[55] = seedArray; int num = 1; for (int i = 1; i < 55; i++) { int num1 = 21 * i % 55; this.SeedArray[num1] = num; num = seedArray - num; if (num < 0) { num = num + 2147483647; } seedArray = this.SeedArray[num1]; } for (int j = 1; j < 5; j++) { for (int k = 1; k < 56; k++) { this.SeedArray[k] = this.SeedArray[k] - this.SeedArray[1 + (k + 30) % 55]; if (this.SeedArray[k] < 0) { this.SeedArray[k] = this.SeedArray[k] + 2147483647; } } } this.inext = 0; this.inextp = 21; Seed = 1; } 当你使用无参数的实例化方法时,它就是用当前时间的 Ticks 数值做为“种子”,因此快速连续调用它,会连续取得相同的结果。如果想连续快速地创建它的对象实例,你就要直接使用第二个——但有一个参数的——实例化方法,并且每一次改变种子值。例如写var seed = Datetime.Now.Ticks; for(var i=1; i<1000000; i++) { Random random = new Random(seed); int i1 = random.Next(0, 99); int i2 = random.Next(3, 9); seed = random.Next(); ......... } 这样,保证下一次实例化的时候的seed不会重复。当然如果你只是需要一个随机发生器的话(而不是多个),最方便的编程中声明为 private static 的,这已经足矣了。根本没有必要实例化无数个 Random 对象!
var seed = Datetime.Now.Ticks; for(var i=1; i<1000000; i++) { Random random = new Random(seed); int i1 = random.Next(0, 99); int i2 = random.Next(3, 9); seed = random.Next(); ......... }
计算机生成的随机数,不会跟你扔骰子一样,受到各种环境原因影响
一个计算,输入的参数是确定的,输出的值就是确定的了而Random的算法,大体上就是获取时间片并进行一些计算
如果你在循环外部定义,那么生成了第一个数后,第二个数会再把第一个参数传进来进行计算,以保证不会都是同一个数
而如果在循环内部定义,它没有别的参数可以参考,只能取时间片,而循环太快,时间片还没有发生变化,就已经生成了多个Random的实例,这些实例的参数都是同一个,所以生成的随机数也都是同一个
{
} public Random(int Seed)
{
int seedArray = 161803398 - Math.Abs(Seed);
this.SeedArray[55] = seedArray;
int num = 1;
for (int i = 1; i < 55; i++)
{
int num1 = 21 * i % 55;
this.SeedArray[num1] = num;
num = seedArray - num;
if (num < 0)
{
num = num + 2147483647;
}
seedArray = this.SeedArray[num1];
}
for (int j = 1; j < 5; j++)
{
for (int k = 1; k < 56; k++)
{
this.SeedArray[k] = this.SeedArray[k] - this.SeedArray[1 + (k + 30) % 55];
if (this.SeedArray[k] < 0)
{
this.SeedArray[k] = this.SeedArray[k] + 2147483647;
}
}
}
this.inext = 0;
this.inextp = 21;
Seed = 1;
}
当你使用无参数的实例化方法时,它就是用当前时间的 Ticks 数值做为“种子”,因此快速连续调用它,会连续取得相同的结果。如果想连续快速地创建它的对象实例,你就要直接使用第二个——但有一个参数的——实例化方法,并且每一次改变种子值。例如写var seed = Datetime.Now.Ticks;
for(var i=1; i<1000000; i++)
{
Random random = new Random(seed);
int i1 = random.Next(0, 99);
int i2 = random.Next(3, 9);
seed = random.Next();
.........
}
这样,保证下一次实例化的时候的seed不会重复。当然如果你只是需要一个随机发生器的话(而不是多个),最方便的编程中声明为 private static 的,这已经足矣了。根本没有必要实例化无数个 Random 对象!
for(var i=1; i<1000000; i++)
{
Random random = new Random(seed);
int i1 = random.Next(0, 99);
int i2 = random.Next(3, 9);
seed = random.Next();
.........
}