[英]random_shuffle not really random
我在这样的向量上使用random_shuffle
:
#include <algorithm>
vector <Card> deck;
//some code to add cards to the deck here
random_shuffle ( deck.begin(), deck.end() );
运行时,卡组的内容会混淆,但重新启动程序时会保留此混合顺序。
我错过了什么? 我怎样才能让它真正随意?
您需要首先使用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()的调用和程序的开始之前播种一次。 每次您希望生成一批新的伪随机数时,不应重复播种或重新播种。
使用当前的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';
}
放线:
srand (time (0));
在您执行任何其他操作之前的代码中,例如在main()
的开头。
如果没有这个,将始终使用默认种子1,从而导致rand()
和使用它的任何东西的相同序列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.