【问题标题】:random_shuffle not really randomrandom_shuffle 不是真正随机的
【发布时间】:2012-11-07 17:42:48
【问题描述】:

我在这样的向量上使用random_shuffle

#include <algorithm>
vector <Card> deck;
//some code to add cards to the deck here
random_shuffle ( deck.begin(), deck.end() );

运行时,deck的内容是乱码的,但重启程序后,这个乱码的顺序还是保留了。

我错过了什么吗?我怎样才能让它真正随机?

【问题讨论】:

  • 你一定要播种 rand srand.
  • std :: srand(std :: time(NULL))

标签: c++ random srand


【解决方案1】:

您需要先使用srand 为伪随机数生成器播种。

#include <algorithm>
#include <cstdlib>

...

std::srand(std::time(0));

vector <Card> deck;
//some code to add cards to the deck here
random_shuffle ( deck.begin(), deck.end() );

以上链接的注释:

一般来说,伪随机数生成器应该只 在调用 rand() 和程序开始之前播种一次。 不应重复播种或每次您希望重新播种 生成一批新的伪随机数。

【讨论】:

  • @Chin:请注意,您应该在程序启动时为生成器播种一次,以后不要再播种。
  • time(0)和time(NULL)有区别吗?
  • 好点我假设他发布的代码是int main() 的一部分。我包含了链接的摘录..
  • @Chin 在 C++ 中可以通过三种方式编写空指针:使用旧的 NULL(继承自 C)、使用 0(旧的 C++ 方式)和使用新的 C+ +11 关键字nullptr.
  • random_shuffle() 实际上并没有指定使用rand(),因此srand() 可能没有任何影响。如果你想确定,你应该使用 C++11 形式之一,random_shuffle(b, e, RNG)shuffle(b, e, uRNG)
【解决方案2】:

放置线:

srand (time (0));

在你做任何事情之前在你的代码中 else,例如在main()的开头。

否则,将始终使用默认种子 1,从而导致来自 rand() 的相同序列以及任何使用它的序列。

【讨论】:

    【解决方案3】:

    使用当前的 C++(即 C++11),您可以使用 shuffle 算法,该算法可以将伪随机数生成器 (PRNG) 对象(您可以播种)作为第三个参数:

    #include <iostream>
    #include <random>
    #include <algorithm>
    #include <vector>
    #include <string>
    #include <ctime>
    using namespace std;
    
    int main(int argc, char **argv)
    {
      vector<string> v;
      for (int i = 1; i<argc; ++i)
        v.push_back(argv[i]);
      mt19937 g(static_cast<uint32_t>(time(0)));
      shuffle(v.begin(), v.end(), g);
      for (auto &x : v)
        cout << x << ' ';
      cout << '\n';
    }
    

    (GCC 4.8.2需要通过g++ -std=c++11 -Wall -g shuffle.cc -o shuffle编译)

    在上面的示例中,PRNG 以当前系统时间为种子。

    对于 C++11 之前的编译器,您在 STL 中只有 random_shuffle 算法 - 但即便如此,您也可以选择为其指定数字生成器对象/函数。请注意,您不能只将mtl19937 之类的 PRNG 对象插入其中(因为它不提供 operator()(U upper_bound) 成员)。

    因此,您可以像这样提供自己的适配器:

    #include <iostream>
    #include <random>
    #include <algorithm>
    #include <vector>
    #include <string>
    #include <ctime>
    using namespace std;
    
    struct Gen {
      mt19937 g;
      Gen()
       : g(static_cast<uint32_t>(time(0)))
      {
      }
      size_t operator()(size_t n)
      {
        std::uniform_int_distribution<size_t> d(0, n ? n-1 : 0);
        return d(g);
      }
    };
    
    int main(int argc, char **argv)
    {
      vector<string> v;
      for (int i = 1; i<argc; ++i)
        v.push_back(argv[i]);
      random_shuffle(v.begin(), v.end(), Gen());
      for (vector<string>::const_iterator i = v.begin(); i != v.end(); ++i)
        cout << *i << ' ';
      cout << '\n';
    }
    

    【讨论】:

      猜你喜欢
      • 2016-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多