C++实现遗传算法

C++实现遗传算法,第1张

概述本文实例讲述了C++实现简单遗传算法。分享给大家供大家参考。具体实现方法如下:

本文实例讲述了C++实现简单遗传算法。分享给大家供大家参考。具体实现方法如下:

// CMVSOGA.h : main header file for the CMVSOGA.cpp//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #if !defined(AFX_CMVSOGA_H__45BECA_61EB_4A0E_9746_9A94D1CCF767__INCLUDED_)#define AFX_CMVSOGA_H__45BECA_61EB_4A0E_9746_9A94D1CCF767__INCLUDED_ #if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#include "Afxtempl.h"#define variablenum 14class CMVSOGA{public: CMVSOGA(); ~CMVSOGA(); voID selectionoperator(); voID crossoveroperator(); voID mutationoperator(); voID initialpopulation(int,int,double,double *,double *);      //种群初始化 voID generatenextpopulation();     //生成下一代种群 voID evaluatepopulation();      //评价个体,求最佳个体 voID calculateobjectvalue();     //计算目标函数值 voID calculatefitnessvalue();     //计算适应度函数值 voID findbestanDWorstindivIDual();     //寻找最佳个体和最差个体 voID performevolution();   voID GetResult(double *); voID GetPopData(CList <double,double>&); voID SetfitnessData(CList <double,double>&,CList <double,double>&);private: struct indivIDual { double chromosome[variablenum];     //染色体编码长度应该为变量的个数 double value;      double fitness;       //适应度 }; double variabletop[variablenum];     //变量值 double variablebottom[variablenum];     //变量值 int popsize;       //种群大小// int generation;       //世代数 int best_index;  int worst_index; double crossoverrate;      //交叉率 double mutationrate;      //变异率 int maxgeneration;       //最大世代数 struct indivIDual bestindivIDual;     //最佳个体 struct indivIDual worstindivIDual;     //最差个体 struct indivIDual current;       //当前个体 struct indivIDual current1;       //当前个体 struct indivIDual currentbest;     //当前最佳个体 CList <struct indivIDual,struct indivIDual &> population;  //种群 CList <struct indivIDual,struct indivIDual &> newpopulation; //新种群 CList <double,double> cfitness;     //存储适应度值 //怎样使链表的数据是一个结构体????主要是想把种群作成链表。节省空间。};#endif   执行文件: // CMVSOGA.cpp : implementation file// #include "stdafx.h"//#include "vld.h"#include "CMVSOGA.h"#include "math.h"#include "stdlib.h"  #ifdef _DEBUG#define new DEBUG_NEW#undef THIS_filestatic char THIS_file[] = __file__;#endif/////////////////////////////////////////////////////////////////////////////// CMVSOGA.cppCMVSOGA::CMVSOGA(){ best_index=0;  worst_index=0; crossoverrate=0;      //交叉率 mutationrate=0;      //变异率 maxgeneration=0;}CMVSOGA::~CMVSOGA(){ best_index=0;  worst_index=0; crossoverrate=0;      //交叉率 mutationrate=0;      //变异率 maxgeneration=0; population.RemoveAll();  //种群 newpopulation.RemoveAll(); //新种群 cfitness.RemoveAll(); }voID CMVSOGA::initialpopulation(int ps,int gen,double cr,double mr,double *xtop,double *xbottom) //第一步,初始化。{ //应该采用一定的策略来保证遗传算法的初始化合理,采用产生正态分布随机数初始化?选定中心点为多少? int i,j; popsize=ps; maxgeneration=gen; crossoverrate=cr; mutationrate =mr; for (i=0;i<variablenum;i++) { variabletop[i] =xtop[i]; variablebottom[i] =xbottom[i]; } //srand( (unsigned)time( NulL ) ); //寻找一个真正的随机数生成函数。 for(i=0;i<popsize;i++) {  for (j=0;j<variablenum ;j++) {  current.chromosome[j]=double(rand()%10000)/10000*(variabletop[j]-variablebottom[j])+variablebottom[j]; } current.fitness=0; current.value=0; population.InsertAfter(population.Findindex(i),current);//除了初始化使用insertafter外,其他的用setat命令。 }}voID CMVSOGA::generatenextpopulation()//第三步,生成下一代。{ //srand( (unsigned)time( NulL ) ); selectionoperator(); crossoveroperator(); mutationoperator();}//voID CMVSOGA::evaluatepopulation()  //第二步,评价个体,求最佳个体//{// calculateobjectvalue();// calculatefitnessvalue();  //在此步中因该按适应度值进行排序.链表的排序.// findbestanDWorstindivIDual();//}voID CMVSOGA:: calculateobjectvalue() //计算函数值,应该由外部函数实现。主要因为目标函数很复杂。{ int i,j;  double x[variablenum]; for (i=0; i<popsize; i++) { current=population.GetAt(population.Findindex(i));  current.value=0; //使用外部函数进行,在此只做结果的传递。 for (j=0;j<variablenum;j++) {  x[j]=current.chromosome[j];  current.value=current.value+(j+1)*pow(x[j],4); } ////使用外部函数进行,在此只做结果的传递。 population.SetAt(population.Findindex(i),current); }} voID CMVSOGA::mutationoperator() //对于浮点数编码,变异算子的选择具有决定意义。     //需要guass正态分布函数,生成方差为sigma,均值为浮点数编码值c。{// srand((unsigned int) time (NulL)); int i,j; double r1,r2,p,sigma;//sigma高斯变异参数  for (i=0;i<popsize;i++) { current=population.GetAt(population.Findindex(i));  //生成均值为current.chromosome,方差为sigma的高斯分布数 for(j=0; j<variablenum; j++) {    r1 = double(rand()%10001)/10000;  r2 = double(rand()%10001)/10000;  p = double(rand()%10000)/10000;  if(p<mutationrate)  {  double sign;  sign=rand()%2;  sigma=0.01*(variabletop[j]-variablebottom [j]);  //高斯变异  if(sign)  {   current.chromosome[j] = (current.chromosome[j]    + sigma*sqrt(-2*log(r1)/0.4323)*sin(2*3.1415926*r2));  }  else  {   current.chromosome[j] = (current.chromosome[j]    - sigma*sqrt(-2*log(r1)/0.4323)*sin(2*3.1415926*r2));  }  if (current.chromosome[j]>variabletop[j])  {   current.chromosome[j]=double(rand()%10000)/10000*(variabletop[j]-variablebottom[j])+variablebottom[j];  }  if (current.chromosome[j]<variablebottom [j])  {   current.chromosome[j]=double(rand()%10000)/10000*(variabletop[j]-variablebottom[j])+variablebottom[j];  }  } } population.SetAt(population.Findindex(i),current); }}voID CMVSOGA::selectionoperator()  //从当前个体中按概率选择新种群,应该加一个复制选择,提高种群的平均适应度{ int i,j,pindex=0; double p,pc,sum; i=0; j=0; pindex=0; p=0; pc=0; sum=0.001; newpopulation.RemoveAll(); cfitness.RemoveAll(); //链表排序// population.SetAt (population.Findindex(0),current); //多余代码 for (i=1;i<popsize;i++) {  current=population.GetAt(population.Findindex(i)); for(j=0;j<i;j++)  //从小到大用before排列。 {  current1=population.GetAt(population.Findindex(j));//临时借用变量  if(current.fitness<=current1.fitness)   {  population.InsertBefore(population.Findindex(j),current);  population.RemoveAt(population.Findindex(i+1));  break;  } }// m=population.GetCount(); } //链表排序 for(i=0;i<popsize;i++)//求适应度总值,以便归一化,是已经排序好的链。 { current=population.GetAt(population.Findindex(i)); //取出来的值出现问题. sum+=current.fitness; } for(i=0;i<popsize; i++)//归一化 { current=population.GetAt(population.Findindex(i)); //population 有值,为什么取出来的不正确呢?? current.fitness=current.fitness/sum; cfitness.InsertAfter (cfitness .Findindex(i),current.fitness); }  for(i=1;i<popsize; i++)//概率值从小到大; { current.fitness=cfitness.GetAt (cfitness.Findindex(i-1))  +cfitness.GetAt(cfitness.Findindex(i));  //归一化 cfitness.SetAt (cfitness .Findindex(i),current.fitness); population.SetAt(population.Findindex(i),current); } for (i=0;i<popsize;)//轮盘赌概率选择。本段还有问题。 { p=double(rand()%999)/1000+0.0001; //随机生成概率 pindex=0; //遍历索引 pc=cfitness.GetAt(cfitness.Findindex(1)); //为什么取不到数值???20060910 while(p>=pc&&pindex<popsize) //问题所在。 {  pc=cfitness.GetAt(cfitness .Findindex(pindex));  pindex++; } //必须是从index~popsize,选择高概率的数。即大于概率p的数应该被选择,选择不满则进行下次选择。 for (j=popsize-1;j<pindex&&i<popsize;j--) {  newpopulation.InsertAfter (newpopulation.Findindex(0),population.GetAt (population.Findindex(j)));  i++; } } for(i=0;i<popsize; i++) { population.SetAt (population.Findindex(i),newpopulation.GetAt (newpopulation.Findindex(i))); }// j=newpopulation.GetCount();// j=population.GetCount(); newpopulation.RemoveAll();} //current  变化后,以上没有问题了。  voID CMVSOGA:: crossoveroperator()  //非均匀算术线性交叉,浮点数适用,Alpha,beta是(0,1)之间的随机数     //对种群中两两交叉的个体选择也是随机选择的。也可取beta=1-Alpha;     //current的变化会有一些改变。{ int i,j; double Alpha,beta; CList <int,int> index; int point,temp; double p;// srand( (unsigned)time( NulL ) ); for (i=0;i<popsize;i++)//生成序号 { index.InsertAfter (index.Findindex(i),i); } for (i=0;i<popsize;i++)//打乱序号 { point=rand()%(popsize-1); temp=index.GetAt(index.Findindex(i)); index.SetAt(index.Findindex(i),index.GetAt(index.Findindex(point)));  index.SetAt(index.Findindex(point),temp); } for (i=0;i<popsize-1;i+=2) {//按顺序序号,按序号选择两个母体进行交叉 *** 作。 p=double(rand()%10000)/10000.0; if (p<crossoverrate) {    Alpha=double(rand()%10000)/10000.0;  beta=double(rand()%10000)/10000.0;  current=population.GetAt(population.Findindex(index.GetAt(index.Findindex(i))));  current1=population.GetAt(population.Findindex(index.GetAt(index.Findindex(i+1))));//临时使用current1代替  for(j=0;j<variablenum;j++)  {   //交叉  double sign;  sign=rand()%2;  if(sign)  {   current.chromosome[j]=(1-Alpha)*current.chromosome[j]+   beta*current1.chromosome[j];  }  else  {   current.chromosome[j]=(1-Alpha)*current.chromosome[j]-   beta*current1.chromosome[j];  }  if (current.chromosome[j]>variabletop[j]) //判断是否超界.  {   current.chromosome[j]=double(rand()%10000)/10000*(variabletop[j]-variablebottom[j])+variablebottom[j];  }  if (current.chromosome[j]<variablebottom [j])  {   current.chromosome[j]=double(rand()%10000)/10000*(variabletop[j]-variablebottom[j])+variablebottom[j];  }  if(sign)  {   current1.chromosome[j]=Alpha*current.chromosome[j]+   (1- beta)*current1.chromosome[j];  }  else  {   current1.chromosome[j]=Alpha*current.chromosome[j]-   (1- beta)*current1.chromosome[j];  }  if (current1.chromosome[j]>variabletop[j])  {   current1.chromosome[j]=double(rand()%10000)/10000*(variabletop[j]-variablebottom[j])+variablebottom[j];  }  if (current1.chromosome[j]<variablebottom [j])  {   current1.chromosome[j]=double(rand()%10000)/10000*(variabletop[j]-variablebottom[j])+variablebottom[j];  }  }  //回代 } newpopulation.InsertAfter (newpopulation.Findindex(i),current); newpopulation.InsertAfter (newpopulation.Findindex(i),current1); } ASSERT(newpopulation.GetCount()==popsize); for (i=0;i<popsize;i++) { population.SetAt (population.Findindex(i),newpopulation.GetAt (newpopulation.Findindex(i))); } newpopulation.RemoveAll(); index.RemoveAll();}voID CMVSOGA:: findbestanDWorstindivIDual( ) { int i; bestindivIDual=population.GetAt(population.Findindex(best_index)); worstindivIDual=population.GetAt(population.Findindex(worst_index)); for (i=1;i<popsize; i++) { current=population.GetAt(population.Findindex(i)); if (current.fitness>bestindivIDual.fitness) {  bestindivIDual=current;  best_index=i; } else if (current.fitness<worstindivIDual.fitness) {  worstindivIDual=current;  worst_index=i; } } population.SetAt(population.Findindex(worst_index),population.GetAt(population.Findindex(best_index))); //用最好的替代最差的。 if (maxgeneration==0) { currentbest=bestindivIDual; } else { if(bestindivIDual.fitness>=currentbest.fitness) {  currentbest=bestindivIDual; } }}voID CMVSOGA:: calculatefitnessvalue() //适应度函数值计算,关键是适应度函数的设计     //current变化,这段程序变化较大,特别是排序。{ int i; double temp;//Alpha,beta;//适应度函数的尺度变化系数 double cmax=100; for(i=0;i<popsize;i++) { current=population.GetAt(population.Findindex(i)); if(current.value<cmax) {  temp=cmax-current.value; } else {  temp=0.0; } /* if((population[i].value+cmin)>0.0) {temp=cmin+population[i].value;} else {temp=0.0;  } */ current.fitness=temp; population.SetAt(population.Findindex(i),current);  }}voID CMVSOGA:: performevolution() //演示评价结果,有冗余代码,current变化,程序应该改变较大{ if (bestindivIDual.fitness>currentbest.fitness) { currentbest=population.GetAt(population.Findindex(best_index)); } else { population.SetAt(population.Findindex(worst_index),currentbest); }}voID CMVSOGA::GetResult(double *Result){ int i; for (i=0;i<variablenum;i++) { Result[i]=currentbest.chromosome[i]; } Result[i]=currentbest.value;} voID CMVSOGA::GetPopData(CList <double,double>&PopData) { PopData.RemoveAll(); int i,j; for (i=0;i<popsize;i++) { current=population.GetAt(population.Findindex(i)); for (j=0;j<variablenum;j++) {  PopData.AddTail(current.chromosome[j]); } }}voID CMVSOGA::SetfitnessData(CList <double,double>&PopData,double>&fitnessData,double>&ValueData){ int i,j; for (i=0;i<popsize;i++) {  current=population.GetAt(population.Findindex(i)); //就因为这一句,出现了很大的问题。  for (j=0;j<variablenum;j++) {  current.chromosome[j]=PopData.GetAt(PopData.Findindex(i*variablenum+j)); } current.fitness=fitnessData.GetAt(fitnessData.Findindex(i)); current.value=ValueData.GetAt(ValueData.Findindex(i)); population.SetAt(population.Findindex(i),current); } fitnessData.RemoveAll(); PopData.RemoveAll(); ValueData.RemoveAll();} # re: C++遗传算法源程序/********************************************************************filename: aiWorld.hPurpose: 遗传算法,花朵演化。ID:copyright:licence:*********************************************************************/#ifndef AIWORLD_H_#define AIWORLD_H_ #include <iostream>#include <ctime>#include <cstdlib>#include <cmath> #define kMaxFlowers 10 using std::cout;using std::endl; class ai_World{public:ai_World(){srand(time(0));}~ai_World() {} int temperature[kMaxFlowers]; //温度int water[kMaxFlowers]; //水质int sunlight[kMaxFlowers]; //阳光int nutrIEnt[kMaxFlowers]; //养分int beneficialinsect[kMaxFlowers]; //益虫int harmfulinsect[kMaxFlowers]; //害虫 int currentTemperature;int currentWater;int currentSunlight;int currentNutrIEnt;int currentBeneficialinsect;int currentHarmfulinsect; /**第一代花朵*/voID Encode(); /**花朵适合函数*/int fitness(int flower); /**花朵演化*/voID Evolve(); /**返回区间[start,end]的随机数*/inline int tb_Rnd(int start,int end){if (start > end)return 0;else{//srand(time(0));return (rand() % (end + 1) + start);}} /**显示数值*/voID show();};// ----------------------------------------------------------------- //voID ai_World::Encode()// ----------------------------------------------------------------- // {int i; for (i=0;i<kMaxFlowers;i++){temperature[i]=tb_Rnd(1,75);water[i]=tb_Rnd(1,75);sunlight[i]=tb_Rnd(1,75);nutrIEnt[i]=tb_Rnd(1,75);beneficialinsect[i]=tb_Rnd(1,75);harmfulinsect[i]=tb_Rnd(1,75);} currentTemperature=tb_Rnd(1,75);currentWater=tb_Rnd(1,75);currentSunlight=tb_Rnd(1,75);currentNutrIEnt=tb_Rnd(1,75);currentBeneficialinsect=tb_Rnd(1,75);currentHarmfulinsect=tb_Rnd(1,75); currentTemperature=tb_Rnd(1,75); }// ----------------------------------------------------------------- //int ai_World::fitness(int flower)// ----------------------------------------------------------------- // {int thefitness;  thefitness=abs(temperature[flower]-currentTemperature);thefitness=thefitness+abs(water[flower]-currentWater);thefitness=thefitness+abs(sunlight[flower]-currentSunlight);thefitness=thefitness+abs(nutrIEnt[flower]-currentNutrIEnt);thefitness=thefitness+abs(beneficialinsect[flower]-currentBeneficialinsect);thefitness=thefitness+abs(harmfulinsect[flower]-currentHarmfulinsect); return (thefitness); }// ----------------------------------------------------------------- //voID ai_World::Evolve()// ----------------------------------------------------------------- // {int fitTemperature[kMaxFlowers];int fitWater[kMaxFlowers];int fitSunlight[kMaxFlowers];int fitNutrIEnt[kMaxFlowers];int fitBeneficialinsect[kMaxFlowers];int fitHarmfulinsect[kMaxFlowers];int fitness[kMaxFlowers];int i;int leastFit=0;int leastFitIndex; for (i=0;i<kMaxFlowers;i++)if (fitness(i)>leastFit){leastFit=fitness(i);leastFitIndex=i;} temperature[leastFitIndex]=temperature[tb_Rnd(0,kMaxFlowers - 1)];water[leastFitIndex]=water[tb_Rnd(0,kMaxFlowers - 1)];sunlight[leastFitIndex]=sunlight[tb_Rnd(0,kMaxFlowers - 1)];nutrIEnt[leastFitIndex]=nutrIEnt[tb_Rnd(0,kMaxFlowers - 1)];beneficialinsect[leastFitIndex]=beneficialinsect[tb_Rnd(0,kMaxFlowers - 1)];harmfulinsect[leastFitIndex]=harmfulinsect[tb_Rnd(0,kMaxFlowers - 1)]; for (i=0;i<kMaxFlowers;i++){fitTemperature[i]=temperature[tb_Rnd(0,kMaxFlowers - 1)];fitWater[i]=water[tb_Rnd(0,kMaxFlowers - 1)];fitSunlight[i]=sunlight[tb_Rnd(0,kMaxFlowers - 1)];fitNutrIEnt[i]=nutrIEnt[tb_Rnd(0,kMaxFlowers - 1)];fitBeneficialinsect[i]=beneficialinsect[tb_Rnd(0,kMaxFlowers - 1)];fitHarmfulinsect[i]=harmfulinsect[tb_Rnd(0,kMaxFlowers - 1)];} for (i=0;i<kMaxFlowers;i++){temperature[i]=fitTemperature[i];water[i]=fitWater[i];sunlight[i]=fitSunlight[i];nutrIEnt[i]=fitNutrIEnt[i];beneficialinsect[i]=fitBeneficialinsect[i];harmfulinsect[i]=fitHarmfulinsect[i];} for (i=0;i<kMaxFlowers;i++){if (tb_Rnd(1,100)==1)temperature[i]=tb_Rnd(1,75);if (tb_Rnd(1,100)==1)water[i]=tb_Rnd(1,100)==1)sunlight[i]=tb_Rnd(1,100)==1)nutrIEnt[i]=tb_Rnd(1,100)==1)beneficialinsect[i]=tb_Rnd(1,100)==1)harmfulinsect[i]=tb_Rnd(1,75);} }voID ai_World::show(){// cout << "/t temperature water sunlight nutrIEnt beneficialinsect harmfulinsect/n";cout << "current/t " << currentTemperature << "/t " << currentWater << "/t ";cout << currentSunlight << "/t " << currentNutrIEnt << "/t ";cout << currentBeneficialinsect << "/t " << currentHarmfulinsect << "/n";for (int i=0;i<kMaxFlowers;i++){cout << "Flower " << i << ": ";cout << temperature[i] << "/t ";cout << water[i] << "/t ";cout << sunlight[i] << "/t ";cout << nutrIEnt[i] << "/t ";cout << beneficialinsect[i] << "/t ";cout << harmfulinsect[i] << "/t ";cout << endl;}}#endif // AIWORLD_H_ //test.cpp#include <iostream>#include "ai_World.h" using namespace std; int main(){ai_World a;a.Encode();// a.show();for (int i = 0; i < 10; i++){cout << "Generation " << i << endl;a.Evolve();a.show();} system("PAUSE");return 0;}

希望本文所述对大家的C++程序设计有所帮助。

总结

以上是内存溢出为你收集整理的C++实现遗传算法全部内容,希望文章能够帮你解决C++实现遗传算法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1249825.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存