【问题标题】:srand not initializing a new output every time [duplicate]srand 每次都没有初始化一个新的输出[重复]
【发布时间】:2018-01-27 00:18:01
【问题描述】:

我正在创建一个程序,在该程序中我需要在不同的时间输出不同的东西。它是随机的,但总是输出相同的东西,是的,我放入了 srand。

void setcolor()
{
    srand(time(NULL));
    int col = rand() % 4 + 1;
    if (col == 1)
    { cout << "white "; }
    else if (col == 2)
    { cout << "brown "; }
    else if (col == 3)
    { cout << "black "; }
    else if (col == 4)
    { cout << "spotted "; }
}

int main() 
{
    for (int i = 0; i <= 5; ++i)
    {
         setcolor();
    }
} 

【问题讨论】:

  • srand() 应该在程序启动时只调用一次。
  • @alain 为什么我只需要调用一次?
  • 在我链接的问题中有很好而彻底的答案。
  • 简而言之,人们主要期望 rng 的两个属性:1)它产生一个伪随机序列 2)对于相同的种子,你得到相同的数字序列。后者对于能够重现结果很重要

标签: c++


【解决方案1】:

在您的情况下使用time 播种srand(time(NULL)); 可能会导致time 返回的值由于其低精度而在每次迭代中保持相同的情况,因此随机生成从同一位置重新开始。所以你应该在开始循环之前只调用一次。

【讨论】:

  • 即使time 在不同的迭代中总是不同的,从非随机源不断地重新播种 RNG 显然是一个糟糕的主意,从而使这一点落空。
【解决方案2】:

srand 必须被调用一次,而不是在每个循环中。

void setcolor()
{
    int col = rand() % 4 + 1;
    if (col == 1)
    { cout << "white "; }
    else if (col == 2)
    { cout << "brown "; }
    else if (col == 3)
    { cout << "black "; }
    else if (col == 4)
    { cout << "spotted "; }
}

int main() 
{
    srand(time(NULL));
    for (int i = 0; i <= 5; ++i)
    {
         setcolor();
    }
}

之所以这样工作,是因为 srand 初始化了一个由 rand() 函数使用的“全局变量”。

time(null) 返回类似于从 1970 年 1 月 1 日开始经过的秒数。因此,由于“全局变量”的初始化,您使用的是相同值的 5 倍。

但是,在 C++ 中,使用随机值并不是正确的方法。 请改用随机标头 (http://en.cppreference.com/w/cpp/numeric/random) :

#include <iostream>
#include <string>
#include <map>
#include <random>

int main()
{
    std::random_device rd;
    std::map<int, int> hist;
    std::uniform_int_distribution<int> dist(0, 9);
    for (int n = 0; n < 20000; ++n) {
        ++hist[dist(rd)]; // note: demo only: the performance of many 
                          // implementations of random_device degrades sharply
                          // once the entropy pool is exhausted. For practical use
                          // random_device is generally only used to seed 
                          // a PRNG such as mt19937
    }
    for (auto p : hist) {
        std::cout << p.first << " : " << std::string(p.second/100, '*') << '\n';
    }
}

【讨论】:

  • 谢谢,成功了!为什么会发生这种情况?
  • 我添加了一些解释 ;)
猜你喜欢
  • 2011-02-16
  • 1970-01-01
  • 1970-01-01
  • 2012-12-02
  • 1970-01-01
  • 2020-08-08
  • 2021-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多