关于c#:如何播种随机类以避免获得重复的随机值

How do I seed a random class to avoid getting duplicate random values

本问题已经有最佳答案,请猛点这里访问。

我在静态类的静态方法中有以下代码:

1
2
Random r = new Random();
int randomNumber = r.Next(1,100);

我把这个放在一个循环里,我一直得到相同的randomNumber

有什么建议吗?


对我来说,一个好的种子世代是:

1
Random rand = new Random(Guid.NewGuid().GetHashCode());

这是非常随机的。种子总是不同的,因为种子也是随机生成的。


不应在循环中创建新的Random实例。尝试以下方法:

1
2
3
var rnd = new Random();
for(int i = 0; i < 100; ++i)
   Console.WriteLine(rnd.Next(1, 100));

单个Random实例生成的随机数序列应该是均匀分布的。通过为快速连续的每个随机数创建一个新的Random实例,您很可能会用相同的值对它们进行种子设定,并使它们生成相同的随机数。当然,在这种情况下,生成的序列将远离均匀分布。

为了完整起见,如果您确实需要重设一个Random,您将使用新种子创建一个新的Random实例:

1
rnd = new Random(newSeed);


位延迟,但系统使用的实现。random是Environment.TickCount

1
2
3
public Random()
  : this(Environment.TickCount) {
}

这就避免了长时间的强制执行DateTime.UtcNow.Ticks,这无论如何都是有风险的,因为它不代表系统启动后的计时周期,而是"自2001年1月1日午夜12:00:00(0:00:00 UTC,在公历中为0001年1月1日)以来的100纳秒间隔数"。

正在为种皮的StringFactory.GenerateRandomString寻找一个好的整数种子。


如果由于某种原因您不能一次又一次地使用同一个Random,请尝试用一些随时变化的东西初始化它,比如时间本身。

1
new Random(new System.DateTime().Millisecond).Next();

不过,记住这是一种不好的做法。

编辑:默认的构造函数已经从时钟中获取了它的种子,可能比我们更好。从msdn引用:

Random() : Initializes a new instance of the Random class, using a time-dependent default seed value.

下面的代码可能是您的最佳选择:

1
new Random().Next();


这对我很有用:

1
2
3
4
5
private int GetaRandom()
    {
        Thread.Sleep(1);
        return new Random(DateTime.Now.Millisecond).Next();
    }


1
public static Random rand = new Random(); // this happens once, and will be great at preventing duplicates

注意,这不用于加密目的。


一个好的种子初始化可以这样做

1
Random rnd = new Random((int)DateTime.Now.Ticks);

勾号将是唯一的,转换成一个可能有零值的int就可以了。


我在大多数情况下都使用这个,如果需要重复序列,就保留种子。

1
2
    var seed = (int) DateTime.Now.Ticks;
    var random = new Random(seed);

1
    var random = new Random((int)DateTime.Now.Ticks);