随机种子 如何生成相同的数字序列进行调试

本文关键字:字序 调试 数字 种子 何生成 随机 | 更新日期: 2023-09-27 18:31:30

我正在写一个纸牌游戏,需要从一堆随机抽出牌。我正在使用Random和Random.Next(...)来做到这一点。现在,我想调试我的应用程序,并希望能够使用相同的随机序列重现某些方案。谁能帮忙...?在几次搜索中,我都找不到答案。谢谢。

随机种子 如何生成相同的数字序列进行调试

使用接受种子值的 Random 构造函数的重载

static Random r = new Random(0);

这将在每次执行中生成相同的伪随机数序列。

您需要为随机数生成器播种。假设您使用的是System.Random,请使用

Random r = new Random(<some integer>);

<some integer> 开始序列。

但这里有一个重要的注意事项:您需要仔细研究您的随机数生成器。 否则,就有可能破译您的序列,这将使精明的用户无意中从中获利。我怀疑一旦你进入生产环境,你是否会使用Random(从技术上讲,可以在三个多一点的图形中破译线性同余序列 - 这是 C# 使用的。

使用相同的种子创建一个System.Random实例:

Random random = new System.Random(1337);

在随机构造函数中使用相同的种子。这保证了 Next() 将给出相同的结果。例如

Random randomGen1 = new Random(5);
Random randomGen2 = new Random(5);
int r1 = randomGen1.Next();
int r2 = ramdomGen2.Next();
if(r1 == r2)
{
 Console.WriteLine("Great success!!");
}

对于这种情况来说可能有点矫枉过正(使用种子会给你可重复性),但处理你没有完全控制的依赖关系的一个很好的方法是包装依赖关系并通过接口访问它。 这将允许您交换为单元测试/调试提供指定行为的版本。

例如

public interface IRandom {
    int Get();
}
public class DefaultRandom : IRandom {
    private readonly Random random;
    public DefaultRandom() {
        random = new Random();
    }
    public int Get() {
        return random.Next();
    }
}
public class TestRandom : IRandom {
    private readonly List<int> numbers;
    private int top;
    public TestRandom() {
        numbers = new List<int> {1, 1, 2, 3, 5, 8, 13, 21};
        top = 0;
    }
    public int Get() {
        return (top >= numbers.Count)
                ? 0
                : numbers[top++];
    }
}

此方法的一个优点是,您可以使用特定值(例如,测试边缘情况),而使用固定种子值可能难以生成这些值。