C++遗传算法类文件实例分析
本文所述为C++实现的遗传算法的类文件实例。一般来说遗传算法可以解决许多问题,希望本文所述的C++遗传算法类文件,可帮助你解决更多问题,并且代码中为了便于读者更好的理解,而加入了丰富的注释内容,是新手学习遗传算法不可多得的参考代码。
具体代码如下所示:
#include"stdafx.h"
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>//把日期和时间转换为字符串
usingnamespacestd;
//Parametessetting
#definePOPSIZE200//populationsize
#defineMAXGENS1000//maxnumberofgeneration
#defineNVARS2//noofproblemvariables
#definePXOVER0.75//probalilityofcrossover
#definePMUTATION0.15//probalilityofmutation
#defineTRUE1
#defineFALSE0
#defineLBOUND0
#defineUBOUND12
#defineSTOP0.001
intgeneration;//currentgenerationno
intcur_best;//bestindividual
doublediff;
FILE*galog;//anoutputfile
structgenotype
{
doublegene[NVARS];//astringofvariables基因变量
doubleupper[NVARS];//individual'svariablesupperbound基因变量取值上确界
doublelower[NVARS];//individual'sbatiableslowerbound基因变量取值下确界
doublefitness;//individual'sfitness个体适应值
doublerfitness;//relativefitness个体适应值占种群适应值比例
doublecfitness;//curmulationfitness个体适应值的累加比例
};
structgenotypepopulation[POPSIZE+1];
//population当前种群population[POPSIZE]用于存放个体最优值并假设最优个体能存活下去
//在某些遗传算法中最优值个体并不一定能够存活下去
structgenotypenewpopulation[POPSIZE+1];//newpopulationreplacestheoldgeneration子种群
/*Declarationofproceduresusedbythegenticalgorithm*/
voidinitialize(void);//初始化函数
doublerandval(double,double);//随机函数
doublefuntion(doublex1,doublex2);//目标函数
voidevaluate(void);//评价函数
voidkeep_the_best(void);//保留最优个体
voidelitist(void);//当前种群与子代种群最优值比较
voidselect(void);
voidcrossover(void);//基因重组函数
voidswap(double*,double*);//交换函数
voidmutate(void);//基因突变函数
doublereport(void);//数据记录函数
voidinitialize(void)
{
inti,j;
for(i=0;i<NVARS;i++)
{
for(j=0;j<POPSIZE+1;j++)
{
if(!i)
{
population[j].fitness=0;
population[j].rfitness=0;
population[j].cfitness=0;
}
population[j].lower[i]=LBOUND;
population[j].upper[i]=UBOUND;
population[j].gene[i]=randval(population[j].lower[i],population[j].upper[i]);
}
}
}
//***************************************************************************
//Randomvaluegenerator:generatesavaluewithinbounds
//***************************************************************************
doublerandval(doublelow,doublehigh)
{
doubleval;
val=((double)(rand()%10000)/10000)*(high-low)+low;
returnval;
}
//目标函数
doublefuntion(doublex,doubley)
{
doubleresult1=sqrt(x*x+y*y)+sqrt((x-12)*(x-12)+y*y)+sqrt((x-8)*(x-8)+(y-6)*(y-6));
returnresult1;
}
//***************************************************************************
//Evaluationfunction:evaluatetheindividual'sfitness.评价函数给出个体适应值
//Eachtimethefunctionischanges,thecodehastoberecompl
//***************************************************************************
voidevaluate(void)
{
intmem;
inti;
doublex[NVARS];
for(mem=0;mem<POPSIZE;mem++)
{
for(i=0;i<NVARS;i++)
x[i]=population[mem].gene[i];
population[mem].fitness=funtion(x[0],x[1]);//将目标函数值作为适应值
}
}
//***************************************************************************************
//Keep_the_bestfunction:Thisfunctionkeepstrackofthebestmemberofthepopulation.
//找出种群中的个体最优值并将其移动到最后
//***************************************************************************************
voidkeep_the_best()
{
intmem;
inti;
cur_best=0;
for(mem=0;mem<POPSIZE;mem++)//找出最高适应值个体
{
if(population[mem].fitness<population[cur_best].fitness)
{
cur_best=mem;
}
}
//将最优个体复制至population[POSIZE]
if(population[cur_best].fitness<=population[POPSIZE].fitness||population[POPSIZE].fitness<1)//防止出现种群基因退化故保留历史最优个体
{
population[POPSIZE].fitness=population[cur_best].fitness;
for(i=0;i<NVARS;i++)
population[POPSIZE].gene[i]=population[cur_best].gene[i];
}
}
//***************************************************************************
//lastinthearray.Ifthebestindividualfromthenewpopulatinisbetter
//thanthebestindividualfromthepreviouspopulation,thencopythebest
//fromthenewpopulation;elsereplacetheworstindividualfromthecurrent
//populationwiththebestonefromthepreviousgeneration.防止种群最优值退化
//***************************************************************************
voidelitist()
{
inti;
doublebest,worst;//适应值
intbest_mem,worst_mem;//序号
best_mem=worst_mem=0;
best=population[best_mem].fitness;//最高适应值初始化
worst=population[worst_mem].fitness;//最低适应值初始化
for(i=1;i<POPSIZE;i++)//找出最高和最低适应值算法有待改进
{
if(population[i].fitness<best)
{
best=population[i].fitness;
best_mem=i;
}
if(population[i].fitness>worst)
{
worst=population[i].fitness;
worst_mem=i;
}
}
if(best<=population[POPSIZE].fitness)//赋值
{
for(i=0;i<NVARS;i++)
population[POPSIZE].gene[i]=population[best_mem].gene[i];
population[POPSIZE].fitness=population[best_mem].fitness;
}
else
{
for(i=0;i<NVARS;i++)
population[worst_mem].gene[i]=population[POPSIZE].gene[i];
population[worst_mem].fitness=population[POPSIZE].fitness;
}
}
//***************************************************************************
//Selectfunction:Standardproportionalselectionformaximizationproblems
//incorporatingelitistmodel--makessurethatthebestmembersurvives.筛选函数并产生子代
//***************************************************************************
voidselect(void)
{
intmem,i,j;
doublesum=0;
doublep;
for(mem=0;mem<POPSIZE;mem++)//所有适应值求和
{
sum+=population[mem].fitness;
}
for(mem=0;mem<POPSIZE;mem++)
{
population[mem].rfitness=population[mem].fitness/sum;//个人认为还不如建一个种群类把sum看成类成员
}
population[0].cfitness=population[0].rfitness;
for(mem=1;mem<POPSIZE;mem++)
{
population[mem].cfitness=population[mem-1].cfitness+population[mem].rfitness;
}
for(i=0;i<POPSIZE;i++)
{
p=rand()%1000/1000.0;
if(p<population[0].cfitness)
{
newpopulation[i]=population[0];
}
else
{
for(j=0;j<POPSIZE;j++)
if(p>=population[j].cfitness&&p<population[j+1].cfitness)
newpopulation[i]=population[j+1];
}
}
for(i=0;i<POPSIZE;i++)//子代变父代
population[i]=newpopulation[i];
}
//***************************************************************************
//Crossover:performscrossoveroftheselectedparents.
//***************************************************************************
voidXover(intone,inttwo)//基因重组函数
{
inti;
intpoint;
if(NVARS>1)
{
if(NVARS==2)
point=1;
else
point=(rand()%(NVARS-1))+1;//两个都重组吗?
for(i=0;i<point;i++)//只有第一个基因发生重组有待改进
swap(&population[one].gene[i],&population[two].gene[i]);
}
}
//***************************************************************************
//Swapp:aswapprocedurethehelpsinswappling2variables
//***************************************************************************
voidswap(double*x,double*y)
{
doubletemp;
temp=*x;
*x=*y;
*y=temp;
}
//***************************************************************************
//Crossoverfunction:selecttwoparentsthattakepartinthecrossover.
//Implementsasinglepointcorssover.杂交函数
//***************************************************************************
voidcrossover(void)
{
intmem,one;
intfirst=0;
doublex;
for(mem=0;mem<POPSIZE;++mem)
{
x=rand()%1000/1000.0;
if(x<PXOVER)
{
++first;
if(first%2==0)//选择杂交的个体对杂交有待改进事实上往往是强者与强者杂交这里没有考虑雌雄与杂交对象的选择
Xover(one,mem);
else
one=mem;
}
}
}
//***************************************************************************
//Mutationfunction:Randomuniformmutation.avariableselectedformutation
//变异函数事实基因的变异往往具有某种局部性
//isreplacedbyarandomvaluebetweenlowerandupperboundsofthevariables.
//***************************************************************************
voidmutate(void)
{
inti,j;
doublelbound,hbound;
doublex;
for(i=0;i<POPSIZE;i++)
for(j=0;j<NVARS;j++)
{
x=rand()%1000/1000.0;
if(x<PMUTATION)
{
lbound=population[i].lower[j];
hbound=population[i].upper[j];
population[i].gene[j]=randval(lbound,hbound);
}
}
}
//***************************************************************************
//Reportfunction:Reportsprogressofthesimulation.
//***************************************************************************
doublereport(void)
{
inti;
doublebest_val;//种群内最优适应值
doubleavg;//平均个体适应值
//doublestddev;
doublesum_square;//种群内个体适应值平方和
//doublesquare_sum;
doublesum;//种群适应值
sum=0.0;
sum_square=0.0;
for(i=0;i<POPSIZE;i++)
{
sum+=population[i].fitness;
sum_square+=population[i].fitness*population[i].fitness;
}
avg=sum/(double)POPSIZE;
//square_sum=avg*avg*(double)POPSIZE;
//stddev=sqrt((sum_square-square_sum)/(POPSIZE-1));
best_val=population[POPSIZE].fitness;
fprintf(galog,"%6d%6.3f%6.3f%6.3f%6.3f%6.3f\n",generation,best_val,population[POPSIZE].gene[0],population[POPSIZE].gene[1],avg,sum);
returnavg;
}
//***************************************************************************
//mainfunction:Eachgenerationinvolvesselectingthebestmembers,performing
//crossover&mutationandthenevaluatingtheresultingpopulation,untilthe
//terminatingconditionissatisfied.
//***************************************************************************
voidmain(void)
{
inti;
doubletemp;
doubletemp1;
if((galog=fopen("data.txt","w"))==NULL)
{
exit(1);
}
generation=1;
srand(time(NULL));//产生随机数
fprintf(galog,"numbervaluex1x2avgsum_value\n");
printf("generationbestaveragestandard\n");
initialize();
evaluate();
keep_the_best();
temp=report();//记录,暂存上一代个体平均适应值
do
{
select();//筛选
crossover();//杂交
mutate();//变异
evaluate();//评价
keep_the_best();//elitist();
temp1=report();
diff=fabs(temp-temp1);//求浮点数x的绝对值
temp=temp1;
generation++;
}while(generation<MAXGENS&&diff>=STOP);
//fprintf(galog,"\n\nSimulationcompleted\n");
//fprintf(galog,"\nBestmember:\n");
printf("\nBestmember:\ngeneration:%d\n",generation);
for(i=0;i<NVARS;i++)
{
//fprintf(galog,"\nvar(%d)=%3.3f",i,population[POPSIZE].gene[i]);
printf("X%d=%3.3f\n",i,population[POPSIZE].gene[i]);
}
//fprintf(galog,"\n\nBestfitness=%3.3f",population[POPSIZE].fitness);
fclose(galog);
printf("\nBestfitness=%3.3f\n",population[POPSIZE].fitness);
}
感兴趣的读者可以动手测试一下代码,希望对大家学习C++算法能有所帮助。