c++ 随机数问题的相关研究

时间:2021-05-20

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_MAX

3、c++11 随机数

c++11引入了random头文件,可以更加精确的产生随机数,并且提供了完善的操作接口。C++标准规定了随机数设施,包括均匀随机位生成器(Uniform random bit generators,URBG)和随机数分布等,定义在<random>中。

参考文档:http:///pingwen/p/14496607.html

以上就是c++ 随机数问题的相关研究的详细内容,更多关于c++随机数问题研究的资料请关注其它相关文章!

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章