我很努力地找到一種方法,讓每個線程有一個隨機數生成器,同時確保重新運行程序時生成相同的數字。用已知種子創建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