我是靠谱客的博主 幸福导师,最近开发中收集的这篇文章主要介绍C++生成随机数—生成任意范围内的等概率随机数方法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

原文:

http://www.pc6.com/infoview/Article_50245.html

http://www.cnblogs.com/afarmer/archive/2011/05/01/2033715.html

http://www.verydemo.com/demo_c92_i78997.html

 

 

rand()函数返回0到RAND_MAX之间的伪随机数(pseudorandom)。RAND_MAX常量被定义在stdlib.h头文件中。其值等于32767,或者更大。 

srand()函数使用自变量n作为种子,用来初始化随机数产生器。只要把相同的种子传入srand(),然后调用rand()时,就会产生相同的随机数序列。因此,我们可以把时间作为srand()函数的种子,就可以避免重复的发生。如果,调用rand()之前没有先调用srand(),就和事先调用srand(1)所产生的结果一样。

 

 

产生随机数的用法 
1) 给srand()提供一个种子,它是一个unsigned int类型; 
2) 调用rand(),它会根据提供给srand()的种子值返回一个随机数(在0到RAND_MAX之间); 
3) 根据需要多次调用rand(),从而不间断地得到新的随机数; 
4) 无论什么时候,都可以给srand()提供一个新的种子,从而进一步“随机化”rand()的输出结果。

 

0~RAND_MAX之间的随机数程序

 

#include <iostream> 
#include <stdlib.h> 
#include <time.h>  
using namespace std;  
int main() 
{  
srand((unsigned)time(NULL));  
for(int i = 0; i < 10;i++ )  
        cout << rand() << 't';  
cout << endl;  
return 0; 
}

 

 

产生一定范围随机数的通用表示公式 
要取得[a,b)的随机整数,使用(rand() % (b-a))+ a; 
要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a; 
要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1; 
通用公式:a + rand() % n;其中的a是起始值,n是整数的范围。 
要取得a到b之间的随机整数,另一种表示:a + (int)b * rand() / (RAND_MAX + 1)。 
要取得0~1之间的浮点数,可以使用rand() / double(RAND_MAX)。 

 

BUT

————————————————————————————————————————————————

假如你想用C++来生成0——N-1之间的随机数,你会怎么做?你可能会说,很简单,看:

srand( (unsigned)time( NULL ) );
rand() % N;

仔细想一下,这个结果是随机的吗(当然,我们不考虑rand()函数的伪随机性)?

不是的,因为rand()的上限是RAND_MAX,而一般情况下,RAND_MAX并不是N的整数倍,那么如果RAND_MAX % = r,则0——r之间的数值的概率就要大一些,而r+1——N-1之间的数值的概率就要小一些。还有,如果N > RAND_MAX,那该怎么办?

一种非常简单的方式,那就是使用

random_shuffle( RandomAccessIterator _First, RandomAccessIterator _Last ).

例如,生成0——N-1之间的随机数,可以这么写

#include 
#include

long myrandom( long N )
{
      std::vector vl( N ); // 定义一个大小为N的vector
       for ( long i=0; i
       {
               vl[i] = i;
       }

       std::random_shuffle( vl.begin(), vl.end() );

       return (*vl.begin());
}

random_shuffle 还有一个三参数的重载版本

random_shuffle( RandomAccessIterator _First, RandomAccessIterator _Last, RandomNumberGenerator& _Rand )

第三个参数可以接受一个自定义的随机数生成器来把前两个参数之间的元素随机化。

这个方法的缺陷就是,如果只是需要一个随机数的话,当N很大时,空间消耗很大!

 
 
——————————————————————————————————————
 
 

------解决方案--------------------------------------------------------
取10到20间的随机数应该这样写
a[i]= 10+ (rand()% 11);

一般的如果你希望取得 a到b之间(b>a,包含a和b)的随机数,
可这样写:
 a[i]= a + (rand()% (b-a+1)); 
------解决方案--------------------------------------------------------
假如0..9共10个元素随机划分为0..2共3块:
第0块,从0..10-3随机选出比如5,即0..5归第0块
第1块,从5+1..10-2随机选出比如7,即6,7归第1块
第2块,从7+1..10-1,即8,9归第2块。

 

现在有一个问题是,如果 N 大于RAND_MAX,应该怎么处理?

这里N=135534747, 需要划分为10个片段,应该怎么随机划分?

 https://www.zhihu.com/question/24297923

使用C++11 最好的解决方案。

 

 

 

 

 

转载于:https://www.cnblogs.com/xingzifei/p/6635340.html

最后

以上就是幸福导师为你收集整理的C++生成随机数—生成任意范围内的等概率随机数方法的全部内容,希望文章能够帮你解决C++生成随机数—生成任意范围内的等概率随机数方法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部