我很努力地找到一种方法,让每个线程有一个随机数生成器,同时确保重新运行程序时生成相同的数字。用已知种子创建ThreadLocal随机生成器
我现在做的是这样的:
class Program {
static void Main(string[] args) {
var seed = 10;
var data = new List<double>();
var dataGenerator = new Random(seed);
for (int i = 0; i < 10000; i++) {
data.Add(dataGenerator.NextDouble());
}
var results = new ConcurrentBag<double>();
Parallel.ForEach(data, (d) => {
var result = Calculate(d, new Random(d.GetHashCode());
results.Add(result);
});
}
static double Calculate(double x, Random random) {
return x * random.NextDouble();
}
}
因为创建了“数据”列表中的randomgenerator提供种子以及基于被提供的种子是在计算中使用的randomgenerators正在处理的数字的哈希码,结果是可重复的。无论线程的数量和实例化的顺序如何。
我想知道是否有可能为每个线程实例化一个随机生成器。下面的代码片段似乎可以实现这一点,但由于随机生成器不再提供(可再生)种子,结果不可重复。
class Program {
static void Main(string[] args) {
var seed = 10;
var data = new List<double>();
var dataGenerator = new Random(seed);
for (int i = 0; i < 10000; i++) {
data.Add(dataGenerator.NextDouble());
}
var results = new ConcurrentBag<double>();
var localRandom = new ThreadLocal<Random>(() => new Random());
Parallel.ForEach(data, (d) => {
var result = Calculate(d, localRandom.Value);
results.Add(result);
});
}
static double Calculate(double x, Random random) {
return x * random.NextDouble();
}
}
任何人都可以想出一个很好的解决这个问题?
我不认为这是可能的。第一种解决方案的工作原理是因为你的随机数生成器与线程数无关。在第二种情况下,当您为每个线程创建一个随机生成器时,即使您找到一致的方式来初始化种子,结果也将取决于线程的数量。也许做一个Random的自定义实现,让你每次生成一个新的数字时都提供一个种子? – 2011-12-14 09:43:31
无赖。我认为每次设置一个新的种子就像每次实例化一个新的随机一样。 – jkokorian 2011-12-14 11:08:21