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

时间:2022-12-05 19:48:49

//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()出来的数据不是每一个都相同。我在主程序里面有测试。麻烦了!!!  谢谢!!!
//

19 个解决方案

#1


srand((unsigned)time(NULL));

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

#2


好像我试过不行,不过如果你试过行了就麻烦帮我贴出来给我。 谢谢回复。

#3


Dev C++,试运行了下,构造函数中得到的tmp不是固定值呀~
一般情况下,srand是只要调用一次;即构造函数中的srand调用可以去掉

#4


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


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

如果你在很短时间内多次调用,time(NULL)的值不变,等于每次都冲头来,当然就不对了

#5


好像我是在构造函数里面没有时也不错我才移进去的,当然移进去也不对。

#6


好像我是在构造函数里面没有时也不对我才移进去的,当然移进去也不对。

#7


回3楼的,tmp是不固定的,但是好像是每15次就循环回以前的值啊。这样就次次都相同的。

这是怎么回事啊?

谢谢回复!!!

#8



int main()
{
  srand((unsigned)time(NULL));  // seed for rand
  genetype a;
  genetype b;
  display(a);
  display(b);
  
  
  system("pause");
  return 0;
}
//如果将main函数改成这样是不同的。是不是一经调用,在同一个函数里面,里面的时间种子就是一样的???

#9


请确保 srand 调用参数(种子)是不重复的

#10


事实上,在楼主你的代码中, main 中的srand是无效的,因为生成对象的时候你重新 srand 了

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

或者,
去掉 class 中的srand,只在main中srand一次即可

#11


注释掉构造函数里的srand不就可以了吗?
以前碰到过这种问题。楼上说得都对。

#12


srand()只需要出现一次就行了

#13


注释掉构造函数里的srand也是不行的。

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

请问这到底是怎样的?谢谢!!!

#14


可能大家是没有试过的。我这果贴出我运行的一个结果吧。
为什么我像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()却是不同的。  谢谢

#15


tmp是不固定的,但是好像是每15次就循环回以前的值啊。这样就次次都相同的。

--------------------
tmp=rand()%bits;
bits在你的代码中是15,不知道你说的循环是怎样的概念?tmp的取值只在0~14之间;但rand的周期肯定不只15,不应该出现15个数值后马上重复整个序列~ (如果构造中有srand,很可能每15个循环一次,两次srand之间的间隔太短,time的值一样)

#16


我的循环的意思是,每构造一个genetype这15个tmp是与前一个genetype的15个是相同的。
如果说是时间太短为什么我在8楼时改成了2个却符合我的要求呢?

#17


跟踪了下,构造函数只执行了一遍。是否因为vector对其他元素,直接复制数据,不调用构造函数?不熟悉stl,呵呵...

#18


STL我也没有学得太深,可能是这样吧。以前看过好像STL是有这样的特性的。
我在构造函数里面外加了1000个循环造成延迟,结果也是一样错的。

我用数组试下。

谢谢ltc_mouse
    

#19


果然是这样,数组是可以的,但STL的不行。以前看过string类有copy on write的特性,可能vector也是这样的物性吧。

再一次,谢谢ltc_mouse 

#1


srand((unsigned)time(NULL));

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

#2


好像我试过不行,不过如果你试过行了就麻烦帮我贴出来给我。 谢谢回复。

#3


Dev C++,试运行了下,构造函数中得到的tmp不是固定值呀~
一般情况下,srand是只要调用一次;即构造函数中的srand调用可以去掉

#4


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


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

如果你在很短时间内多次调用,time(NULL)的值不变,等于每次都冲头来,当然就不对了

#5


好像我是在构造函数里面没有时也不错我才移进去的,当然移进去也不对。

#6


好像我是在构造函数里面没有时也不对我才移进去的,当然移进去也不对。

#7


回3楼的,tmp是不固定的,但是好像是每15次就循环回以前的值啊。这样就次次都相同的。

这是怎么回事啊?

谢谢回复!!!

#8



int main()
{
  srand((unsigned)time(NULL));  // seed for rand
  genetype a;
  genetype b;
  display(a);
  display(b);
  
  
  system("pause");
  return 0;
}
//如果将main函数改成这样是不同的。是不是一经调用,在同一个函数里面,里面的时间种子就是一样的???

#9


请确保 srand 调用参数(种子)是不重复的

#10


事实上,在楼主你的代码中, main 中的srand是无效的,因为生成对象的时候你重新 srand 了

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

或者,
去掉 class 中的srand,只在main中srand一次即可

#11


注释掉构造函数里的srand不就可以了吗?
以前碰到过这种问题。楼上说得都对。

#12


srand()只需要出现一次就行了

#13


注释掉构造函数里的srand也是不行的。

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

请问这到底是怎样的?谢谢!!!

#14


可能大家是没有试过的。我这果贴出我运行的一个结果吧。
为什么我像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()却是不同的。  谢谢

#15


tmp是不固定的,但是好像是每15次就循环回以前的值啊。这样就次次都相同的。

--------------------
tmp=rand()%bits;
bits在你的代码中是15,不知道你说的循环是怎样的概念?tmp的取值只在0~14之间;但rand的周期肯定不只15,不应该出现15个数值后马上重复整个序列~ (如果构造中有srand,很可能每15个循环一次,两次srand之间的间隔太短,time的值一样)

#16


我的循环的意思是,每构造一个genetype这15个tmp是与前一个genetype的15个是相同的。
如果说是时间太短为什么我在8楼时改成了2个却符合我的要求呢?

#17


跟踪了下,构造函数只执行了一遍。是否因为vector对其他元素,直接复制数据,不调用构造函数?不熟悉stl,呵呵...

#18


STL我也没有学得太深,可能是这样吧。以前看过好像STL是有这样的特性的。
我在构造函数里面外加了1000个循环造成延迟,结果也是一样错的。

我用数组试下。

谢谢ltc_mouse
    

#19


果然是这样,数组是可以的,但STL的不行。以前看过string类有copy on write的特性,可能vector也是这样的物性吧。

再一次,谢谢ltc_mouse 

#20