gpt4 book ai didi

C# Seeding StaticRandom in parallel.for 以获得可重现的序列

转载 作者:行者123 更新时间:2023-11-30 13:58:49 24 4
gpt4 key购买 nike

我正在开发一个 C# 项目,该项目需要在 parallel.for 循环中使用随机数。为此,我使用了 Jon Skeet 的 MiscUtil 中的 StaticRandom 类。

对于测试,我希望能够重现我的结果。因此,我尝试在每次测试运行时为底层 System.Random 设置种子以获得相同的序列。然而,即使有了种子,我每次都会得到不同的结果。在常规的 for 循环中,每次都输出相同的序列。下面有代码可以重现我的问题(您必须使用机器的输出更新预期序列)。

有没有办法为 Random 播种,以便我可以在 parallel.for 循环中获得可重现的序列?

    [TestMethod]
public void MultiThreadedSeededRandom()
{
var actual = new ConcurrentBag<int>();
Parallel.For(0, 10, i =>
{
actual.Add(StaticRandom.Next(1000));
});

WriteActualToOutput(actual);

var expected = new int[] { 743, 51, 847, 682, 368, 959, 245, 849, 192, 440, };

Assert.IsTrue(AreEqual(expected, actual.ToArray()));
}

public static bool AreEqual<T>(T[] expected, T[] actual)
{
if (expected.Length != actual.Length)
return false;

for (int i = 0; i < expected.Length; i++)
{
if (!expected[i].Equals(actual[i]))
return false;
}
return true;
}

private static void WriteActualToOutput(ConcurrentBag<int> acual)
{
var result = string.Empty;
result += "new int[] {";
foreach (var value in acual)
{
result += value.ToString() + ",";
}
result += "};";

Trace.WriteLine(result);
}

public static class StaticRandom
{
private static Random random = new Random(1231241);
private static object myLock = new object();

public static int Next(int max)
{
object obj;
Monitor.Enter(obj = StaticRandom.myLock);
int result;
try
{
result = StaticRandom.random.Next(max);
}
finally
{
Monitor.Exit(obj);
}
return result;
}
}

最佳答案

当您使用 Parallel.For 时,根据设计,您将获得乱序的结果,因为每次迭代都将以不确定的方式并行运行。如果您需要具有相同序列的“随机”数字,则需要以可靠的顺序调用 Random.Next()。这不适用于多个线程。

与其尝试使用 Parallel.For 来填充随机数,不如考虑提前生成“随机”数序列,然后使用 Parallel.For事后根据这些数字进行处理。这样,您将始终以正确的顺序生成数字,这将保留顺序。

关于C# Seeding StaticRandom in parallel.for 以获得可重现的序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15209137/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com