c++中生成随机数时的种子问题
我是个c++新手,希望各位能帮个忙我在编写遗传算法程序时,里面有很多个函数都需要随机数,而且需要运行很多遍(因为随机数每次生成的不一样,多算几次得到最优结果);我知道如果...
我是个c++新手,希望各位能帮个忙
我在编写遗传算法程序时,里面有很多个函数都需要随机数,而且需要运行很多遍(因为随机数每次生成的不一样,多算几次得到最优结果);我知道如果直接用a=rand()那么每次运行时得到的随机数都一样,比如第一次得到1、3、5、9,那么再运行一遍还是1、3、5、9,所以就必须用srand(time(0))这样来利用时间来初始化种子
我的问题是,我这个程序里面有很多个函数,每个都需要随机数,那么我是否应该在每个函数里面都写一句strand(time(0))呢?,还是只需要在main函数里面写一个,然后每个函数只需要写a=rand()就可以了呢?这两种有什么区别?我实验了一下,如果按如下编写
int a;
int b
srand(time(0));
for(int i=0;i<10;i++) {
a=rand()%101;
cout<<a<<'\t';
}
srand(time(0));
for(int ii=0;ii<10;ii++) {
b=rand()%101;
cout<<b<<'\t';
}
这样会得到两组完全一样的结果,例如
5 4 9 6 8 7 2 3 6 5
5 4 9 6 8 7 2 3 6 5
请问这是什么原因?
如果回答的好,我还可以再加分,请大家帮帮我 展开
我在编写遗传算法程序时,里面有很多个函数都需要随机数,而且需要运行很多遍(因为随机数每次生成的不一样,多算几次得到最优结果);我知道如果直接用a=rand()那么每次运行时得到的随机数都一样,比如第一次得到1、3、5、9,那么再运行一遍还是1、3、5、9,所以就必须用srand(time(0))这样来利用时间来初始化种子
我的问题是,我这个程序里面有很多个函数,每个都需要随机数,那么我是否应该在每个函数里面都写一句strand(time(0))呢?,还是只需要在main函数里面写一个,然后每个函数只需要写a=rand()就可以了呢?这两种有什么区别?我实验了一下,如果按如下编写
int a;
int b
srand(time(0));
for(int i=0;i<10;i++) {
a=rand()%101;
cout<<a<<'\t';
}
srand(time(0));
for(int ii=0;ii<10;ii++) {
b=rand()%101;
cout<<b<<'\t';
}
这样会得到两组完全一样的结果,例如
5 4 9 6 8 7 2 3 6 5
5 4 9 6 8 7 2 3 6 5
请问这是什么原因?
如果回答的好,我还可以再加分,请大家帮帮我 展开
展开全部
先纠正一下错误,是srand((unsigned int)time(0));srand的形参是unsigned int类型的;这句话只要写一次,一般情况下只能写一次;
随机数是随机的数,但计算机不可能产生随机数,计算机根据你的输入,再跟一个算法就产生一个特定的序列.
只要你给计算机一个相同的数,计算机返回的就是一个特定的数,所以这样的数叫做伪随机数.
而srand(unsigned int par);这就是原型,这就是你给计算机的数.计算机通过rand()返回一个序列,假设是{2,6,8,51....},只要给相同的参数, 这个序列是特定的.int a=rand();这时候a=2;所以可以得出只要每次给计算机不同的数也就是srand(unsigned int pra)也就是给pra是不同的值,我们就可以认为这个序列是随机的.要想给不同的值,最简单的方法是把系统时间转化成unsigned给计算机就可以了,因为每时每刻时间都是不同的.这里要注意,时间是秒为单位,也就是说你如果srand((unsigned)time(NULL)); 只是在每一秒内取随rand()的话,因为时间还没来得及变,它还不是完全随机的,在下一秒就会换取另一条序列,可以说是相对的随机。这牵扯掉内部的东西,只要知道层面上的东西就够了。
现在我来告诉你为什么你得到了2组一样的结果,因为计算机运算的速度是相当快的,你的2次srand()取值操作肯定是在一秒内之间发生的,第一次产生随机数后,你又写了一遍srand((unsigned)time(NULL)); 相当于根据时间又埋下了种子,而这次埋下的种子和上一次的种子是完全相同的,所以产生的序列也相同,于是计算机又按顺序从头开始把这条序列中的值取出来,产生了上述结果;
总结,在程序中只要写一次srand((unsigned)time(NULL));
随机数是随机的数,但计算机不可能产生随机数,计算机根据你的输入,再跟一个算法就产生一个特定的序列.
只要你给计算机一个相同的数,计算机返回的就是一个特定的数,所以这样的数叫做伪随机数.
而srand(unsigned int par);这就是原型,这就是你给计算机的数.计算机通过rand()返回一个序列,假设是{2,6,8,51....},只要给相同的参数, 这个序列是特定的.int a=rand();这时候a=2;所以可以得出只要每次给计算机不同的数也就是srand(unsigned int pra)也就是给pra是不同的值,我们就可以认为这个序列是随机的.要想给不同的值,最简单的方法是把系统时间转化成unsigned给计算机就可以了,因为每时每刻时间都是不同的.这里要注意,时间是秒为单位,也就是说你如果srand((unsigned)time(NULL)); 只是在每一秒内取随rand()的话,因为时间还没来得及变,它还不是完全随机的,在下一秒就会换取另一条序列,可以说是相对的随机。这牵扯掉内部的东西,只要知道层面上的东西就够了。
现在我来告诉你为什么你得到了2组一样的结果,因为计算机运算的速度是相当快的,你的2次srand()取值操作肯定是在一秒内之间发生的,第一次产生随机数后,你又写了一遍srand((unsigned)time(NULL)); 相当于根据时间又埋下了种子,而这次埋下的种子和上一次的种子是完全相同的,所以产生的序列也相同,于是计算机又按顺序从头开始把这条序列中的值取出来,产生了上述结果;
总结,在程序中只要写一次srand((unsigned)time(NULL));
2010-03-20
展开全部
srand(time(NULL));
只需要在main()函数中调用一次,如果每次取随机数之前都调用srand()函数,那么返回的随机数顺序是一样的.
只需要在main()函数中调用一次,如果每次取随机数之前都调用srand()函数,那么返回的随机数顺序是一样的.
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
// 其实一次两次都是可以的。
你这个程序两次都一样,因为两次srand()的时间太接近了,计算机速度这么快,你两次srand()的时间压根就一样,得到结果是一样的。
如果你在中间sleep(1000)一下,结果自然就不一样了。
// 给个例子你运行下。
#include <iostream>
#include <time.h>
#include <windows.h>
using namespace std;
int main()
{
int a;
int b;
srand(time(0));
for(int i=0;i<10;i++)
{
a=rand()%101;
cout<<a<<'\t';
}
Sleep(1000); // 只在这里+了这行,就可以实现不一样了。
srand(time(0));
for(int ii=0;ii<10;ii++)
{
b=rand()%101;
cout<<b<<'\t';
}
return 0;
}
+一次就可以了,系统会帮你自动选时间的。
有问题再Hi我。
你这个程序两次都一样,因为两次srand()的时间太接近了,计算机速度这么快,你两次srand()的时间压根就一样,得到结果是一样的。
如果你在中间sleep(1000)一下,结果自然就不一样了。
// 给个例子你运行下。
#include <iostream>
#include <time.h>
#include <windows.h>
using namespace std;
int main()
{
int a;
int b;
srand(time(0));
for(int i=0;i<10;i++)
{
a=rand()%101;
cout<<a<<'\t';
}
Sleep(1000); // 只在这里+了这行,就可以实现不一样了。
srand(time(0));
for(int ii=0;ii<10;ii++)
{
b=rand()%101;
cout<<b<<'\t';
}
return 0;
}
+一次就可以了,系统会帮你自动选时间的。
有问题再Hi我。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
标准库<cstdlib> (被包含于<iostream>中) 提供两个帮助生成伪随机数的函数:
函数一:int rand(void) ;
从srand (seed)中指定的seed 开始,返回一个[ seed, RAND_MAX (0x7fff) )间的随机整数。
函数二:void srand(unsigned seed);
参数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(int i=0;i<10;i++){
ran_num=ra nd() % 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=ra nd() % 6;
cout<<ran_num<<" ";
}
每次运行都将输出:5 5 4 4 5 4 0 0 4 2
跟例子一的结果完全一样。
例三,指定seed 为定值6:
srand(6);
for(int i=0;i<10;i++){
ran_num=ra nd() % 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>
//…
srand((unsigned)time(0));
for(int i=0;i<10;i++){
ran_num=ra nd() % 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<<time(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)可以取得0~1 之间的浮点数(注意,不同于整型时候的公式,是除以,不是求模) ,举例:
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 个0~1 之间的浮点数,每次结果都不同。如果想取更大范围的随机浮点数,比如1~10,可以将
rand() /(double)(RAND_MAX) 改为rand() /(double)(RAND_MAX/10)
运行结果为:7.19362,6.45775,…等10 个1~10 之间的浮点数,每次结果都不同。
至于100,1000 的情况,如此类推。
以上不是伪随机浮点数最好的实现方法,不过可以将就着用用!
函数一:int rand(void) ;
从srand (seed)中指定的seed 开始,返回一个[ seed, RAND_MAX (0x7fff) )间的随机整数。
函数二:void srand(unsigned seed);
参数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(int i=0;i<10;i++){
ran_num=ra nd() % 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=ra nd() % 6;
cout<<ran_num<<" ";
}
每次运行都将输出:5 5 4 4 5 4 0 0 4 2
跟例子一的结果完全一样。
例三,指定seed 为定值6:
srand(6);
for(int i=0;i<10;i++){
ran_num=ra nd() % 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>
//…
srand((unsigned)time(0));
for(int i=0;i<10;i++){
ran_num=ra nd() % 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<<time(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)可以取得0~1 之间的浮点数(注意,不同于整型时候的公式,是除以,不是求模) ,举例:
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 个0~1 之间的浮点数,每次结果都不同。如果想取更大范围的随机浮点数,比如1~10,可以将
rand() /(double)(RAND_MAX) 改为rand() /(double)(RAND_MAX/10)
运行结果为:7.19362,6.45775,…等10 个1~10 之间的浮点数,每次结果都不同。
至于100,1000 的情况,如此类推。
以上不是伪随机浮点数最好的实现方法,不过可以将就着用用!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询