如何强制Random的所有实例在不同的运行中生成相同的数字序列



我正在编写一个应用程序,用于使用随机生成的输入测试算法。这涉及到分布在代码周围的Random类的几个实例。我需要所有这些实例在不同的运行中生成相同的输入,以便在发现意外结果时调试算法。这是使用Delphi创建的应用程序的行为,除非您手动调用Randomize

我知道我可以:

  • 为所有创建的实例提供常量种子
  • 将使用常量种子创建的唯一实例传递给所有需要随机生成器的方法

我不喜欢使用上述任何方法的原因是,大多数生成随机数据的函数都是在互联网上到处收集的黑盒函数。由于未知的原因,他们中的一些人甚至使用了几个随机生成器。除非迫不得已,否则我宁愿不乱用这些功能。

那么,还有其他方法可以一起控制所有这些实例吗?

下面是一个具有两个静态成员的类的快速示例,其中一个是a"固定RNG";,而另一个只是正常的";RNG";,您可以在代码中的任何地方使用:

int x = MyRandom.RNG.Next(1, 7);
int y = MyRandom.FixedRNG.Next(1, 7);

代码:

public class MyRandom
{
private static Random _fixedRandom = new Random(1234);
private static Random _random = new Random();
public static Random FixedRNG
{
get
{
return _fixedRandom;
}
}
public static Random RNG
{
get
{
return _random;
}
}
}

另一种选择可能是包含一个IsRandom属性,用于确定返回哪个属性:

public class MyRandom
{
private static bool _isRandom = false;
private static Random _fixedRandom = new Random(1234);
private static Random _random = new Random();
public static bool IsRandom
{
get
{
return _isRandom;
}
set
{
_isRandom = value;
}
}
public static Random RNG
{
get
{
if (IsRandom)
return _random;
else
return _fixedRandom;
}
}
}

感谢@Idle_Mind的建议。这里有一个更像Delphi的版本:

public static class GlobalRandom
{
private static int _randSeed = 0;
public static Random RNG { get; private set; } = new Random(_randSeed); // Made accessible for Random extensions
public static void Randomize() { RNG = new Random(); }
public static int RandSeed { get => _randSeed;
set { _randSeed = value; RNG = new Random(_randSeed); } }
public static int Next() => RNG.Next();
public static int Next(int minValue, int maxValue) => RNG.Next(minValue, maxValue);
public static int Next(int maxValue) => RNG.Next(maxValue);
public static void NextBytes(byte[] buffer) => RNG.NextBytes(buffer);
public static double NextDouble() => RNG.NextDouble();
}

像一样使用

Console.WriteLine($"Default seed (0):     {GlobalRandom.Next()}");
GlobalRandom.Randomize();
Console.WriteLine($"Unknown seed:         {GlobalRandom.Next()}");
GlobalRandom.RandSeed = 100;
Console.WriteLine($"Constant seed (100):  {GlobalRandom.Next()}");
GlobalRandom.RandSeed = 0;
Console.WriteLine($"Back to default seed: {GlobalRandom.Next()}");

首次运行:

默认种子(0(:1559595546
未知种子:1837960504
恒定种子(100(:2080427802
返回默认种子:155959556

第二次运行:

默认种子(0(:1559595546
未知种子:54655523
恒定种子(100(:2080427802
返回默认种子:1559595.546

最新更新