寻大牛讲解一下遗传算法的源程序
在网上找到一个遗传算法的源代码,想学习一下。遇到一个问题:
在源程序中,有个GT_Corssover(),不明白是什么意思,求大牛讲解一下。
还有,最近在用遗传算法做隐函数的数据拟合程序,有经验的兄弟能给帮下忙吗?
源程序:
/*-------------------------------------------------------------|
|求函数的最大值 : |
| f(x,y)=21.5+x*sin(4*PI*x)+y*sin(20*PI*y) |
| |
| 定义域 D: -3<=x<=12.1 , 4.1<=y<=5.8 |
| 注: 目前最好结果:f(11.6255448,5.7250441)=38.8502944790207 |
|------------------------------------------------------------*/
#include <iostream.h>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <iomanip.h>
using namespace std;
#define PCROSSOVER 0.95 // 交叉概率
//
#define PMUTATION 0.15 // 变异概率
#define POPSIZE 100 // 和数数目
#define MAXGEN 10000 // 世代数目
#define PI 3.14159265 // PI
#define lbound1 -3 // X 上限
#define ubound1 12.1 // X 下限
#define lbound2 4.1 // Y 上限
#define ubound2 5.8 // Y 下限
//double PMUTATION=0.08;
////////////////////////////Individual Structure///////////////////////////
typedef struct Individual
{
double a1; // 改为a1进行尝试
double a2; // 改为a2进行尝试
double fitness;
double rfitness;
double cfitness;
}Individual;
Individual Population[POPSIZE+1];
Individual temp[POPSIZE];//定义一个临时存储空间存储将要放入新群体的个体
double TotalFitness=0.0f;
//int curBest=0;
double lbound[1],ubound[1];
double a;
int curGen=0;
//////////////////////////Function Prototype//////////////////////////////
void Initialize();
void EvaluateFitness();
Individual Roulette();
void Mutate(Individual *indiv);
void Crossover(Individual *dad, Individual *mom);
void GT_Crossover(int m);
int GetWorst(Individual *indiv, int size);
void Elitist();
void Report();
//////////////////////////Main()//////////////////////////////////////
int main()
{
srand((int)time(NULL));
int change=1;
clock_t start, finish;
start=clock();
Initialize();
EvaluateFitness();
while(change&&curGen<MAXGEN)
{
EvaluateFitness();
Individual dad, mom;
int i=0;
while(i<POPSIZE)
{
dad=Roulette();
do{
mom = Roulette();
}while((dad.a1==mom.a1) && (dad.a2==mom.a2));
Crossover(&dad,&mom);
Mutate(&dad);
Mutate(&mom);
temp[i++]=dad;
temp[i++]=mom;
}
GT_Crossover(rand()%3 + 7);
//将后代个体放入新群体中
for (i=0; i<POPSIZE; i++)
Population[i] = temp[i];
EvaluateFitness();
Elitist();
//Report();
// int j; // 暂时没用到的变量
// for(j=1;j<POPSIZE;j++)
// if((Population[j].x1!=Population[j-1].x1)||(Population[j].x2!=Population[j-1].x2)) break;
// if (POPSIZE==j) change=0;
curGen++;
//PMUTATION=PMUTATION-0.008;
}
finish=clock();
cout<<endl;
//for (int i=0;i<POPSIZE;i++)
// cout<<Population[i].fitness<<endl;
printf("%.13f\n",Population[POPSIZE].fitness);
// cout<<"进化"<<curGen<<"代后的最佳适应值为"<<Population[POPSIZE].fitness<<"耗时"<<(double)finish/1000<<"s"<<endl;
// if(getchar()!='\n') ;
return 0;
}//main
//////////////////////////////Function Definition//////////////////////////////////
//--------------------------------- 初始化种群 ------------------------------------------
void Initialize()
{
for(int i = 0; i < POPSIZE; i++)
{
Population[i].a1 = lbound1 + (ubound1-lbound1) * (double)rand() / RAND_MAX; // 改为a1进行尝试
Population[i].a2 = lbound2 + (ubound2-lbound2) * (double)rand() / RAND_MAX; // 改为a2进行尝试
Population[i].fitness = 0.0f;
Population[i].rfitness = 0.0f;
Population[i].cfitness = 0.0f;
}
return;
}
//---------------------------------- 适应度计算 -------------------------------------------
void EvaluateFitness()
{
double x = 0;
TotalFitness = 0;
int i;
// 计算个体的适应值
for (i = 0; i < POPSIZE; i++)
{
double x,y;
x = Population[i].a1; // 改为a1进行尝试
y = Population[i].a2; // 改为a1进行尝试
Population[i].fitness = 21.5 + x * sin(4 * PI * x) + y * sin(20 * PI * y); /////考虑加上一个数避免出现负值
}
//群体总适应值
for (i = 0; i<POPSIZE; i++)
TotalFitness += Population[i].fitness;
//计算个体相对适应值
if(0==TotalFitness)
exit(0);
else
for (i = 0; i < POPSIZE; i++)
Population[i].rfitness = Population[i].fitness / TotalFitness; //需要处理除数为0的情况
//计算个体累积适应值
Population[0].cfitness = Population[0].rfitness;
for (i=1;i<POPSIZE;i++)
Population[i].cfitness = Population[i].rfitness + Population[i-1].cfitness;
return;
}
//----------------------- 通过轮盘选择策略从旧群体中获取个体 -----------------------------
Individual Roulette()
{
if(Population[POPSIZE - 1].cfitness <= (double)rand() / RAND_MAX)
return Population[POPSIZE];
for (int i = 0; i < POPSIZE; i++)
{
if (Population[i].cfitness > (double)rand() / RAND_MAX)
return Population[i];
}
if(i == POPSIZE)
{
cout<<"ERROR";
exit(1);
}
}
//---------------------------------- 交叉 ---------------------------------------
void Crossover(Individual *dad, Individual *mom)
{
if((double)rand()/RAND_MAX<PCROSSOVER)
{
double u1,u2;
double v1,v2;
a = (double)curGen / (double)MAXGEN; //a如何取比较合适
u1 = (*dad).a1;
u2 = (*dad).a2;
v1 = (*mom).a1;
v2 = (*mom).a2;
(*dad).a1 = v1*a + u1 * (1-a);
(*dad).a2 = v2*a + u2 * (1-a);
(*mom).a1 = u1*a + v1 * (1-a);
(*mom).a2 = u2*a + v2 * (1-a);
}
return;
}
void GT_Crossover(int m)
{
Individual tempindiv;
int i, *index, *sel, select, size;
double *r, s;
index = new int[POPSIZE];
sel = new int[m];
r = new double[m];
for(i=0; i < POPSIZE; i++)
index[i] = i;
size = POPSIZE;
for(i = 0; i < m; i++)
{
select = rand()%size;
sel[i] = index[select];
index[select] = index[--size];
}
s = r[0] = -0.5 + (double)rand()/RAND_MAX * 2;
for(i = 1; i < m - 1; i++)
{
r[i] = -0.5 + (double)rand()/RAND_MAX*(1.5 - s);
s+= r[i];
}
r[m - 1] = 1 - s;
tempindiv.a1 = 0;
tempindiv.a2 = 0;
if((double)rand()/RAND_MAX < 0.1)
for(i=0; i < m; i++)
tempindiv.a1 += Population[sel[i]].a1 * r[i];
if((double)rand()/RAND_MAX < 0.1)
for(i = 0; i < m; i++)
tempindiv.a2 += Population[sel[i]].a2 * r[i];
double x=tempindiv.a1;
double y=tempindiv.a2;
tempindiv.fitness = 21.5 + x * sin(4 * PI * x) + y * sin(20 * PI * y);
int worstindex = GetWorst(Population, POPSIZE);
if(tempindiv.fitness > Population[worstindex].fitness)
Population[worstindex] = tempindiv;
delete[] index;
delete[] sel;
delete[] r;
}
//------------------------------------单点变异---------------------------------------
void Mutate(Individual *indiv)
{
if ((double)rand() / RAND_MAX < PMUTATION)
{
(*indiv).a1 = lbound1 + (ubound1-lbound1) * ((double)rand() / RAND_MAX);
(*indiv).a2 = lbound2 + (ubound2-lbound2) * ((double)rand() / RAND_MAX);
}
return;
}
//------------------------------实施精英策略-------------------------------------
void Elitist()
{
double best,worst;
int bestIndex,worstIndex;
best = Population[0].fitness;
worst = Population[0].fitness;
for (int i=0;i<POPSIZE-1; ++i)
{
if(Population[i].fitness > Population[i+1].fitness)
{
if (Population[i].fitness >= best)
{
best = Population[i].fitness;
bestIndex = i;
}
if (Population[i+1].fitness <= worst)
{
worst = Population[i+1].fitness;
worstIndex = i + 1;
}
}
else
{
if (Population[i].fitness <= worst)
{
worst = Population[i].fitness;
worstIndex = i;
}
if (Population[i+1].fitness >= best)
{
best = Population[i+1].fitness;
bestIndex = i + 1;
}
}
}
//若新群体的最好个体比前一代的最好个体还好,则新群体的个体放入POPSIZE单元中;
//否则用前一代的最佳个体置换当前群体的最坏个体
if (best >= Population[POPSIZE].fitness)
{
Population[POPSIZE] = Population[bestIndex];
}
else
{
Population[worstIndex] = Population[POPSIZE];
}
}
int GetWorst(Individual *indiv, int size)
{
int worstindex = 0;
for(int i = 1; i < size; i++)
{
if(indiv[i].fitness < indiv[worstindex].fitness)
worstindex = i;
}
return worstindex;
}
//----------------------- 显示基因编码 ------------------------
void Report()
{
cout<<"TotalFitness is "<<TotalFitness<<endl;
cout.setf(ios::left,ios::adjustfield);
cout.fill(' ');
cout<<setw(16) << "变量值";
cout<<setw(10) << "Fitness";
cout<<setw(18) << "RelativeFitness";
cout<<setw(20) << "CumulativeFitness" << endl;
cout.setf(ios::right,ios::adjustfield);
for(int i=0;i<POPSIZE;i++)
{
cout<<setw(16) << Population[i].a1 << " " << Population[i].a2;
cout<<setw(10) << Population[i].fitness;
cout<<setw(18) << Population[i].rfitness;
cout<<setw(20) << Population[i].cfitness << endl;
}
return;
}