我应该多久在C ++中种植? [英] How often should I reseed in C++?

查看:128
本文介绍了我应该多久在C ++中种植?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想知道是否足够种子的随机数发生器只有一次在程序的开始。我写了使用随机数的函数。我从来没有种子在函数内的rand()生成器,而是在主条目上留下调用srand()。例如。我的程序可能如下所示:

I just wonder if it is enough to seed the random number generator only once at the beginning of a program. I write functions which uses random numbers. I never seed the rand() generator within the function, but rather leave calling srand() on main entry. E.g. my program may look like:

void func1()
{
    std::cout << "This is func1 " << std::rand() << std::endl;
}

void func2()
{
    std::cout << "This is func2 " << std::rand() << std::endl;
}

int main()
{
    std::srand(std::time(NULL));
    func1();
    func2();
    return 0;
}

通过这样做,我可以从主条目中轻松关闭播种。它在调试程序时很有用 - 每次运行程序时结果保持不变,无需播种。有时候,如果由于一些随机数发生问题,它可能会消失,如果要生成一组不同的随机数,所以我宁愿这样一个简单的机制关闭种子。

By doing so, I can easily switch off seeding from the main entry. It comes useful when debugging a program - the results are kept the same every time I run the program without seeding. Sometimes, if a problem occurs due to some random number, it may just disappear if a different set of random numbers is to be generated, so I'd prefer such a simple mechanism to switch off seeding.

但是,我注意到在C ++ 11的新的随机实用程序集,随机数生成器必须在使用前实例化。 (例如default_random_engine)。每次发电机必须单独播种。我想知道是否真的鼓励在需要新发电机时对发电机补种。我知道我可以创建一个全局随机生成器和种子它只有一次像以前一样,但我真的不喜欢使用全局变量的想法。否则,如果我创建一个本地随机数生成器,我就失去了全局关闭播种以进行调试或任何目的的能力。

However, I noticed in C++11's new random utility set, the random number generator has to be instantiated before using. (e.g. default_random_engine). And every time a generator has to be seeded separately. I wonder if it is actually encouraged to reseed the generator whenever a new generator is needed. I know I could create a global random generator and seed it only once as before, but I don't really like the idea of using global variables at all. Otherwise, if I create a local random number generator, I sort of lose the ability to globally switch off seeding for debugging or whatever purpose.

我很高兴学习在C ++ 11中的新功能,但有时它只是很混乱。任何人都可以让我知道,如果我有任何错误的新的随机生成器?或者什么可能是C ++ 11中的最佳实践?

I'm excited to learn the new features in C++11, but sometimes it's just very confusing. Can anyone let me know if I got anything wrong with the new random generators? Or what might be the best practice in C++11?

推荐答案

有一个随机数生成器)需要实例化,以便它可以保持其状态内部,这样在多线程应用程序中,当多个线程使用相同的RNG与进程全局状态时,不引入非确定性。假设你有两个线程,每个线程都处理一个问题的独立部分 - 如果状态(种子)对于RNG实例是私有的,那么当你使用一个已知的值填充每个线程的RNG时,你可以有确定性。另一方面,如果RNG将状态保存在全局变量中,则每个线程观察到的随机数序列取决于它们对RNG的调用 - 您现在已经引入了非确定性。

One of the reasons for having a random number generator (RNG) require instantiation is so that it can keep its state internal, that way in a multi-threaded application you don't introduce non-determinism when multiple threads use the same RNG with process-global state. Suppose you have two threads, each working on independent parts of a problem - if the state (seed) is private to the RNG instance then you can have determinism when you seed each thread's RNG with a known value. On the other hand, if the RNG keeps state in a global variable then the sequence of random numbers observed by each thread depends on the inter-leaving of their calls to the RNG - you've now introduced non-determinism.

用于在多线程应用程序中分配工作的一种编程模式是线程池。如果为要执行的池中的工作线程排队的工作项需要RNG,并且您希望执行从运行到执行都是确定性的,那么您希望每个线程在从一个新工作项

One programming pattern that is used to assign work in multi-threaded applications is a thread pool. If the work items that are queued up for worker threads in the pool to execute require an RNG and you want execution to be deterministic from run to run, then you want each thread to re-seed the RNG after pulling a new work item from the queue


  • 这可以作为工作项初始化的一部分

  • 涉及作业参数的散列函数

  • if你很小心这个是如何编码的,你可以有伪随机
    和确定性,无论工作线程的数量或
    顺序,他们从队列中取出工作。

这里有一个SO问题处理这个问题:确定性随机数生成器绑定到实例(线程独立)

Here's an SO question that deals with this: Deterministic random number generator tied to instance (thread independent)

在单线程应用程序中需要重新种下一个RNG,事实上,这是不可取的,因为这样做,你缩短它的周期,它将开始重复。这是例外,@MatthewSanders指出,加密 - 在这种情况下,你想要最大熵(最小确定性),因为随机数被用作私钥。

In a single-threaded application it is not necessary to re-seed an RNG, and in fact it is undesirable because by doing that you shorten it's cycle before it will start repeating. The exception to this is what @MatthewSanders pointed out, Cryptography - in that case you want maximum entropy (least determinism) because random numbers are used as private keys.

这篇关于我应该多久在C ++中种植?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆