C# Random.Next suddenly stops returning random values
Possible Duplicate:
System.Random keeps on returning the same value
我正在重构和扩展一个基于代理的小型模型,以帮助一些生物学教授预测疾病的传播。在每年的模拟中,每一个单独的药剂都随机地移动到附近的人口节点,可能传播疾病。我对C是全新的,但我已经读过随机的潜在问题。接下来,如果用相同的系统时间重新初始化,则返回相同的值。为了避免这种情况,我创建了一个静态实例,它被每个新的随机值引用。
具体情况:
在我扩大模型的努力中,我改变了它,以并行计算每个人口节点的"旅行"信息。在测试这个模型时,我注意到在新版本中,疾病不会在第一年后传播。进一步的调查将问题缩小到节点之间的行程。第一年之后,所有的特工都不动了。我检查了负责它们运行的函数,发现它是通过创建一个所有附近节点的列表,生成一个随机数<=列表中元素的数量,并运行到ListofNearByNodes[MyrandomNumber]来工作的。
问题:
然后我添加了一个print语句来输出每个迭代的随机索引的值。我发现整个模型在模拟的第一年中完全按照预期工作,随机数在一个可接受的范围内生成。但是,在第一年结束并且模拟循环之后,完全相同的代码将只返回0的"随机"索引。每个线程,每个迭代,每个节点,每个代理,总是0。由于代理的当前节点始终是列表中的第一个项目,因此代理不会再次移动。
我认为这可能是系统时间种子错误的另一种表现形式,所以我尝试了三种不同的方法来实现静态随机对象,但没有帮助。每次我运行模拟时,第一年总是正确运行,然后随机运行。next()开始只返回0。
有人知道我下一步应该在哪里寻找这个bug吗?谢谢!
我怀疑您在多个线程中同时使用同一个
选项:
- 为每个线程创建一个新的
Random 实例(ThreadStatic 在这里有帮助) - 使用EDOCX1的单个实例(0),但只能在锁中使用它。
我有一篇博客文章,上面有一些示例代码,但是请阅读评论,并有一些改进的好建议。我打算在不久的将来写另一篇关于随机性的文章…
我不相信随机类被设计成线程安全的(同时可从多个线程使用)-因此,如果您以这种方式共享一个实例,您可能会损坏随机生成器的状态,从而阻止它正确运行。
您可以将保存对随机类引用的静态变量修饰为
1 2 3 4 5 6 7 8 | [ThreadStatic] private static Random m_Random; // don't attempt to initialize this here... public void YourThreadStartMethod() { // initialize each random instance as each thread starts... m_Random = new Random(); } |
如果您使用的是.NET 4.0,那么还有
1 2 3 4 5 6 7 8 9 10 11 12 | class ThreadSafeRandom { private static Random random = new Random(); public static int Next() { lock (random) { return random.Next(); } } } |
您还可以使用
我认为您应该使用RNGCryptoServiceProvider
http://msdn.microsoft.com/en-us/library/system.security.cryptography.rngcryptoserviceprovider.aspx