如何从C++ rand()获取当前种子?

use*_*629 19 c++ random get seed

我基于C++ rand()函数在我的程序中生成了几千个对象.将它们保存在记忆中将是详尽无遗的.有没有办法在任何给定时间复制rand()的CURRENT种子?这将使我有机会只存储当前种子而不是完整对象.(因此我可以通过重新生成完全相同的随机数子序列来重新生成这些对象)

一个详尽的解决方案是存储由rand()给出的完整随机数序列- 不值得.另一种解决方案是实现我自己的类的随机数字.

谷歌没有给我任何积极的线索.有数百篇文章教授rand和srand的基础知识,我找不到具体的文章.

有没有人知道实施种子窃取器的其他随机数发生器?


谢谢你的快速答案!这个问题有更多可能的答案/解决方案,所以我在这里列出了你的答案.

解决方案:

  1. 简短的回答是:没有标准的方法来获得种子

  2. 最接近的解决方法是将INITIAL种子保存在开头,并计算调用rand()函数的次数.我将其标记为解决方案,因为它适用于每个编译器的当前std :: rand()函数(这是关于的主要问题).我已经对我的2.0 GHz CPU进行了基准测试,发现我可以在35秒内调用&计数rand() 1,000,000,000次.这可能听起来不错,但我有80,000个调用来生成一个对象.由于unsigned long的大小,这将生成的数量限制为50,000.无论如何,这是我的代码:

    class rand2
    {
       unsigned long n;
    
       public:
    
       rand2 () : n(0) {}
    
       unsigned long rnd()
       {
          n++;
          return rand();
       }
       // get number of rand() calls inside this object
       unsigned long getno ()
       {
          return n;
       }
       // fast forward to a saved position called rec
       void fast_forward (unsigned long rec)
       {
          while (n < rec) rnd();
       }
    };
    
    Run Code Online (Sandbox Code Playgroud)
  3. 另一种方法是实现自己的伪随机数生成器,就像Matteo Italia建议的那样.这是最快,也可能是最佳解决方案.您不仅限于4,294,967,295次rand()调用,也不需要使用其他库.值得一提的是,不同的编译器有不同的生成器.我将Matteo的LCG与Mingw/GCC 3.4.2和G ++ 4.3.2中的rand()进行了比较.其中所有3个都不同(种子= 0).

  4. 使用来自C++ 11或其他库的生成器,如Cubbi,Jerry Coffin和Mike Seymour建议的那样.如果您已经与他们合作,这是最好的主意.C++ 11生成器的链接:http://en.cppreference.com/w/cpp/numeric/random (这里也有一些算法描述)

Cub*_*bbi 13

有没有人知道实施种子窃取器的其他随机数发生器

所有标准C++ 11随机数生成器(也可在TR1和Boost中使用)都提供此功能.您只需复制生成器对象或序列化/反序列化它们即可.


Mat*_*lia 8

没有标准的方法来获取当前种子(你只能通过它设置srand),但你可以在几行代码中自己重新实现rand()(通常是一个线性同余生成器):

class LCG
{
private:
    unsigned long next = 1;
public:

    LCG(unsigned long seed) : next(seed) {}

    const unsigned long rand_max = 32767

    int rand()
    {
        next = next * 1103515245 + 12345;
        return (unsigned int)(next/65536) % 32768;
    }

    void reseed(unsigned long seed)
    {
        next = seed;
    }

    unsigned long getseed()
    {
        return next;
    }
};
Run Code Online (Sandbox Code Playgroud)


Col*_*n D 5

使用srand()设置种子.保存您用作种子的值.

http://cplusplus.com/reference/clibrary/cstdlib/srand/

  • 如果您想重新创建整个序列,那就没问题了,但如果您想在任何给定时间提取种子,则不行. (7认同)

Jer*_*fin 5

C++ 11中的随机数生成类支持operator<<存储它们的状态(主要是种子)并将operator>>其读回.因此,基本上,在创建对象之前,保存状态,然后在需要重新生成时序列,读回状态,然后离开.