【问题标题】:Get random number in sequence C++获取序列中的随机数 C++
【发布时间】:2013-07-28 07:42:55
【问题描述】:

有没有办法使用随机生成器中内置的 C++ 标准库来获取序列中的特定随机数,而无需全部保存?

喜欢

srand(cTime);
getRand(1); // 10
getRand(2); // 8995
getRand(3); // 65464456
getRand(1); // 10
getRand(2); // 8995
getRand(1); // 10
getRand(3); // 65464456

【问题讨论】:

  • 使用调整,您可以生成特定范围内的随机数,例如,如果您只需要 0-36 的随机数,那么您可以使用 % 运算符轻松实现(如 rand()%36)使用 rand() 函数,但我不知道有任何内置函数,它会将 X 作为 getRand(X) 的输入并每次都生成一些 f(X)。

标签: c++ random generator


【解决方案1】:

C++11 随机数引擎需要实现成员函数 discard(unsigned long long z)(第 26.5.1.4 节),该函数将随机数序列推进 z 步骤。复杂性保证很弱:“不比 z 连续调用 e()" 的复杂性。显然,该成员的存在只是为了尽可能地公开更多高性能实现,如注释 274 所述:

这个操作在用户代码中很常见,经常可以实现 以特定于发动机的方式,以提供显着的性能 对等效的幼稚循环的改进,使z 连续 致电e()

给定discard,您可以通过重新设置生成器、丢弃n-1 值并使用下一个生成的值来轻松实现按顺序检索第n 个数字的要求。

我不知道哪些标准 RNG 引擎(如果有的话)适用于discard 的有效实现。进行一些调查和分析可能值得您花时间。

【讨论】:

    【解决方案2】:

    您必须保存数字。可能还有其他变体,但它仍然需要保存一个数字列表(例如,根据getRand() 的参数使用不同的种子 - 但这对保存它们并没有真正的好处)。

    我会说这样的事情会很好地工作:

    int getRand(int n)
    {
        static std::map<int, int> mrand;
        // Check if it's there. 
        if ((std::map::iterator it = mrand.find(n)) != mrand.end())
        {
            return it->second;
        }
    
        int r = rand();
        mrand[n] = r;
        return r;
    }
    

    (我没有编译这段代码,只是把它写成“这种事情可能会工作”)

    【讨论】:

    • 保存不是一种选择,可能有数百万个数字,具体取决于应用程序运行的时间。
    • 好吧,如果不保存数字,或者每次都使用新的(但相同的)种子,您就不能两次获得相同的数字。请注意,在现代计算机中保存数百万个数字应该不是问题——如今,即使是手机也有数兆字节的内存。 1M 个数字 = ~ 4MB(尽管 map 可能会占用更多空间)。 rand 的全部意义在于每次调用它时都会生成一个不同的数字。当然,您可以每次调用 srand 并使用新的种子,但这需要为每个序列号保存并生成好的种子,这样就更糟了。
    • 那你如何在 Java 中实现这一点?
    【解决方案3】:

    实现getRand() 以始终播种,然后返回给定的数字。但是,这会干扰系统中的所有其他随机数,而且速度会很慢,尤其是对于大型索引。假设一个从 1 开始的索引:

    int getRand(int index)
    {
        srand(999);  // fix the seed
        for (int loop=1; loop<index; ++loop)
            rand();
        return rand();
    }
    

    【讨论】:

    • 我刚刚阅读了另一条评论“可能有数百万个数字,具体取决于应用程序运行的时间” - 虽然这可以满足您的要求,但对于如此大的索引来说并不实用。
    【解决方案4】:

    类似于cdmh的帖子,

    从 C++11 开始也可以使用:

    #include<random>
    
    long getrand(int index)
    {
     std::default_random_engine e;
     for(auto i=1;i<index;i++)
         e();
      return e();
    }
    

    【讨论】:

      【解决方案5】:

      查看: Random123

      来自文档:

      Random123 是一个“基于计数器”的随机数生成器 (CBRNG) 库,其中第 N 个随机数可以通过对 N.. 应用无状态混合函数来获得。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-22
        • 2015-01-27
        • 2022-06-16
        • 2023-03-11
        • 2013-07-06
        • 1970-01-01
        • 2011-11-01
        • 1970-01-01
        相关资源
        最近更新 更多