1、问题背景
某项目中有个复杂的排序,先是各种规则依次排序,最后如果依然并列的话,那就随机位置,名次并列。测试中发现一个诡异现象,并列时随机排序但随机后2个case打印的顺序每次都一样,随机数没有起到任何作用。经过分析发现,随机数种子srand(clock()),本意是希望连续调用这个函数,给多个随机数设置种子,实际上设置的种子相同,最后产生的随机数是伪随机数。那么有没有一种随机数方法可以在较快的循环中,保证随机性呢?
原问题较复杂,给个类似的例子说明具体场景:
void test_random(){ vector<int> vec; vec.resize(100); iota(vec.begin(), vec.end(), 1); vector<int> vec2(vec); srand(clock()); random_shuffle(vec.begin(), vec.end()); srand(clock()); random_shuffle(vec2.begin(), vec2.end()); int cnt = 0; cout << "vec:" << endl; for (auto v : vec) { cout << v << " "; if ((++cnt % 10) == 0) cout << endl; } cout << endl<< endl; cnt = 0; cout << "vec2:" << endl; for (auto v : vec2) { cout << v << " "; if ((++cnt % 10) == 0) cout << endl; }}输出结果为:
2、rand()和srand()
rand()和srand()是c函数,在stdlib.h中定义,rand()能产生0--32767范围的随机数。
如果只使用rand,则每次输出的随机数都是一样的,相当于使用srand(1)作为默认种了。如果给定种了,则能产生不同的随机数,所以time或clock函数就是一个好种子,获取计算机的时间,用秒或毫秒来做随机数种子以产生不同的随机数。但是在某些场景下,会引发下列问题:
问题1:在程序运行较慢或不需要连续产生随机数时,用时钟当做种子没有问题,但要快速产生不同的组数的随机数时,就会出现前面出现的现象,较大概率出现相同的随机数。
问题2:如果希望生成某个范围的随机数,则不好控制,通常会采用取模的方式,而这种方式会破坏随机数的分布概率。
// 0--10 的随机数srand((unsigned int)time(NULL));int r = rand() % 10// 100--200的随机数int min = 100;int max = 200;srand((unsigned int)time(NULL));int r = rand() % (max - min) + min // [0--1.0] 浮点数srand((unsigned int)time(NULL));float r = rand() % RAND_MAX3、c++11 随机数
c++11引入了random头文件,可以更加精确的产生随机数,并且提供了完善的操作接口。C++标准规定了随机数设施,包括均匀随机位生成器(Uniform random bit generators,URBG)和随机数分布等,定义在<random>中。
参考文档:http:///pingwen/p/14496607.html
以上就是c++ 随机数问题的相关研究的详细内容,更多关于c++随机数问题研究的资料请关注其它相关文章!