为什么srand()不起作用???

HelloDan 2008-02-22 11:02:42

//genetype.h

#ifndef __genetype_H
#define __genetype_H

#include<bitset>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<ctime>

////////////////////////////////////////////////////////////////////////////////////////////////
// The following is ths definition of the class.
const std::size_t bits(15);
//srand((unsigned)time(NULL));

class genetype
{
public: // Constructor function to initialize the class
genetype(unsigned long ul=0,double rf=0.8,double cf=0.8,double f=1000.0,double rl=10.0)\
:gene(ul),rfitness(rf),cfitness(cf),fitness(f),ruler(rl) // initialize the members of the class
{ //here reset bitset to be a random bitset.
srand((unsigned)time(NULL));
int tmp(0);
for(size_t i=0;i<bits;++i)
{
tmp=rand()%bits;
gene.flip(tmp); // Reverse value of the bit in b in tmp, in order to make it a random bitset.
}
fitness=static_cast<double>(gene.to_ulong())/10.0; // as a root of the function to solve.
ruler=fabs((1.0/350.0)*pow((0.021*pow(fitness,1.85)+0.25*25*25),0.50)*pow(fitness,0.84)-24.0);
if(ruler<0.1)
ruler=5.0;
else
ruler=1.0/ruler;
}

genetype& operator = (const genetype&); // Overload assignment operator
///////////////////////////////////////////////////////////////////////////////////////////////
// basic interface functions

std::bitset<bits> getgene() const; // return the genes of the individual
bool getbit(const size_t& st) const; // get the excetly bit of the gene.
double getrf() const; // get relative fitness
double getcf() const; // get cumulative fitness
double getfitness() const; // get GT's fitness, us it to get the best individual
double getruler() const;


typedef std::vector<genetype>::iterator VIP;

private:
std::bitset<bits> gene; // using bitset to implement binary form genetype, set integral part
// precision to 10000, and the other to indicate the decimal fraction
//static double best; // store the best fitness value of the best individual

double rfitness; // relative fitness
double cfitness; // cumulative fitness
double fitness; // GT's fitness, us it to get the best individual
double ruler; // set for "roulette wheel" algorithm
};

#endif




//genetype.cpp

#include"genetype.h"
/////////////////////////////////////////////////////////////////////////////////////////
//The following are the implimentations of the class member functions.


// Overload assignment operator
genetype& genetype::operator = (const genetype& rhs)
{
gene=rhs.gene;
rfitness=rhs.rfitness;
cfitness=rhs.cfitness;
ruler=rhs.ruler;
fitness=rhs.fitness;
return *this;
}


double genetype::getruler()const
{
return ruler;
}


// get relative fitness
double genetype::getrf() const
{
return rfitness;
}

// get cumulative fitness
double genetype::getcf() const
{
return cfitness;
}

// get GT's fitness, us it to get the best individual
double genetype::getfitness() const
{
return fitness;
}

bool genetype::getbit(const size_t& st) const
{
return gene[st];
}

std::bitset<bits> genetype::getgene() const // return the genes of the individual
{
return gene;
}








//main.cpp
#include<iostream>
#include<ctime>
#include"genetype.h"

using namespace std;


////////////////////////////////////////////////////////////////////////////////////
// Basic settings
const size_t MaxGen(1000); // generation to evaluate
const size_t PopSize(50); // populations of each generations
double pmutation=0.15; // probability of mutation
double pxcross=0.8; // probability of crossover


void display(const genetype& ge,ostream &os=cout)
{
os<<"\n Probability of mutation: "<<pmutation;
os<<"\n Probability of crossover:"<<pxcross<<"\n";
os<<"\n Relative fitness: "<<ge.getrf();
os<<"\n cumulative fitness:"<<ge.getcf();
os<<"\n Best fitness:"<<ge.getfitness();
os<<"\n Gene type: "<<ge.getgene();
os<<"\n Ruler: "<<ge.getruler()<<endl;
}

/**************************************************************/
/* Main function: Each generation involves selecting the best */
/* members, performing crossover & mutation and then */
/* evaluating the resulting population, until the terminating */
/* condition is satisfied */
/**************************************************************/
int main()
{
srand((unsigned)time(NULL)); // seed for rand
vector<genetype> gvec(10);
for(vector<genetype>::iterator it=gvec.begin();it!=gvec.end();++it)
{
display(*it);
}

system("pause");
return 0;
}
//这是我写的一个遗传算法的程序,为了方便阅读我已经将程序缩到最少代码量了。但我发现有一个问题,是经过构造函数出来的
//所有个体是一样的。我要每个个体出来的基因型是随机的。好像srand((unsigned)time(NULL));根本不起作用。请问各位,我应该怎样改才行?
//即display()出来的数据不是每一个都相同。我在主程序里面有测试。麻烦了!!! 谢谢!!!
//
...全文
608 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
HelloDan 2008-02-23
  • 打赏
  • 举报
回复
果然是这样,数组是可以的,但STL的不行。以前看过string类有copy on write的特性,可能vector也是这样的物性吧。

再一次,谢谢ltc_mouse
HelloDan 2008-02-23
  • 打赏
  • 举报
回复
STL我也没有学得太深,可能是这样吧。以前看过好像STL是有这样的特性的。
我在构造函数里面外加了1000个循环造成延迟,结果也是一样错的。

我用数组试下。

谢谢ltc_mouse
ltc_mouse 2008-02-23
  • 打赏
  • 举报
回复
跟踪了下,构造函数只执行了一遍。是否因为vector对其他元素,直接复制数据,不调用构造函数?不熟悉stl,呵呵...
HelloDan 2008-02-23
  • 打赏
  • 举报
回复
我的循环的意思是,每构造一个genetype这15个tmp是与前一个genetype的15个是相同的。
如果说是时间太短为什么我在8楼时改成了2个却符合我的要求呢?
ltc_mouse 2008-02-23
  • 打赏
  • 举报
回复
tmp是不固定的,但是好像是每15次就循环回以前的值啊。这样就次次都相同的。

--------------------
tmp=rand()%bits;
bits在你的代码中是15,不知道你说的循环是怎样的概念?tmp的取值只在0~14之间;但rand的周期肯定不只15,不应该出现15个数值后马上重复整个序列~ (如果构造中有srand,很可能每15个循环一次,两次srand之间的间隔太短,time的值一样)
HelloDan 2008-02-23
  • 打赏
  • 举报
回复
可能大家是没有试过的。我这果贴出我运行的一个结果吧。
为什么我像1楼那样的main()会出现下面这样的结果,全部分是相同的:

Probability of mutation: 0.15
Probability of crossover:0.8

Relative fitness: 0.8
cumulative fitness:0.8
Best fitness:1794.9
Gene type: 100011000011101
Ruler: 0.00485147

Probability of mutation: 0.15
Probability of crossover:0.8

Relative fitness: 0.8
cumulative fitness:0.8
Best fitness:1794.9
Gene type: 100011000011101
Ruler: 0.00485147

Probability of mutation: 0.15
Probability of crossover:0.8

Relative fitness: 0.8
cumulative fitness:0.8
Best fitness:1794.9
Gene type: 100011000011101
Ruler: 0.00485147

Probability of mutation: 0.15
Probability of crossover:0.8

Relative fitness: 0.8
cumulative fitness:0.8
Best fitness:1794.9
Gene type: 100011000011101
Ruler: 0.00485147

Probability of mutation: 0.15
Probability of crossover:0.8

Relative fitness: 0.8
cumulative fitness:0.8
Best fitness:1794.9
Gene type: 100011000011101
Ruler: 0.00485147

Probability of mutation: 0.15
Probability of crossover:0.8

Relative fitness: 0.8
cumulative fitness:0.8
Best fitness:1794.9
Gene type: 100011000011101
Ruler: 0.00485147

Probability of mutation: 0.15
Probability of crossover:0.8

Relative fitness: 0.8
cumulative fitness:0.8
Best fitness:1794.9
Gene type: 100011000011101
Ruler: 0.00485147

Probability of mutation: 0.15
Probability of crossover:0.8

Relative fitness: 0.8
cumulative fitness:0.8
Best fitness:1794.9
Gene type: 100011000011101
Ruler: 0.00485147

Probability of mutation: 0.15
Probability of crossover:0.8

Relative fitness: 0.8
cumulative fitness:0.8
Best fitness:1794.9
Gene type: 100011000011101
Ruler: 0.00485147

Probability of mutation: 0.15
Probability of crossover:0.8

Relative fitness: 0.8
cumulative fitness:0.8
Best fitness:1794.9
Gene type: 100011000011101
Ruler: 0.00485147
Press any key to continue . . .


而像8楼那样的main()却是不同的。 谢谢
HelloDan 2008-02-23
  • 打赏
  • 举报
回复
注释掉构造函数里的srand也是不行的。

我就是因为不行才在构造函数里的加srand的,当然也不行,在简化代码贴出来时忘了去掉了。

请问这到底是怎样的?谢谢!!!
独孤过儿 2008-02-23
  • 打赏
  • 举报
回复
srand()只需要出现一次就行了
itegel84 2008-02-23
  • 打赏
  • 举报
回复
注释掉构造函数里的srand不就可以了吗?
以前碰到过这种问题。楼上说得都对。
jixingzhong 2008-02-23
  • 打赏
  • 举报
回复
事实上,在楼主你的代码中, main 中的srand是无效的,因为生成对象的时候你重新 srand 了

1 去掉main中的 srand
2 类中的 srand((unsigned)time(NULL)); 前面增加一些时间延迟,比如sleep/delay 之类的

或者,
去掉 class 中的srand,只在main中srand一次即可
jixingzhong 2008-02-23
  • 打赏
  • 举报
回复
请确保 srand 调用参数(种子)是不重复的
HelloDan 2008-02-23
  • 打赏
  • 举报
回复

int main()
{
srand((unsigned)time(NULL)); // seed for rand
genetype a;
genetype b;
display(a);
display(b);


system("pause");
return 0;
}
//如果将main函数改成这样是不同的。是不是一经调用,在同一个函数里面,里面的时间种子就是一样的???
HelloDan 2008-02-23
  • 打赏
  • 举报
回复
回3楼的,tmp是不固定的,但是好像是每15次就循环回以前的值啊。这样就次次都相同的。

这是怎么回事啊?

谢谢回复!!!
HelloDan 2008-02-23
  • 打赏
  • 举报
回复
好像我是在构造函数里面没有时也不对我才移进去的,当然移进去也不对。
HelloDan 2008-02-23
  • 打赏
  • 举报
回复
好像我是在构造函数里面没有时也不错我才移进去的,当然移进去也不对。
arong1234 2008-02-23
  • 打赏
  • 举报
回复

srand那行代码移动到main函数后第一行即可


原因:srand用于设置种子,当其参数不变时,其中自补变,随即序列一样

如果你在很短时间内多次调用,time(NULL)的值不变,等于每次都冲头来,当然就不对了
ltc_mouse 2008-02-23
  • 打赏
  • 举报
回复
Dev C++,试运行了下,构造函数中得到的tmp不是固定值呀~
一般情况下,srand是只要调用一次;即构造函数中的srand调用可以去掉
HelloDan 2008-02-22
  • 打赏
  • 举报
回复
好像我试过不行,不过如果你试过行了就麻烦帮我贴出来给我。 谢谢回复。
飘飘白云 2008-02-22
  • 打赏
  • 举报
回复
srand((unsigned)time(NULL));

只需要设定一次就可以了,一般习惯取当前时间做种子
在genetype的构造函数里提供一个参数入口,将外部产生的随机数传进去~

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧