Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何再现相同状态的随机基算法_C++_Algorithm_C++11_Random - Fatal编程技术网

C++ 如何再现相同状态的随机基算法

C++ 如何再现相同状态的随机基算法,c++,algorithm,c++11,random,C++,Algorithm,C++11,Random,我正在研究包含随机初始状态的算法。因此,每次运行该算法时,它的输出都不是健壮的。当我捕捉到错误的输出并想要调试它以查看问题所在时,这会让我非常头疼,因为当我再次运行它时,由于算法的随机因素,问题可能不会重新产生。我使用C++随机生成器如下:< /P> std::random_device rd; std::mt19937 rnd_generator(rd()); std::uniform_int_distribution<> rnd_distribution(

我正在研究包含随机初始状态的算法。因此,每次运行该算法时,它的输出都不是健壮的。当我捕捉到错误的输出并想要调试它以查看问题所在时,这会让我非常头疼,因为当我再次运行它时,由于算法的随机因素,问题可能不会重新产生。我使用C++随机生成器如下:< /P>
    std::random_device rd;
    std::mt19937 rnd_generator(rd());
    std::uniform_int_distribution<> rnd_distribution(0, data_size - 1);

    auto get_random_index = [&](){
        return rnd_distribution(rnd_generator);
    };
std::随机设备rd;
标准:mt19937 rnd_发生器(rd());
std::统一内部分布rnd分布(0,数据大小-1);
自动获取随机索引=[&](){
返回rnd_分配(rnd_发生器);
};

如何模拟这个函数生成的最后一个随机序列?例如,我可以给它一些静态种子,我可以重新输入它,得到完全相同的随机序列吗?我这样问是因为我认为这是一个常见的问题,所以可能有一些好的、高效的、众所周知的方法。

std::mt19937 rnd_生成器(rd())每次使用不同的随机种子对PRNG进行种子设定。如果您想在测试时使用相同的随机序列,那么您可以只硬编码一个种子,而不是使用
rd()


std::mt19937 rnd_生成器(rd())每次使用不同的随机种子对PRNG进行种子设定。如果您想在测试时使用相同的随机序列,那么您可以只硬编码一个种子,而不是使用
rd()


将调用的结果保存到
rd()
,并在下一个过程中使用该结果初始化
rnd\U生成器

例如:

#include <iostream>
#include <random>


auto main() -> int
{
    using namespace std;

    random_device rd;
    auto seed = rd();

    for (int pass = 0 ; pass < 3 ; ++pass)
    {
        mt19937 rnd_generator(seed);
        uniform_int_distribution<> rnd_distribution(0, 9);

        for (int i = 0 ; i < 5 ; ++i)
        {
            cout << rnd_distribution(rnd_generator) << ", ";
        }
        cout << endl;
    }

    return 0;
}

将调用的结果保存到
rd()
,并在下一个过程中使用该结果初始化
rnd\U生成器

例如:

#include <iostream>
#include <random>


auto main() -> int
{
    using namespace std;

    random_device rd;
    auto seed = rd();

    for (int pass = 0 ; pass < 3 ; ++pass)
    {
        mt19937 rnd_generator(seed);
        uniform_int_distribution<> rnd_distribution(0, 9);

        for (int i = 0 ; i < 5 ; ++i)
        {
            cout << rnd_distribution(rnd_generator) << ", ";
        }
        cout << endl;
    }

    return 0;
}

您可以将RNG引擎打印到
std::ostream
以序列化它,然后从
std::istream
读取它以反序列化它。请注意,由于您使用的是
std::uniform_int_distribution
,因此在使用不同的编译器时不会再现相同的数字序列。

您可以将RNG引擎打印到
std::ostream
以对其进行序列化,然后从
std::istream
读取以对其进行反序列化。请注意,由于您使用的是
std::uniform_int_distribution
,因此在使用不同的编译器时,不会再现相同的数字序列。

std::mt19937
是随机性的来源。使用一致种子(我认为是
uint\u least32\u t
)进行测试是有意义的,但使用
random\u device()
(这是一个提供“random”
uint\u least32\u t
的函数)也可以

问题是你在错误的地方创造了它。设计代码,使有趣的逻辑与随机源分离。调用调用方/类创建者的问题,并使代码可测试

大概是这样的:

    class ThingDooer final
    {
        std::mt19937 _prng;
    public:
        // ThingDooer(uint_least32_t seed);
        // ThingDooer() : ThingDoor(std::_Random_device()) {}; // these two or
        ThingDooer(std::mt19937 prng);
        void DoThing();
    };
<>我在C++中做的第一件事是在<代码> IrANDOM 接口中包装<代码> STD::MT1937 < /Cord>,以便我可以提供精确的指定的模拟实现。当然,这对你来说可能太过分了。尽管如此,在不拖入嘲弄库的情况下,我仍然会展示一个我们可能嘲弄的想法:

    class RandallRandom : public IRandom final
    {
    public:
        RandallRandom();
        int32_t Next() { return 4; }
    };

std::mt19937
是随机性的来源。使用一致种子(我认为是
uint\u least32\u t
)进行测试是有意义的,但使用
random\u device()
(这是一个提供“random”
uint\u least32\u t
的函数)也可以

问题是你在错误的地方创造了它。设计代码,使有趣的逻辑与随机源分离。调用调用方/类创建者的问题,并使代码可测试

大概是这样的:

    class ThingDooer final
    {
        std::mt19937 _prng;
    public:
        // ThingDooer(uint_least32_t seed);
        // ThingDooer() : ThingDoor(std::_Random_device()) {}; // these two or
        ThingDooer(std::mt19937 prng);
        void DoThing();
    };
<>我在C++中做的第一件事是在<代码> IrANDOM 接口中包装<代码> STD::MT1937 < /Cord>,以便我可以提供精确的指定的模拟实现。当然,这对你来说可能太过分了。尽管如此,在不拖入嘲弄库的情况下,我仍然会展示一个我们可能嘲弄的想法:

    class RandallRandom : public IRandom final
    {
    public:
        RandallRandom();
        int32_t Next() { return 4; }
    };

那么,不要使用
随机\u设备
。使用固定种子为
mt19937
播种。您没有正确播种MT。您至少需要使用
std::seed\u seq
。4个字节不足以种子MT的巨大内部状态。请不要使用
随机\u设备
。使用固定种子为
mt19937
播种。您没有正确播种MT。您至少需要使用
std::seed\u seq
。4字节不足以为MT巨大的内部状态设置种子。谢谢,这个解决方案的问题是,如果我在同一个种子上测试所有样本,一些问题可能根本不会发生。特别是,当样本集很小时,OP可能至少应该使用
std::seed_seq
;即便如此,这也是次优的。MT有一个巨大的内部状态。然而,它可能是唯一的解决方案,所以我必须将它设置为静态,然后多次更改它,并在每一次测试中测试它们time@HumamHelfawi您可以使用不同的硬编码种子运行测试,以确保捕获不同的种子cases@NathanOliver是的,那是汉克斯,这个解决方案的问题是,如果我在同一个种子上测试所有样本,一些问题可能根本不会发生。特别是,当样本集很小时,OP可能至少应该使用
std::seed_seq
;即便如此,这也是次优的。MT有一个巨大的内部状态。然而,它可能是唯一的解决方案,所以我必须将它设置为静态,然后多次更改它,并在每一次测试中测试它们time@HumamHelfawi您可以使用不同的硬编码种子运行测试,以确保捕获不同的种子cases@NathanOliver是的