?? sga(實數編碼).cpp
字號:
/*-------------------------------------------------------------|
|求函數的最大值 : |
| 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"
#include "stdafx.h"
using namespace std;
#define PCROSSOVER 0.95
#define PMUTATION 0.15
#define POPSIZE 100
#define MAXGEN 10000
#define PI 3.14159265
#define lbound1 -3
#define ubound1 12.1
#define lbound2 4.1
#define ubound2 5.8
//double PMUTATION=0.08;
////////////////////////////Individual Structure///////////////////////////
typedef struct Individual
{
double x1;
double x2;
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.x1==mom.x1)&&(dad.x2==mom.x2));
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//////////////////////////////////
//-------------------------Initialize Population------------------------------------------
void Initialize()
{
for(int i=0;i<POPSIZE;i++)
{
Population[i].x1=lbound1+(ubound1-lbound1)*(double)rand()/RAND_MAX;
Population[i].x2=lbound2+(ubound2-lbound2)*(double)rand()/RAND_MAX;
Population[i].fitness=0.0f;
Population[i].rfitness=0.0f;
Population[i].cfitness=0.0f;
}
return;
}
//--------------------------Evaluate Fitness-------------------------------------------
void EvaluateFitness()
{
double x=0;
TotalFitness =0;
int i;
// 計算個體的適應值
for (i=0; i<POPSIZE; i++)
{
double x,y;
x=Population[i].x1;
y=Population[i].x2;
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).x1;
u2=(*dad).x2;
v1=(*mom).x1;
v2=(*mom).x2;
(*dad).x1=v1*a+u1*(1-a);
(*dad).x2=v2*a+u2*(1-a);
(*mom).x1=u1*a+v1*(1-a);
(*mom).x2=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.x1 = 0;
tempindiv.x2 = 0;
if((double)rand()/RAND_MAX < 0.1)
for(i=0; i < m; i++)
tempindiv.x1 += Population[sel[i]].x1 * r[i];
if((double)rand()/RAND_MAX < 0.1)
for(i = 0; i < m; i++)
tempindiv.x2 += Population[sel[i]].x2 * r[i];
double x=tempindiv.x1;
double y=tempindiv.x2;
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).x1= lbound1+(ubound1-lbound1)*((double)rand()/RAND_MAX);
(*indiv).x2= 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;
}
//-------------------Print Information of Generations------------------------
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].x1<<" "<<Population[i].x2;
cout<<setw(10)<<Population[i].fitness;
cout<<setw(18)<<Population[i].rfitness;
cout<<setw(20)<<Population[i].cfitness<<endl;
}
return;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -