C++随机数的生成

上传人:小** 文档编号:43695140 上传时间:2021-12-03 格式:DOC 页数:20 大小:182KB
收藏 版权申诉 举报 下载
C++随机数的生成_第1页
第1页 / 共20页
C++随机数的生成_第2页
第2页 / 共20页
C++随机数的生成_第3页
第3页 / 共20页
资源描述:

《C++随机数的生成》由会员分享,可在线阅读,更多相关《C++随机数的生成(20页珍藏版)》请在装配图网上搜索。

1、标准库 <cstdlib> (被包含于 <iostream> 中)提供两个帮助生成伪随机数的函数: 函数一: int rand(void) ;从 srand (seed) 中指定的 seed 开始,返回一个 seed, RAND_MAX ( 0x7fff )间的随机整数。函数二: void srand(unsigned seed) ;参数 seed 是 rand() 的种子,用来初始化 rand() 的起始值。可以认为 rand() 在每次被调用的时候,它会查看:1) 如果用户在此之前调用过srand(seed),给seed指定了一个值,那么它会自动调用 sran d(

2、seed)一次来初始化它的起始值。2) 如果用户在此之前没有调用过srand(seed),它会自动调用srand(1)一次。根据上面的第一点我们可以得出:1) 如果希望rand ()在每次程序运行时产生的值都不一样,必须给srand(seed)中的seed 一个变值,这个变值必须在每次程序运行时都不一样(比如到目前为止流逝的时间)。2) 否则,如果给seed指定的是一个定值,那么每次程序运行时rand ()产生的值都会一样,虽然这个值会是 seed, RAND_MAX( 0x7fff )之间的一个随机取得的值。3) 如果在调用 rand() 之前没有调用过 srand(seed) ,效果将和调

3、用了 srand(1) 再调用 rand() 一样( 1 也是一个定值)。举几个例子,假设我们要取得06之间的随机整数(不含 6本身):例一,不指定 seed :for(int i=0;i<10;i+)ran_num=rand() % 6;cout<<ran_num<<" "每次运行都将输出: 5 5 4 4 5 4 0 0 4 2例二,指定 seed 为定值 1 :srand(1);for(int i=0;i<10;i+)ran_num=rand() % 6;cout<<ran_num<<" "

4、;每次运行都将输出: 5 5 4 4 5 4 0 0 4 2 跟例子一的结果完全一样。例三,指定 seed 为定值 6 :srand(6);for(int i=0;i<10;i+)ran_num=rand() % 6;cout<<ran_num<<" " 每次运行都将输出: 4 1 5 1 4 3 4 4 2 2随机值也是在 0,6 )之间,随得的值跟 srand(1) 不同,但是每次运行的结果都相同。例四,指定 seed 为当前系统流逝了的时间(单位为秒): time_t time(0) :#include <ctime>sran

5、d(unsigned)time(0);for(i nt i=0;i<10;i+)ran_num=rand() % 6;cout<<ran_num<<" " 第一次运行时输出: 0 1 5 4 5 0 2 3 4 2第二次: 3 2 3 0 3 5 5 2 2 3总之,每次运行结果将不一样, 因为每次启动程序的时刻都不同 (间隔须大于 1 秒?见下) 。关于 time_t time(0) :time_t 被定义为长整型, 它返回从 1970 年 1 月 1 日零时零分零秒到目前为止所经过的时间, 单位为秒。比如假设输出:cout<<t

6、ime(0);值约为 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)可以

7、取得01之间的浮点数(注意,不同于整型时候的公式,是除以,不是求模),举例:double ran_numf=0.0;srand(unsigned)time(0);for(int i=0;i<10;i+)ran_numf = rand() / (double)(RAND_MAX);cout<<ran_numf<<" "运行结果为:0.716636 , 0.457725 ,等10个01之间的浮点数,每次结果都不同。如果想取更大范围的随机浮点数,比如 110,可以将rand() /(double)(RAND_MAX) 改为 rand() /(doub

8、le)(RAND_MAX/10)运行结果为:7.19362 , 6.45775 ,等10个110之间的浮点数,每次结果都不同。 至于 100, 1000 的情况,如此类推。C+中常用ran d()函数生成随机数,但严格意义上来讲生成的只是伪随机数 (pseudo-random integral number )。生成随机数时需要我们指定一个种子,如果在程序 内循环,那么下一次生成随机数时调用上一次的结果作为种子。 但如果分两次执行程序, 那么由于种子相同,生成的 “随机数 ”也是相同的。在工程应用时, 我们一般将系统当前时间 (Unix 时间 )作为种子, 这样生成的随机数更接 近于实际意义上

9、的随机数。给一下例程如下:#include <iostream>#include <ctime>#include <cstdlib>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)<

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 个数出现的频率是不是大

11、 致相同的。程序如下:#include <iostream>#include <ctime>#include <cstdlib>#include <iomanip>using namespace std;int main()double random(double,double);int a10 = 0;const int Gen_max = 10000000; srand(unsigned(time(0);for(int icnt = 0; icnt != Gen_max; +icnt) switch(int(random(0,10)case

12、0: a0+; break;case 1: a1+; break;case 2: a2+; break;case 3: a3+; break;case 4: a4+; break;case 5: a5+; break;case 6: a6+; break;case 7: a7+; break;case 8: a8+; break;case 9: a9+; break;default: cerr << "Error!" << endl; exit(-1); for(int icnt = 0; icnt != 10; +icnt)cout <<

13、; icnt << ": " << setw(6) << setiosflags(ios:fixed) << setprecision(2) << double(aicnt)/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

14、.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() 函数可以用来产生随机数, 但是这不是真真意义上的随机数, 是一个 伪随机数,是根据一个数, 我们可以称它为种子, 为基准以某个递推公式推算出来的一系数, 当这系列数很大的时候, 就符合正态公布, 从而相当于产生了随机数, 但这不是真正的随机 数,当计算机正常开机后, 这个种子的值是定了的, 除非你破坏了系统, 为了

15、改变这个种子 的值, C 提供了 srand() 函数,它的原形是 void srand( int a) 。可能大家都知道 C 语言中的随机函数 random ,可是 random 函数并不是 ANSI C 标准, 所以说, random 函数不能在 gcc,vc 等编译器下编译通过。rand()会返回一随机数值, 范围在0至RAND_MAX 间。返回0至RAND_MAX 之间的 随机数值, RAND_MAX 定义在 stdlib.h , (其值至少为 32767)我运算的结果是一个不定的数, 要看你定义的变量类型, int 整形的话就是 32767。 在调用此函数产生随机数前,必须先利 用s

16、rand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为 1。 一般用 for 语句来设置种子的个数。具体见下面的例子。一如何产生不可预见的随机序列呢利用srand(unsigned int)(time(NULL)是一种方法,因为每一次运行程序的时间是不同的。在C语言里所提供的随机数发生器的用法:现在的 C编译器都提供了一个基于 ANSI 标准的伪随机数发生器函数,用来生成随机数。它们就是rand()和srand()函数。这二个函数的工作过程如下:1) 首先给srand()提供一个种子,它是一个unsigned int类型,其取值范围从 065535 ;2) 然

17、后调用rand(),它会根据提供给 srand()的种子值返回一个随机数(在0到32767之间)3) 根据需要多次调用rand(),从而不间断地得到新的随机数;4) 无论什么时候,都可以给srand()提供一个新的种子,从而进一步随机化” rand的输出结果。下面是032767之间的随机数程序:#in clude <stdlib.h>#i nclude <stdio.h>#in clude <time.h>II使用当前时钟做种子void mai n( void )int i;srand( (un sig ned)time( NULL ); for( i =

18、0; i < 10;i+ )prin tf( " %dn", ran d();根据上面的程序可以很容易得到II初始化随机数II打印出10个随机数01之间的随机数:#in clude <stdlib.h>#i nclude <stdio.h>#in clude <time.h>mai n()int i;srand( (un sig ned)time( NULL );for( i = 0; i < 10;i+ )prin tf( "%5.2fn", ran d()I32767.0);而产生1100之间的随机数可

19、以这样写:#i nclude <stdlib.h>#in clude <stdio.h>#in clude <time.h>mai n()int i;srand( (un sig ned)time( NULL );for( i = 0; i < 10;i+ )prin tf( "%dn", ran d()%100+1);come from 二,三个通用的随机数发生器,推荐用第三个 函数名 : rand 功 能 : 随机数发生器 用 法: void rand(void); 程序例 :#include <stdlib.h>#

20、include <stdio.h>int main(void)int i;printf("Ten random numbers from 0 to 99nn");for(i=0; i<10; i+)printf("%dn", rand() % 100);return 0;函数名 : random功 能 : 随机数发生器用 法: int random(int num); 程序例 :#include <stdlib.h>#include <stdio.h>#include <time.h>/* print

21、s a random number in the range 0 to 99 */int main(void)randomize();printf("Random number in the 0-99 range: %dn", random (100); return 0;函数名 : randomize 这个比较好!功 能 : 初始化随机数发生器用 法: void randomize(void); 程序例 :#include <stdlib.h>#include <stdio.h>#include <time.h>int main(voi

22、d)int i;randomize();printf("Ten random numbers from 0 to 99nn");for(i=0; i<10; i+) printf("%dn", rand() % 100);return 0;在计算机常用算法中有介绍随机数的生成算法三 如何产生设定范围内的随机数由于 rand 产生的随机数从 0 到 rand_max ,而 rand_max 是一个很大的数,那么如何产生从 XY 的数呢?从X到Y,有Y X + 1个数,所以要产生从 X到Y的数,只需要这样写: k=rand()%( Y -X+ 1 )+

23、X;这样,就可以产生你想要的任何范围内的随机数了。 四,产生不重复的随机数1 ) #include <stdlib.h> #include <stdio.h> #include<stdio.h> #include <time.h> swap(int *pm,int *pn)/* 必须用指针进行交换 */int temp;temp=*pm;*pm=*pn;*pn=temp;int main(void)int i,a513;/*int *pa,*pb;*/srand( (unsigned)time( NULL ) ); /* 定义这个可以产生不同的随

24、机数 */ for(i=1; i<=512; i+)ai=i;printf("%4d",ai); for(i=512; i>=1; i-)/* pa=&ai; pb=&arand()%i+1;*/swap(&ai, &arand()%i+1);/* 加一是从一到 i 的随机,就不会包含 0*/* 不用再定义指针,这样结论是一样的 */ printf("n") ;for(i=1; i<=64; i+) printf("%4d",ai );getch(); /*wintc 的输出 */2)

25、 #include <stdlib.h>#include <stdio.h>#include<stdio.h> int main(void)int a100=0; int i,m;for(i=1; i<=99; +i) printf("%4d",ai );srand( (unsigned)time( NULL ) ); for(i=1; i<=99; i+)while(am=rand()%100+1); am = i;for(i=1; i<=99; +i) printf("%4d",ai );getc

26、h();/ Snake.cpp : 定义控制台应用程序的入口点。/This program is used to collect the most mark and output the routine. /by nwpu043814/date:20100509#include "stdafx.h"#include <iostream>#include <fstream>#include <vector>using namespace std;/this struct represents an location. typedef str

27、uctint x;int y; Pair;class Grid private :Grid(const Grid& g);public: Pair * m_data;const int m_width; /grid widthconst int m_height; /grid height int * m_adjacent; /memory array/constructor with width and height of the grid. Grid(int x, int y):m_width(x), m_height(y) m_data = new Pairx*y; memset

28、(m_data, 0, x*y *sizeof(Pair); m_adjacent = new intx*y; memset(m_adjacent, -1, x*y *sizeof(int);/free resourceGrid()delete m_data; delete m_adjacent;int Bin2One(int x, int y)return y*m_width + x;Pair One2Bin(int index)Pair p;p.x = index % m_width;p.y = index / m_width;return p;/this method is used t

29、o get or set the item of the grid.int & item(int x, int y)return m_datax+ y*m_width.x;/dynamic program main method, it recursively select the next location from the adjacents according to the priority.int getCap(const Pair & loc)/this array is used to storage the priority of four adjacents.i

30、nt value4 = 0;/this array is used to access four adjacents according to current location.int mask42 = -1,0,0,1,1,0,0,-1/*x_coordinate, y_coordinate*/;/now, we start to deal with four adjacents.for (int i = 0; i < 4; i+)/make sure current location has four adjacentsif (loc.x + maski0 >= 0 &

31、& loc.x + maski0 < m_width&& loc.y + maski1 >= 0 && loc.y + maski1 < m_height) /if the toy in the adjacent can hold current one.int current_toy = (m_dataBin2One(loc.x, loc.y).x >0)?m_dataBin2One(loc.x, loc.y).x:m_dataBin2One(loc.x, loc.y).y; if ( item(loc.x + maski0,

32、loc.y + maski1) >current_toy/item(loc.x , loc.y)| item(loc.x + maski0, loc.y + maski1) = 0)/when the adjacent has no toy.Pair adjacent;adjacent.x = loc.x + maski0;adjacent.y = loc.y + maski1;m_dataBin2One(adjacent.x, adjacent.y).y = current_toy; valuei = getCap(adjacent);int sum = 0;for (int i =

33、0; i < 4; i+)sum += valuei;/when all adjacents is less than current.if (sum = 0)return item(loc.x , loc.y);elseint index = 0;int current_max = valueindex;int select = 0;for (int index = 0; index < 4; index+)if (current_max < valueindex)current_max = valueindex;select = index;m_adjacentBin2O

34、ne(loc.x, loc.y) = Bin2One(loc.x + maskselect0, loc.y + maskselect1);return current_max + item(loc.x , loc.y);/this method drives the classvoid run()Pair loc;loc.x = 0;loc.y = 0;for (int i = 0; i < m_width*m_height; i+)m_datai.y = m_datai.x;cout << "total mark=" << this->

35、getCap(loc) << endl;/display the gridvoid displayGrid()for (int i =0 ; i < this->m_height; i+)for (int j = 0; j < this->m_width; j+)cout << " " << this->m_datai*m_width + j.x;cout << endl;/display the routine.void print()int current, next, out ;curren

36、t = 0;next = m_adjacentcurrent;out = m_datacurrent.x;while (next != -1)cout << " " << out ;current = next;next = m_adjacentcurrent; out = m_datacurrent.x;cout << " " << out ;int _tmain(int argc, _TCHAR* argv) ifstream in("input.txt"); int x,y, k,

37、 value;in >> x >> y ;Grid * grid = new Grid(y, x);value = 0;/this block initializes the grid items with ifstream. while (true)if (in.eof() break; in >> k;grid->item(value%grid->m_width, value/grid->m_width) = k; value+;grid->displayGrid(); grid->run();/done grid->

38、print();cin >>x; delete grid; grid = NULL; in.close(); return 0;/ Snake.cpp : 定义控制台应用程序的入口点。/This program is used to collect the most mark and output the routine. /by nwpu043814/date:20100509#include "stdafx.h"#include <iostream>#include <fstream>#include <vector>us

39、ing namespace std;/this struct represents an location. typedef structint x;int y; Pair;class Gridprivate :Grid(const Grid& g);public: Pair * m_data;const int m_width; /grid widthconst int m_height; /grid height int * m_adjacent; /memory array/constructor with width and height of the grid. Grid(i

40、nt x, int y):m_width(x), m_height(y) m_data = new Pairx*y; memset(m_data, 0, x*y *sizeof(Pair); m_adjacent = new intx*y; memset(m_adjacent, -1, x*y *sizeof(int);/free resourceGrid()delete m_data;delete m_adjacent; int Bin2One(int x, int y)return y*m_width + x; Pair One2Bin(int index)Pair p;p.x = ind

41、ex % m_width;p.y = index / m_width;return p;/this method is used to get or set the item of the grid. int & item(int x, int y)return m_datax+ y*m_width.x;/dynamic program main method, it recursively select the next location from the adjacents according to the priority.int getCap(const Pair &

42、loc)/this array is used to storage the priority of four adjacents.int value4 = 0;/this array is used to access four adjacents according to current location.int mask42 = -1,0,0,1,1,0,0,-1/*x_coordinate, y_coordinate*/ ;/now, we start to deal with four adjacents.for (int i = 0; i < 4; i+)/make sure

43、 current location has four adjacentsif (loc.x + maski0 >= 0 && loc.x + maski0 < m_width&& loc.y + maski1 >= 0 && loc.y + maski1 < m_height)/if the toy in the adjacent can hold current one.int current_toy = (m_dataBin2One(loc.x, loc.y).x >0)?m_dataBin2One(loc.x,

44、 loc.y).x:m_dataBin2One(loc.x, loc.y).y;if ( item(loc.x + maski0, loc.y + maski1) > current_toy/item(loc.x , loc.y)| item(loc.x + maski0, loc.y + maski1) = 0)/when the adjacent has no toy.Pair adjacent;adjacent.x = loc.x + maski0;adjacent.y = loc.y + maski1;m_dataBin2One(adjacent.x, adjacent.y).y

45、 = current_toy; valuei = getCap(adjacent);int sum = 0;for (int i = 0; i < 4; i+)sum += valuei;/when all adjacents is less than current.if (sum = 0)return item(loc.x , loc.y);elseint index = 0;int current_max = valueindex;int select = 0;for (int index = 0; index < 4; index+)if (current_max <

46、 valueindex)current_max = valueindex;select = index;m_adjacentBin2One(loc.x, loc.y) = Bin2One(loc.x + maskselect0, loc.y + maskselect1);return current_max + item(loc.x , loc.y);/this method drives the classvoid run()Pair loc;loc.x = 0;loc.y = 0;for (int i = 0; i < m_width*m_height; i+)m_datai.y =

47、 m_datai.x;cout << "total mark=" << this->getCap(loc) << endl;/display the gridvoid displayGrid()for (int i =0 ; i < this->m_height; i+)for (int j = 0; j < this->m_width; j+)cout << " " << this->m_datai*m_width + j.x;cout << e

48、ndl;/display the routine.void print()int current, next, out ;current = 0;next = m_adjacentcurrent;out = m_datacurrent.x;while (next != -1)cout << " " << out ;current = next;next = m_adjacentcurrent;out = m_datacurrent.x;cout << " " << out ;int _tmain(int a

49、rgc, _TCHAR* argv) ifstream in("input.txt");int x,y, k, value;in >> x >> y ;Grid * grid = new Grid(y, x);value = 0;/this block initializes the grid items with ifstream.while (true)if (in .eof()break;in >> k;grid->item(value%grid->m_width, value/grid->m_width) = k

50、; value+;grid->displayGrid();grid->r un();/donegrid->pri nt();cin >>x;delete grid;grid = NULL;in .close();return 0;应百度网友wu329613403的要求,花半小时写了个大体思路,最近太忙了,只能 写个思路,估计有不完善的地方,欢迎指正。(注意题目中没有给将距离与时间 沟通起来的教师行进速度,我认为应该给。)A,假设家长数目为N,从文件读取家长的时间表,定义一个家长类,包括的成 员为开始时间,结束时间,家长编号,存储到其余每个家长的距离的一个数组, 从

51、文件读入多少个家长就创建多少个家长对象,用一个容器C1来存放N个家长对象的指针,定义一个容器 C2保存家长的拜访情况.B, 删除安排时间段小于45分钟的家长,根据每个家长的开始时间对容器 C1中 的家长进行排序,时间早的排在最前面。C, 选取开始时间最早的家长作为当前准备拜访的家长,拜访时间持续 45分钟, 将当前家长的拜访情况保存到容器 C2,同时从容器C1中删除当前家长的信息。D, 用当前家长到其余每个(未拜访)的家长的时间加上各个家长的开始时间作 为每个家长的新的开始时间,重新对容器 C1按照新的开始时间进行排序,对容 器中的家长C1i进行判断(i从0开始):if( 当前家长的开始时间比

52、现在的时间早(小,意思是已经错过了) )新拜访结束时刻 1 = 当前时时刻 + 刚刚拜访的家长到当前家长 C1i 需要的 时间长度 + 45 分钟;if ( 新拜访结束时刻 1 比 家长 C1i 的结束时刻早 ( 或者为同一个时刻 )拜访这个家长 C1i ,时间持续 45 分钟 ; 将拜访信息添加到 C2;从 C1 中删除当前家长 C1i;if(C1 不为空 )goto D;(意思是:重复步骤D的内容)elsegoto E;( 去输出C2的内容)else从C1中删除当前家长C1i;else拜访容器 C1 中的排第一的家长,时间持续 45分钟;( 出现这种情况,就是老 师走到下个拜访的家长的时候, 拜访时间还没有开始, 需要等待一段时间, 实际 上这样的情况是浪费了时间了, 谁叫这个家长的开始时间安排的晚呢, 不能怪老 师。)将拜访信息添加到 C2;从C1中删除当前家长C1i;if(C1 不为空 )goto D;(意思是:重复步骤D的内容)elsegoto E;( 去输出C2的内容)E, 根据容器C2的拜访记录输出家访安排计划

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!