Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.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/0/azure/12.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++_Random_Srand - Fatal编程技术网

C++ 在哪里初始化通过多个随机模块使用的随机种子?

C++ 在哪里初始化通过多个随机模块使用的随机种子?,c++,random,srand,C++,Random,Srand,所以,每次我开发一些大的东西,多个模块一起构建一个最终的功能,我都在想同样的问题:如果超过一个模块需要使用随机函数,在哪里初始化随机种子 如果我有一个需要随机的类(例如,通过使用自我实现的快速排序对输入数组进行排序来初始化自身的类,因此我需要一个随机的数据透视选择),我通常有一个私有的静态bool isRandOn变量,所以在开始随机轴心选择之前,我检查该变量并执行srand(time(NULL))如果随机设置尚未打开 如果我在一个名称空间中有大量的实用函数,我会做一件非常类似的事情:我将这样一

所以,每次我开发一些大的东西,多个模块一起构建一个最终的功能,我都在想同样的问题:如果超过一个模块需要使用随机函数,在哪里初始化随机种子

如果我有一个需要随机的类(例如,通过使用自我实现的快速排序对输入数组进行排序来初始化自身的类,因此我需要一个随机的数据透视选择),我通常有一个私有的
静态bool isRandOn变量,所以在开始随机轴心选择之前,我检查该变量并执行
srand(time(NULL))如果随机设置尚未打开

如果我在一个名称空间中有大量的实用函数,我会做一件非常类似的事情:我将这样一个变量放在我的utils库中的一个匿名名称空间中,并做与类差不多的事情

我遇到的问题是如何组合这些模块。就其本身而言,我知道每个模块不会设置种子超过一次。但是,我希望能够一起使用我的各种模块,我希望其他人能够独立使用我的一个或多个模块


那么,处理多个随机种子模块的最佳方法是什么?在每个模块中设置种子?根本不要设置种子,而是记录random的用法,如果用户想要使用该模块,请让用户初始化种子?第三件事?

您可以为随机数生成创建一个特殊的“模块”,并从应用程序的其他部分使用它。然后,在初始化随机数模块时,您只需进行一次种子设定。

我建议使用Boost.random,而不是依赖于在程序级别共享的某些全局状态

Boost.Random有两个概念:

  • 引擎:它生成随机数
  • 分布:调整引擎的结果,以提供符合特定分布(正态分布、泊松分布、高斯分布等)的结果
然后,每个模块可能有自己的引擎,或者实际上有几个引擎:没有特定的理由让给定的引擎在同一模块内的几个不同功能之间共享


最后一句话:无论你做什么,都要确保你有一种方法可以确定地设置种子,用于bug复制目的。Bug Repo可能会从拥有多个引擎中受益(隔离部件会有所帮助)。

@penelope给出了正确的答案。在
rand()
后面有一些生成伪随机数序列的复杂算法。这类似于某个函数
rand\u func(prev\u rand)
,它从上一个函数生成下一个伪随机数。这是您第一次调用
srand(time(NULL))
,它将
prev\u rand
设置为,假设
time(NULL)
非常不确定。因此,您可以安全地多次调用
srand()
(设置)


特别的问题是,如果您需要可预测的伪随机序列:例如,
srand(0)
等,但这似乎不是您的情况。

为了避免重复始终相同的初始随机序列,我提供的最佳方法是在调用
random()
函数的每个模块中执行以下操作:

/* Global variable to remember if we already initialized the PRNG */
static bool seed_initialized = false;

/* Helper function to avoid having always the same sequence again and again */
static void
prng_init (unsigned int seed)
{
  if (!seed_initialized)
    {
      srandom (seed);
      seed_initialized = true;
    }
}
并且,每次在函数中使用
random()
时,都会使用以下内容启动函数:

 /* Initializing PRNG with a 'reasonably strong' random seed for our purpose */
 prng_init (time (NULL) - getpid());
这样,您可以确保:

  • 您将至少在第一次通过时初始化PRNG

  • 在模块内,您将不会多次重新初始化随机序列


  • 希望这有帮助

    多次设置种子有什么不对?我不知道,这就是为什么我要问:)如果种子在整个执行过程中被有效地重置了几次,它不会降低整个事情的随机性吗?假设每次都使用时间(NULL),并且没有办法真的预测time()将返回什么,我不知道一个随机变量会比下一个随机得多。我猜我要问的是,你是在代码的中间调用Srand,还是你有多个类,只是在一开始就调用它?如果一开始就有5个调用,然后一直使用同一个seed,那就没什么大不了的了……因为我在多个项目中都想知道这一点,其中有些项目在运行时偶尔调用seed,有些项目只在开始时调用,我想知道所有的最佳实践。只有当a)我是唯一一个使用和开发我的应用程序的人,b)没有其他人会使用我的任何单个模块,c)它不会与来自外部的任何东西混合时,这才有效。我想知道什么是尽可能广泛适用的最佳实践。我知道调试的确定性种子。这是一个很好的建议,但由于我正在寻找一种适用于各种情况的最佳实践,所以对于像Boost这样的外部库何时不允许有任何建议?(或者,如果在团队中开发,至少是团队外的库?@penelope:那么,重新开发相同的概念?mersenne twister通常很容易实现,您可以直接使用结果(类似于
    rand()
    将生成的结果)。Boost中的发行版只是糖衣,它的语法比[89,99]中的整数更有意义。当然,它们没有引入biais(与我的快速演示相反)。