📄 es.cpp
字号:
#include "StdAfx.h"
#include ".\es.h"
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <iomanip>
#include <fstream>
using namespace std;
int numConvergence; // 收敛的次数
double numAvgGen; // 平均收敛代数
ofstream Save_all("all.txt",ios::out);
ofstream Save_time("time.txt",ios::out);
ofstream Save_result("result.txt",ios::out);
//ofstream Save_err("err.txt",ios::out);
vector<int> vec1(pop); //用于产生0~pop-1之间的随机数
//比较函数
bool less_fval( const Individual &x, const Individual &y)
{
return x.fval < y.fval;
}
ES::ES(void)
{
Gen = 2000;
popSize = pop;
epsilon = 0.0001; // 精度
chSigma = 0.85; // 变异方差的变化
numConvergence = 0;
numAvgGen = 0;
for(int i=0; i<pop; i++)//产生0~pop-1随机数容器
vec1[i] = i;
}
ES::~ES(void)
{
}
// 适应度函数
double ES:: F(double x, double y, double z)
{
return x*x + y*y + z*z;
}
//初始种群
void ES::Init()
{
int i;
double tx, ty, tz, tf;
nSucMut = 0; // 成功变异的次数
sigma = 1; // 变异方差
g = 0;
for(i=0; i<popSize; i++)
{
tx = myRand();
ty = myRand();
tz = myRand();
tf = F(tx, ty, tz);
Individual ind(tx,ty,tz,tf);
vecInd.push_back(ind);
}
sort_fval(vecInd.begin(),vecInd.begin()+popSize); // 种群按适应度大小升序排列
tf = F(5.12,5.12,5.12);
for(i=0; i<popSize; i++)
{
Individual ind(5.12, 5.12, 5.12, tf);
vecInd.push_back(ind);
}
}
void ES::ReInit()
{
int i;
double tx, ty, tz, tf;
nSucMut = 0; // 成功变异的次数
sigma = 1; // 变异方差
g = 0;
for(i=0; i<popSize; i++)
{
tx = myRand();
ty = myRand();
tz = myRand();
tf = F(tx, ty, tz);
vecInd[i].xval = tx;
vecInd[i].yval = ty;
vecInd[i].zval = tz;
vecInd[i].fval = tf;
}
sort_fval(vecInd.begin(),vecInd.begin()+popSize); // 种群按适应度大小升序排列
tf = F(5.12,5.12,5.12);
for(i=0; i<popSize; i++)
{
vecInd[i+popSize].xval = 5.12;
vecInd[i+popSize].yval = 5.12;
vecInd[i+popSize].zval = 5.12;
vecInd[i+popSize].fval = tf;
}
}
// 产生-5.12到5.12之间的随机小数
double ES::myRand()
{
// int类型最大为32767
double tx = 100.0 * (rand()%10240) + 10*(rand()%10) + (rand()%10);
return ( -5.12 + (tx /100000.0) ); //产生[-5.12,5.12]的浮点数,保留5位小数
}
// 产生-10.24到10.24之间的随机小数
double ES::RangeRand()
{
double tx = 100.0 * (rand()%20480) + (rand()%100) + (rand()%10);
return ( -10.24 + (tx /100000.0) ); //产生[-5.12,5.12]的浮点数,保留5位小数
}
// 种群中个体按按适应度大小升序排列
void ES::sort_fval(vector<Individual>::iterator begin, vector<Individual>::iterator end)
{
sort(begin, end, less_fval);
}
//产生0~1随机小数
double ES:: _random(void)
{
int a;
double r;
a=rand()%32767;
r=(a+0.00)/32767.00;
return r;
}
// 产生满足正态分布的随机数
double ES::N(double mu, double sigma)
{
int i;
double r,sum=0.0;
if(sigma<=0.0) exit(1);
for(i=1;i<=12;i++)
sum = sum + _random();
r=(sum-6.00)*sigma+mu;
return r;
}
//判断x是否满足要求
bool ES:: fit_x(double x)
{
if(x>=-5.12 && x <=5.12 ) return true;
else return false;
}
//变异算子,基于柯西分布
void ES::Mutation_Cauchy()
{
int i;
double tx, ty, tz;
for(i=0; i<popSize; i++)
{
do{
tx = vecInd[i].xval + cauchy(0,sigma); // 柯西分布变化
}while(!fit_x(tx));
do{
ty = vecInd[i].yval + cauchy(0,sigma); // 柯西分布变化
}while(!fit_x(ty));
do{
tz = vecInd[i].zval + cauchy(0,sigma); // 柯西分布变化
}while(!fit_x(tz));
vecInd[i+popSize].xval = tx;
vecInd[i+popSize].yval = ty;
vecInd[i+popSize].zval = tz;
vecInd[i+popSize].fval = F(tx, ty, tz);
}
}
//变异算子,基于高斯分布
void ES::Mutation_Gauss()
{
int i;
double tx, ty, tz;
for(i=0; i<popSize; i++)
{
do{
tx = vecInd[i].xval + N(0,sigma); // 正态分布变化
}while(!fit_x(tx));
do{
ty = vecInd[i].yval + N(0,sigma); // 正态分布变化
}while(!fit_x(ty));
do{
tz = vecInd[i].zval + N(0,sigma); // 正态分布变化
}while(!fit_x(tz));
vecInd[i+popSize].xval = tx;
vecInd[i+popSize].yval = ty;
vecInd[i+popSize].zval = tz;
vecInd[i+popSize].fval = F(tx, ty, tz);
}
}
//变异算子,基于高斯分布和柯西分布
void ES::Mutation_Gauss_Cauchy()
{
int i;
double tx, ty, tz;
for(i=0; i<popSize; i++)
{
if (i < popSize/2) // 适应度小的个体
{
do{
tx = vecInd[i].xval + N(0,sigma); // 正态分布变化
}while(!fit_x(tx));
do{
ty = vecInd[i].yval + N(0,sigma); // 正态分布变化
}while(!fit_x(ty));
do{
tz = vecInd[i].zval + N(0,sigma); // 正态分布变化
}while(!fit_x(tz));
}// end if
else // 适应度小的个体
{
do{
tx = vecInd[i].xval + cauchy(0,sigma); // 柯西分布变化
}while(!fit_x(tx));
do{
ty = vecInd[i].yval + cauchy(0,sigma); // 柯西分布变化
}while(!fit_x(ty));
do{
tz = vecInd[i].zval + cauchy(0,sigma); // 正态分布变化
}while(!fit_x(tz));
}//end else
vecInd[i+popSize].xval = tx;
vecInd[i+popSize].yval = ty;
vecInd[i+popSize].zval = tz;
vecInd[i+popSize].fval = F(tx, ty, tz);
}// end for
}// Mutation_mix
//变异算子,基于双种群
void ES::Mutation_twoPop() // 双种群进化
{
int i;
double tx, ty, tz, tw;
for(i=0; i<popSize; i++)
{
if(i<popSize/4)
{
do{
tw = sigma * exp(-0.01*g);
tx = vecInd[i].xval + N(0,fabs(tw));
}while(!fit_x(tx));
do{
tw = sigma * exp(-0.01*g);
ty = vecInd[i].yval + N(0,fabs(tw));
}while(!fit_x(ty));
do{
tw = sigma * exp(-0.01*g);
tz = vecInd[i].zval + N(0,fabs(tw));
}while(!fit_x(tz));
}
else
{
do{
tx = vecInd[vec1[i]].xval + cauchy(0,sigma);
}while(!fit_x(tx));
do{
ty = vecInd[vec1[i]].yval + cauchy(0,sigma);
}while(!fit_x(ty));
do{
tz = vecInd[vec1[i]].zval + cauchy(0,sigma);
}while(!fit_x(tz));
}
vecInd[i+popSize].xval = tx;
vecInd[i+popSize].yval = ty;
vecInd[i+popSize].zval = tz;
vecInd[i+popSize].fval = F(tx, ty, tz);
}
}
/*
//变异算子,基于双种群
void ES::Mutation_twoPop() // 双种群进化
{
int i;
double tx, ty, tz, tw;
random_shuffle(vec1.begin(),vec1.end());
for(i=0; i<popSize; i++)
{
if(vec1[i]<popSize/2)
{
do{
tw = sigma * exp(-0.01*g);
tx = vecInd[vec1[i]].xval + N(0,fabs(tw));
}while(!fit_x(tx));
do{
tw = sigma * exp(-0.01*g);
ty = vecInd[vec1[i]].yval + N(0,fabs(tw));
}while(!fit_x(ty));
do{
tw = sigma * exp(-0.01*g);
tz = vecInd[vec1[i]].zval + N(0,fabs(tw));
}while(!fit_x(tz));
}
else
{
do{
tx = vecInd[vec1[i]].xval + RangeRand()* N(0,1);
}while(!fit_x(tx));
do{
ty = vecInd[vec1[i]].yval + RangeRand()* N(0,1);
}while(!fit_x(ty));
do{
tz = vecInd[vec1[i]].zval + RangeRand()* N(0,1);
}while(!fit_x(tz));
}
vecInd[i+popSize].xval = tx;
vecInd[i+popSize].yval = ty;
vecInd[i+popSize].zval = tz;
vecInd[i+popSize].fval = F(tx, ty, tz);
}
}
*/
// 选择算子
void ES::Selection()
{
//sort_fval(vecInd.begin(),vecInd.begin()+popSize);
//sort_fval(vecInd.begin()+popSize,vecInd.end());
for(int i=0; i<popSize; i++) // 计算成功的变异
{
if((vecInd[i+popSize].fval-vecInd[i].fval) < 0) ++nSucMut;
}
sort_fval(vecInd.begin(), vecInd.end()); // 种群按适应度大小升序排列
}
// 输出种群的信息
void ES::showPop()
{
cout << "第" << g << "代: f(" << vecInd[0].xval << ", " << vecInd[0].yval << ", "
<< vecInd[0].zval <<") = " << vecInd[0].fval << endl;
Save_all << endl << "第" << g << "代:" << endl;
for(int i=0; i<popSize; i++)
{
Save_all << setw(8)<< vecInd[i].xval << "\t" << setw(8)<< vecInd[i].yval<< "\t"
<< setw(8)<< vecInd[i].zval << "\t" << setw(8)<< vecInd[i].fval << endl;
}
Save_result << "第" << g << "代: f(" << vecInd[0].xval << ", " << vecInd[0].yval << ", "
<< vecInd[0].zval <<") = " << vecInd[0].fval << endl;
}
// 1/5成功法则
void ES:: fifthSuccessRule()
{
int tnum = popSize * NGEN;
if ( (5*nSucMut) > tnum ) // 成功变异大于1/5
{
sigma = sigma / chSigma; // 增加变异步长
}
else if((5*nSucMut) < tnum ) // 成功变异小于于1/5
{
sigma = sigma * chSigma; // 减少变异步长
}
}
// 进化过程
void ES::evolution()
{
// srand((unsigned)time(NULL));//随机种子
// Init(); //初始化种群
showPop();
while(g<Gen && vecInd[0].fval > epsilon )
{
++g;
Mutation_twoPop();
// Mutation_Gauss();
// Mutation_Gauss_Cauchy();
// Mutation_Cauchy();
Selection();
showPop();
if ( (g % NGEN)==0 ) // 每进化NGEN代执行1/5成功法则
{
fifthSuccessRule();
nSucMut = 0;
}
}
numAvgGen += g;
if(g < Gen) numConvergence++;
}
// 产生满足柯西分布的随机数
double ES::cauchy(double a, double b)
{
double u = _random();
return a - b/tan(PI*u);
}
int _tmain(int argc, _TCHAR* argv[])
{
ES example;
clock_t start, finish;
double duration;
start = clock();
example.Init();
example.evolution();
for(int i=0; i<19; i++)
{
example.ReInit();
example.evolution();
}
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
cout<<"该进化算法运行时间为"<<duration<<"秒!"<<endl;
cout<<"总收敛次数:"<< numConvergence<<endl;
cout<<"平均收敛代数: " << numAvgGen/20 <<endl;
Save_time<<"该进化算法运行时间为"<<duration<<"秒!"<<endl;
system("pause");
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -