【问题标题】:Rand() returns same or very similar output values [duplicate]Rand() 返回相同或非常相似的输出值 [重复]
【发布时间】:2013-12-21 08:44:49
【问题描述】:

这里的 C++ 问题,使用 Code::Blocks。 我正在尝试运行此代码来测试伪随机函数

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
    int count = 0;
    while (count < 10){
        srand(time(NULL));
        cout << rand() << ' ';
        cout << (time( NULL )) << " \n";
        count++;
    }
    return 0;
}

由此产生的输出是 10 条相等的行。这不是真正的问题,因为这里的种子是一样的,所以结果应该是一样的。问题是,如果我再次运行这个程序,它会给出 10 条非常相似的行,不仅在 time() 输出上,而且在 rand 输出上也几乎没有变化。

srand(time(NULL)) 给出的答案非常相似,返回值基本相同,只是稍大一些。

(第一次运行返回 9631,第二次返回 9656)。

我的问题是,这是预期的行为吗?我怎样才能得到更多不同的结果,比如第一次运行 38,第二次运行 671?

【问题讨论】:

  • 你能说得更准确点吗?你期望看到什么?你看到了什么?这怎么不符合您的期望?

标签: c++ random time seed srand


【解决方案1】:

这里有很多误解......两个time(NULL) 彼此接近的调用之间的差异很小,这是意料之中的。毕竟,时间流逝的如此之快。下一个问题是rand() 返回一个(伪)随机值(质量不同):在这种情况下,随机意味着您可能会重复多次获得33,只要它不可预测。话虽如此,rand() 是依赖于实现的,很可能是您的实现使用了类似 LCG 的东西,它不会生成良好的均匀随机值。唯一的解决方法是切换到不同的 rng。由于这被标记为 C++,您可能需要查看 C++11s 随机标头并使用类似于他们的 mersenne twister 实现的东西,这是一个很好的伪随机数生成器,可以生成高质量和均匀分布的随机数。

【讨论】:

  • 这一切我都知道。我要说的是,一旦我知道我第一次运行程序时得到的值,我可以预期如果我关闭它并再次运行它会得到什么值。我什至可以计算该数字达到某个点需要多长时间,然后我总能预测我会从中得到的数字。它没有给我任何随机的东西。甚至没有任何伪随机。如果我只是打印“Time(null)”,结果将是相同的:一个总是以一定速度增长的数字。
【解决方案2】:

不同执行之间的差异可能是time 中的微小变化差异。 rand 的结果对于不同的 C 运行时可能不同,但这里是 Visual Studio 10 中 rand 的实现。

int __cdecl rand ()
{
    _ptiddata ptd = _getptd();

    return( ((ptd->_holdrand = ptd->_holdrand * 214013L
        + 2531011L) >> 16) & 0x7fff );
}

holdrand 存储要开始的种子的位置。这是一个linear congruential generator,通常不会产生高质量的随机性。每次它也会丢弃很多状态,这无济于事。

【讨论】:

  • 所以基本上,这意味着 rand 的工作方式实际上是一个线性且可预测的函数?好吧,那么我想让它看起来像返回随机值的唯一方法是,如果我限制我可以从中获得的最大值。就像使用 rand(time(0))%10 或 % 单个数字一样。我试图获得的结果越大,结果就越相似和可预测。
【解决方案3】:

要生成具有几乎相同种子(时间)的随机数,您可以添加一个静态变量以使rand() 即使使用相同的参数也表现不同;或者,您可以在同一时间更改参数。例如:

int t=0;
...
rand(t=(t*7)^time(NULL));

【讨论】:

  • 这实际上是一个很好的解决方案!我这样做了,我可以同时获得 100 个不同的解决方案(通过运行这个程序一次,while 计数上升到 100)。再次运行它,似乎解决方案的可预测性也非常非常低。我唯一需要补充的是,我需要更改的函数调用是 srand,而不是 rand。但我明白你的意思。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
  • 2014-07-23
  • 1970-01-01
相关资源
最近更新 更多