设为首页 加入收藏

TOP

C/C++随机数生成方法
2015-02-02 14:43:15 来源: 作者: 【 】 浏览:21
Tags:C/C 随机 生成 方法

一、随机数测试


C++中常用rand()函数生成随机数,但严格意义上来讲生成的只是伪随机数(pseudo-random integral number)。生成随机数时需要我们指定一个种子,如果在程序内循环,那么下一次生成随机数时调用上一次的结果作为种子。但如果分两次执行程序,那么由于种子相同,生成的“随机数”也是相同的。


C语言梳理一下,分布在以下10个章节中:


在工程应用时,我们一般将系统当前时间(Unix时间)作为种子,这样生成的随机数更接近于实际意义上的随机数。给一下例程如下:


#include
#include
#include
using namespace std;



int main()
{
? ? double random(double,double);
? ? srand(unsigned(time(0)));
? ? for(int icnt = 0; icnt != 10; ++icnt)
? ? ? ? cout << "No." << icnt+1 << ": " << int(random(0,10))<< endl;
? ? return 0;
}
double random(double start, double end)
{
? ? return start+(end-start)*rand()/(RAND_MAX + 1.0);
}


/* 运行结果
* No.1: 3
* No.2: 9
* No.3: 0
* No.4: 9
* No.5: 5
* No.6: 6
* No.7: 9
* No.8: 2
* No.9: 9
* No.10: 6
*/


利用这种方法能不能得到完全意义上的随机数呢?似乎9有点多哦?却没有1,4,7?!我们来做一个概率实验,生成1000万个随机数,看0-9这10个数出现的频率是不是大致相同的。


程序如下:


#include
#include
#include
#include
using namespace std;
int main()
{
? ? double random(double,double);
? ? int a[10] = {0};
? ? const int Gen_max = 10000000;
? ? srand(unsigned(time(0)));
? ?
? ? for(int icnt = 0; icnt != Gen_max; ++icnt)
? ? ? ? switch(int(random(0,10)))
? ? ? ? {
? ? ? ? case 0: a[0]++; break;
? ? ? ? case 1: a[1]++; break;
? ? ? ? case 2: a[2]++; break;
? ? ? ? case 3: a[3]++; break;
? ? ? ? case 4: a[4]++; break;
? ? ? ? case 5: a[5]++; break;
? ? ? ? case 6: a[6]++; break;
? ? ? ? case 7: a[7]++; break;
? ? ? ? case 8: a[8]++; break;
? ? ? ? case 9: a[9]++; break;
? ? ? ? default: cerr << "Error!" << endl; exit(-1);
? ? ? ? }
? ?
? ? for(int icnt = 0; icnt != 10; ++icnt)
? ? ? ? cout << icnt << ": " << setw(6) << setiosflags(ios::fixed) << setprecision(2) << double(a[icnt])/Gen_max*100 << "%" << endl;
? ?
? ? return 0;
}
double random(double start, double end)
{
? ? return start+(end-start)*rand()/(RAND_MAX + 1.0);
}


/* 运行结果
* 0: 10.01%
* 1:? 9.99%
* 2:? 9.99%
* 3:? 9.99%
* 4:? 9.98%
* 5: 10.01%
* 6: 10.02%
* 7: 10.01%
* 8: 10.01%
* 9:? 9.99%
*/
可知用这种方法得到的随机数是满足统计规律的。
另:在Linux下利用GCC编译程序,即使我执行了1000000次运算,是否将random函数定义了inline函数似乎对程序没有任何影响,有理由相信,GCC已经为我们做了优化。但是冥冥之中我又记得要做inline优化得加O3才行...
不行,于是我们把循环次数改为10亿次,用time命令查看执行时间:
linuxidc@gentoo ~/workspace/test/Debug $ time ./test
0: 10.00%
1: 10.00%
2: 10.00%
3: 10.00%
4: 10.00%
5: 10.00%
6: 10.00%
7: 10.00%
8: 10.00%
9: 10.00%



real? ? 2m7.768s
user? ? 2m4.405s
sys? ? 0m0.038s
linuxidc@gentoo ~/workspace/test/Debug $ time ./test
0: 10.00%
1: 10.00%
2: 10.00%
3: 10.00%
4: 10.00%
5: 10.00%
6: 10.00%
7: 10.00%
8: 10.00%
9: 10.00%



real? ? 2m7.269s
user? ? 2m4.077s
sys? ? 0m0.025s
前一次为进行inline优化的情形,后一次为没有作inline优化的情形,两次结果相差不大,甚至各项指标后者还要好一些,不知是何缘由...


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇构建Android的交叉编译器、用NDK.. 下一篇C#中Interlocked不能保证的事情

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: