【问题标题】:Why does my random function generate the same number every time I call it in a loop?为什么我的随机函数每次循环调用时都会生成相同的数字?
【发布时间】:2022-01-25 23:53:15
【问题描述】:

我的随机函数在该范围内生成一个伪随机数:

double Utils::randomNumber(int min, int max)
{
    assert(min < max);
    srand(time(nullptr));
    return (max - min) * ((double)rand() / RAND_MAX) + min;
}

但是,当我在循环中调用它时,我总是得到相同的数字,尽管我为序列设定种子:

for (int i = 0; i < m_inputs; ++i)
{
    m_weights.push_back(Utils::randomNumber(0, 1));
}

输出:

Weights: [0.787561, 0.787561, 0.787561, 0.787561, 0.787561, 0.787561, 0.787561, 0.787561, 0.787561, 0.787561, 0.787561, 0.787561]

【问题讨论】:

  • srand(time(nullptr)); 应该在进程的生命周期内调用一次;不是功能。它不属于你拥有它的地方。坦率地说,无论如何你都应该使用&lt;random&gt; 的产品。
  • @WhozCraig,好吧,但是有没有一种优雅的方法可以做到这一点,因为我正在编写一个库,所以我需要这个函数。
  • 您每次都从头开始播种随机数生成器,并且由于循环很紧time(nullptr) 在迭代之间不会发生变化,因此您最终会得到相同的数字。
  • @CuriousPanCake 你需要一个静态变量。
  • 不知道你为什么要公开它。对于所有意图,您似乎想要std::uniform_real_distribution 已经提供的东西。

标签: c++ random random-seed


【解决方案1】:

在时间紧迫的情况下重复播种将在每次播种后产生相同的初始结果。如果由于调用方位置而不能选择每个进程播种一次,则应改为提供初始静态状态。 可能对你有用的是:

#include <random>

double Utils::randomNumber(int min, int max)
{
    static std::mt19937 rng{ std::random_device{}() };
    std::uniform_real_distribution<double> dist(min, max);
    return dist(rng);
}

请注意,统一实际范围的潜在上限存在一个内在问题,它可能适用于您的使用(不太可能,但永远不要说永远)。有关详细信息,请参阅注释 here

【讨论】:

  • 这个真的很有帮助。我会进入主题以了解更多,谢谢!
  • @CuriousPanCake 很高兴它有帮助。相信我,与srandrand 的传统石器时代机制相比,您了解和使用&lt;random&gt; 中的产品越多,您就会越喜欢它。
  • 最初,有一个想法是只使用自制函数编写一个库(是的,我知道大多数人对这种方法的看法),这就是为什么我想实现自己的随机函数也。不幸的是,它的效果并不好。以前,有一些情况我倾向于重新发明“已经写好的轮子”,但是,我真的很喜欢。
【解决方案2】:

我假设你是从另一个函数 main 或 else 调用 randomNumber 函数。

如果你在函数内声明种子,你将重置函数。 重置该功能会使相同的数字出现多次,同一秒。

srand(time(nullptr)); 移至主函数应该可以解决问题。

【讨论】:

  • 我在对象的构造函数中有randomNumber,我真的不知道要创建多少个对象。
  • @CuriousPanCake 没关系。 srand 应该被调用一次
  • 如果你偶然发现srand 需要被多次调用的情况,那么rand 无法产生足够高质量的序列的可能性非常高。您的需求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-08
  • 2016-03-29
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多