您的位置:首页 > 编程语言 > C语言/C++

概率算法 预备知识 用rand()和srand()产生伪随机数的方法总结

2012-09-17 14:53 281 查看
用rand()和srand()产生伪随机数的方法总结

---------------------------------

标准库<cstdlib>(被包含于<iostream>中)提供两个帮助生成伪随机数的函数:

函数一:int rand(void);返回[0,RAND_MAX(0x7fff) ] 的随机数。注意RAND_MAX=32767,生成的随机数包含32767.

函数二:void srand(unsigned seed);参数seed是rand()的种子,用来初始化rand()的起始值。默认为srand(1),一般用 srand( unsignd long (time(0));来初始化种子。

例子1. 生成[0,n) 之间的随机整数,n <= RAND_MAX.

法① (unsigned long) (( rand() / (double)RAND_MAX ) * n);//将 [0,RAND_MAX)映射到[0,n)上面 ,最后的long long 转换,会使(n-1).*** 后的小数点舍去,既不会产生返回n的随机数 

法②rand() % n 。 实验表明这两种方法在当随机次数足够大时,生成的随机数分布类似。不过感觉第②中好些。

例子2. 生成[0,n)之间的随机整数,n>RAND_MAX

用到了移位操作。

  unsigned long randNum=0;

        randNum = (unsigned long) rand();

         randNum = randNum<<15;   //关键,左移15位

  randNum |= (unsigned long) rand();
        randNum = randNum % n;     

例子3. 生成[a,b)之间的随机整数。

        先生成一个[0,b-a)之间的随机整数r,然后r+a,就可以得到结果.

        if( b-a <= RAND_MAX) 

(rand()%(b-a)) +a.

例子4. 生成一个[0,1)之间的实数

rand()/(double)(RAND_MAX); 

例子5. 生成一个[a,b)之间的实数

        (rand()%(double)RAND_MAX )*(b-a)+a。

       a为0.0的情况下,简写为(rand()%(double)RAND_MAX )*b。

代码实例:

/*
* Abstract:随机生成函数, 重点的Random一个大于RAND_MAX=32767的数。
*   最后还通过实验,输出了生成0~N(N>32767) 随机数的分布情况
*
* Author: Ace.Ma
* Date:2012/9/17
* Version:0.1
*/
#include<iostream>
#include<ctime>
#include<map>
using namespace std;

//产生[0,n)之间的随机整数, n必须大约0 且 小于long long 表示范围
//注意算法还不能有生成 n 整数的概率
unsigned long Random (unsigned long n)
{
unsigned long randNum=0;
if ( n < RAND_MAX )
{
//将 [0,RAND_MAX)映射到[0,n)上面 ,最后的long long 转换,会使(n-1).*** 后的小数点舍去,既不会产生返回n的随机数
randNum = (unsigned long) (( rand() / (double)RAND_MAX ) * n);
}
else
{
randNum = (unsigned long) rand();
randNum = randNum<<15;
randNum |= (unsigned long) rand();
randNum = randNum % n;
}
return randNum;

}
//产生[0,n)之间的随机整数, n必须大于0小于RAND_MAX
long long RandomShort (unsigned long n)
{
//srand((unsigned long)time(0)); //注意在这里,如果有这个语句,若两次调用此函数的间隔小于1秒,产生序列一样
if ( n < RAND_MAX && n > 0 )
{
//将 [0,RAND_MAX)映射到[0,n)上面 ,最后的long long 转换,会使(n-1).*** 后的小数点舍去,既不会产生返回n的随机数
return (long long) ( rand() / (double)RAND_MAX ) * n;
}
else
{
cout<<"out of rang"<<endl;
return 0;
}
}
//产生[0,1)之间的随机实数
double fRandom(void)
{
return rand()/(double)(RAND_MAX);
}

int main()
{
const unsigned long N = 50000;
const unsigned long totalCount=10000000;
map<unsigned long,unsigned int> randCount;
srand( (unsigned long)time(0));
unsigned long num = 0;

for ( unsigned long i=0; i < totalCount; ++i)
{
num = Random(N);
++randCount[num];
}

for( unsigned long i=0;i < N; i += 1000)
{
for( unsigned long j=0; j < randCount[i]; ++j)
{
if( j % 10 == 0)
cout<<"*";
}
cout<<"   "<<i<<endl;
}
system("pause");
return 0;
}


注本文参考博客:http://blog.sina.com.cn/s/blog_4826f7970100076h.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息