C++随机数的生成1.docx

上传人:b****8 文档编号:10338786 上传时间:2023-02-10 格式:DOCX 页数:29 大小:22.70KB
下载 相关 举报
C++随机数的生成1.docx_第1页
第1页 / 共29页
C++随机数的生成1.docx_第2页
第2页 / 共29页
C++随机数的生成1.docx_第3页
第3页 / 共29页
C++随机数的生成1.docx_第4页
第4页 / 共29页
C++随机数的生成1.docx_第5页
第5页 / 共29页
点击查看更多>>
下载资源
资源描述

C++随机数的生成1.docx

《C++随机数的生成1.docx》由会员分享,可在线阅读,更多相关《C++随机数的生成1.docx(29页珍藏版)》请在冰豆网上搜索。

C++随机数的生成1.docx

C++随机数的生成1

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

函数一:

intrand(void);

从srand(seed)中指定的seed开始,返回一个[seed,RAND_MAX(0x7fff))间的随机整数。

函数二:

voidsrand(unsignedseed);

参数seed是rand()的种子,用来初始化rand()的起始值。

可以认为rand()在每次被调用的时候,它会查看:

1)如果用户在此之前调用过srand(seed),给seed指定了一个值,那么它会自动调用

srand(seed)一次来初始化它的起始值。

2)如果用户在此之前没有调用过srand(seed),它会自动调用srand

(1)一次。

根据上面的第一点我们可以得出:

1)如果希望rand()在每次程序运行时产生的值都不一样,必须给srand(seed)中的seed一个变值,这个变值必须在每次程序运行时都不一样(比如到目前为止流逝的时间)。

2)否则,如果给seed指定的是一个定值,那么每次程序运行时rand()产生的值都会一样,虽然这个值会是[seed,RAND_MAX(0x7fff))之间的一个随机取得的值。

3)如果在调用rand()之前没有调用过srand(seed),效果将和调用了srand

(1)再调用rand()一样(1也是一个定值)。

举几个例子,假设我们要取得0~6之间的随机整数(不含6本身):

例一,不指定seed:

for(inti=0;i<10;i++){

ran_num=rand()%6;

cout<

}

每次运行都将输出:

5544540042

例二,指定seed为定值1:

srand

(1);

for(inti=0;i<10;i++){

ran_num=rand()%6;

cout<

}

每次运行都将输出:

5544540042

跟例子一的结果完全一样。

例三,指定seed为定值6:

srand(6);

for(inti=0;i<10;i++){

ran_num=rand()%6;

cout<

}

每次运行都将输出:

4151434422

随机值也是在[0,6)之间,随得的值跟srand

(1)不同,但是每次运行的结果都相同。

例四,指定seed为当前系统流逝了的时间(单位为秒):

time_ttime(0):

#include

//…

srand((unsigned)time(0));

for(inti=0;i<10;i++){

ran_num=rand()%6;

cout<

}

第一次运行时输出:

0154502342

第二次:

3230355223

总之,每次运行结果将不一样,因为每次启动程序的时刻都不同(间隔须大于1秒?

见下)。

关于time_ttime(0):

time_t被定义为长整型,它返回从1970年1月1日零时零分零秒到目前为止所经过的时间,单位为秒。

比如假设输出:

cout<

值约为1169174701,约等于37(年)乘365(天)乘24(小时)乘3600(秒)(月日没算)。

另外,关于ran_num=rand()%6,

将rand()的返回值与6求模是必须的,这样才能确保目的随机数落在[0,6)之间,否则rand()的返回值本身可能是很巨大的。

一个通用的公式是:

要取得[a,b)之间的随机整数,使用(rand()%(b-a))+a(结果值将含a不含b)。

在a为0的情况下,简写为rand()%b。

最后,关于伪随机浮点数:

用rand()/double(RAND_MAX)可以取得0~1之间的浮点数(注意,不同于整型时候的公式,是除以,不是求模),举例:

doubleran_numf=0.0;

srand((unsigned)time(0));

for(inti=0;i<10;i++){

ran_numf=rand()/(double)(RAND_MAX);

cout<

}

运行结果为:

0.716636,0.457725,…等10个0~1之间的浮点数,每次结果都不同。

如果想取更大范围的随机浮点数,比如1~10,可以将

rand()/(double)(RAND_MAX)改为rand()/(double)(RAND_MAX/10)

运行结果为:

7.19362,6.45775,…等10个1~10之间的浮点数,每次结果都不同。

至于100,1000的情况,如此类推。

●C++中常用rand()函数生成随机数,但严格意义上来讲生成的只是伪随机数(pseudo-randomintegralnumber)。

生成随机数时需要我们指定一个种子,如果在程序内循环,那么下一次生成随机数时调用上一次的结果作为种子。

但如果分两次执行程序,那么由于种子相同,生成的“随机数”也是相同的。

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

给一下例程如下:

#include

#include

#include

usingnamespacestd;

intmain()

{

   doublerandom(double,double);

   srand(unsigned(time(0)));

   for(inticnt=0;icnt!

=10;++icnt)

       cout<<"No."<

"<

   return0;

}

doublerandom(doublestart,doubleend)

{

   returnstart+(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

usingnamespacestd;

intmain()

{

   doublerandom(double,double);

   inta[10]={0};

   constintGen_max=10000000;

   srand(unsigned(time(0)));

   

   for(inticnt=0;icnt!

=Gen_max;++icnt)

      switch(int(random(0,10)))

      {

      case0:

a[0]++;break;

      case1:

a[1]++;break;

      case2:

a[2]++;break;

      case3:

a[3]++;break;

      case4:

a[4]++;break;

      case5:

a[5]++;break;

      case6:

a[6]++;break;

      case7:

a[7]++;break;

      case8:

a[8]++;break;

      case9:

a[9]++;break;

      default:

cerr<<"Error!

"<

      }

   

   for(inticnt=0;icnt!

=10;++icnt)

      cout<

"<

:

fixed)<

(2)<

   

   return0;

}

doublerandom(doublestart,doubleend)

{

   returnstart+(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%

*/

可知用这种方法得到的随机数是满足统计规律的。

用C语言产生随机数

在C语言中,rand()函数可以用来产生随机数,但是这不是真真意义上的随机数,是一个伪随机数,是根据一个数,我们可以称它为种子,为基准以某个递推公式推算出来的一系数,当这系列数很大的时候,就符合正态公布,从而相当于产生了随机数,但这不是真正的随机数,当计算机正常开机后,这个种子的值是定了的,除非你破坏了系统,为了改变这个种子的值,C提供了srand()函数,它的原形是voidsrand(inta)。

可能大家都知道C语言中的随机函数random,可是random函数并不是ANSIC标准,所以说,random函数不能在gcc,vc等编译器下编译通过。

rand()会返回一随机数值,范围在0至RAND_MAX间。

返回0至RAND_MAX之间的随机数值,RAND_MAX定义在stdlib.h,(其值至少为32767)我运算的结果是一个不定的数,要看你定义的变量类型,int整形的话就是32767。

在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。

一般用for语句来设置种子的个数。

具体见下面的例子。

 

一如何产生不可预见的随机序列呢

利用srand((unsignedint)(time(NULL))是一种方法,因为每一次运行程序的时间是不同的。

      在C语言里所提供的随机数发生器的用法:

现在的C编译器都提供了一个基于ANSI标准的伪随机数发生器函数,用来生成随机数。

它们就是rand()和srand()函数。

这二个函数的工作过程如下:

1)首先给srand()提供一个种子,它是一个unsignedint类型,其取值范围从0~65535;

2)然后调用rand(),它会根据提供给srand()的种子值返回一个随机数(在0到32767之间)

3)根据需要多次调用rand(),从而不间断地得到新的随机数;

4)无论什么时候,都可以给srand()提供一个新的种子,从而进一步“随机化”rand()的输出结果。

     下面是0~32767之间的随机数程序:

#include

#include

#include          //使用当前时钟做种子

voidmain(void)

{inti;

srand((unsigned)time(NULL));         //初始化随机数

    for(i=0;i<10;i++)                         //打印出10个随机数

         printf("%d\n",rand());

}

  根据上面的程序可以很容易得到0~1之间的随机数:

#include

#include

#include

main()

{inti;

srand((unsigned)time(NULL)); 

      for(i=0;i<10;i++)

           printf("%5.2f\n",rand()/32767.0);

}

    而产生1~100之间的随机数可以这样写:

#include

#include

#include

main()

{inti;

srand((unsigned)time(NULL)); 

      for(i=0;i<10;i++)

           printf("%d\n",rand()%100+1);

}

comefrom

二,三个通用的随机数发生器,推荐用第三个

函数名:

rand

功 能:

随机数发生器

用 法:

voidrand(void);

程序例:

#include

#include

intmain(void)

{

  inti;

  printf("Tenrandomnumbersfrom0to99\n\n");

  for(i=0;i<10;i++)

     printf("%d\n",rand()%100);

  return0;

}

 函数名:

random

功 能:

随机数发生器

用 法:

intrandom(intnum);

程序例:

#include

#include

#include

/*printsarandomnumberintherange0to99*/

intmain(void)

{

  randomize();

  printf("Randomnumberinthe0-99range:

%d\n",random(100));

  return0;

}

 

 

函数名:

randomize    这个比较好!

功 能:

初始化随机数发生器

用 法:

voidrandomize(void);

程序例:

#include

#include

#include

intmain(void)

{

  inti;

  randomize();

  printf("Tenrandomnumbersfrom0to99\n\n");

  for(i=0;i<10;i++)

      printf("%d\n",rand()%100);

  return0;

}

 

在《计算机常用算法》中有介绍随机数的生成算法

三如何产生设定范围内的随机数  

 由于rand产生的随机数从0到rand_max,而rand_max是一个很大的数,那么如何产生从X~Y的数呢?

   从X到Y,有Y-X+1个数,所以要产生从X到Y的数,只需要这样写:

   k=rand()%(Y-X+1)+X;

   这样,就可以产生你想要的任何范围内的随机数了。

四,产生不重复的随机数

1)#include

#include

#include

 #include 

swap(int*pm,int*pn)     /*必须用指针进行交换*/

{

  inttemp;

  temp=*pm;

  *pm=*pn;

  *pn=temp;

}

intmain(void)

{

int  i,a[513];

/*int*pa,*pb;*/

srand((unsigned)time(NULL));/*定义这个可以产生不同的随机数*/

for(i=1;  i<=512;  i++){a[i]=i;printf("%4d",a[i]);}

for(i=512;  i>=1;  i--)

{

 /*pa=&a[i];pb=&a[rand()%i+1];*/

 swap(&a[i],&a[rand()%i+1]);    /*加一是从一到i的随机,就不会包含0*/

 /*不用再定义指针,这样结论是一样的*/

}

  printf("\n") ;

 for(i=1;  i<=64;  i++)

  printf("%4d",a[i]);

getch();  /*wintc的输出*/

}

2)

 #include

#include

#include

intmain(void)

{

  inta[100]={0}; inti,m;

   for(i=1;  i<=99;  ++i)

    printf("%4d",a[i]);

srand((unsigned)time(NULL));

for(i=1;i<=99;i++)

{

       while(a[m=rand()%100+1]);

       a[m]=i;

}

      for(i=1;  i<=99;  ++i)

    printf("%4d",a[i]);

getch();

}

//Snake.cpp:

定义控制台应用程序的入口点。

//Thisprogramisusedtocollectthemostmarkandoutputtheroutine.

//bynwpu043814

//date:

20100509

#include"stdafx.h"

#include

#include

#include

usingnamespacestd;

//thisstructrepresentsanlocation.

typedefstruct

{

intx;

inty;

}Pair;

classGrid

{

private:

Grid(constGrid&g);

public:

Pair*m_data;

constintm_width;    //gridwidth

constintm_height;  //gridheight

int*m_adjacent;  //memoryarray

//constructorwithwidthandheightofthegrid.

Grid(intx,inty):

m_width(x),m_height(y)

{

  m_data=newPair[x*y];

  memset(m_data,0,x*y*sizeof(Pair));

  m_adjacent=newint[x*y];

  memset(m_adjacent,-1,x*y*sizeof(int));

}

//freeresource

~Grid()

{

  delete[]m_data;

  delete[]m_adjacent;

}

intBin2One(intx,inty)

{

  returny*m_width+x;

}

PairOne2Bin(intindex)

{

  Pairp;

  p.x=index%m_width;

  p.y=index/m_width;

  returnp;

}

//thismethodisusedtogetorsettheitemofthegrid.

int&item(intx,inty)

{

  returnm_data[x+y*m_width].x;

}

//dynamicprogrammainmethod,itrecursivelyselectthenextlocationfromtheadjacentsaccordingtothepriority.

intgetCap(constPair&loc)

{

  //thisarrayisusedtostoragethepriorityoffouradjacents.

  intvalue[4]={0};

  //thisarrayisusedtoaccessfouradjacentsaccordingtocurrentlocation.

  intmask[4][2]={

   {-1,0},{0,1},{1,0},{0,-1}/*{x_coordinate,y_coordinate}*/

  };

  //now,westarttodealwithfouradjacents.

  for(inti=0;i<4;i++)

  {

   //makesurecurrentlocationhasfouradjacents

   if(loc.x+mask[i][0]>=0&&loc.x+mask[i][0]

    &&loc.y+mask[i][1]>=0&&loc.y+mask[i][1]

   {

   

    //ifthetoyintheadjacentcanholdcurrentone.

    intcurrent_toy=(m_data[Bin2One(loc.x,loc.y)].x>0)?

m_data[Bin2One(loc.x,loc.y)].x:

m_data[Bin2One(loc.x,loc.y)].y;

    if(item(loc.x+mask[i][0],loc.y+mask

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 调查报告

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1