⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 es.cpp

📁 该算法采用另外一种策略
💻 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);


//比较函数
bool less_fval( const Individual &x,  const Individual &y)
{
	return x.fval < y.fval; 
}


ES::ES(void)
{

	Gen = 2000;
	popSize = pop;
	epsilon = 1; // 精度
	chSigma = 0.85; // 变异方差的变化
	numConvergence = 0; 
    numAvgGen = 0;

}

ES::~ES(void)
{
}

// 适应度函数  
double ES:: F(double x[20])
{
	double  z = 0;

    for(int i=0; i<20; i++) 
	{ 
		z += pow(x[i], 2) - 10*cos(2*PI*x[i]) + 10;
	}

	return z;
}

//初始种群
void ES::Init() 
{   
	int i;
	double tx[20], tf;

	nSucMut = 0; // 成功变异的次数
	sigma = 1;   // 变异方差
	g = 0;

	for(i=0; i<popSize; i++)
	{
         for(int j=0; j<20; j++) tx[j] = myRand();
		
		tf = F(tx);
    	Individual ind(tx,tf);
		vecInd.push_back(ind);
	}

	sort_fval(vecInd.begin(),vecInd.begin()+popSize); // 种群按适应度大小升序排列


	for(i=0; i<popSize; i++)
	{
		for(int j=0; j<20; j++) tx[j] = myRand();

		tf = F(tx);
		Individual ind(tx,tf);
		vecInd.push_back(ind);
	}

	

}

void ES::ReInit() 
{   
	int i;
	double tx[20];

	nSucMut = 0; // 成功变异的次数
	sigma = 1;   // 变异方差
	g = 0;

	for(i=0; i<popSize; i++)
	{
	   for(int j=0; j<20; j++)
	   {
		   tx[j] = myRand();
		   vecInd[i].xval[j] = tx[j];
	   }
		
		vecInd[i].fval = F(tx);

	}

	sort_fval(vecInd.begin(),vecInd.begin()+popSize); // 种群按适应度大小升序排列


	for(i=0; i<popSize; i++)
	{
		for(int j=0; j<20; j++)
		{
			tx[j] = myRand();
			vecInd[i+popSize].xval[j] = tx[j];
		}

		vecInd[i+popSize].fval = F(tx);

	}


}
// 产生-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位小数
}


// 种群中个体按按适应度大小升序排列
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[20] ;

	for(i=0; i<popSize; i++)
	{
		for(int j=0; j<20; j++)
		{
			do{
				tx[j] = vecInd[i].xval[j] +  cauchy(0,sigma); // 柯西分布变化	
                  
			}while(!fit_x(tx[j]));

			vecInd[i+popSize].xval[j] = tx[j];

		}

		vecInd[i+popSize].fval = F(tx);
	}
}

//变异算子,基于高斯分布
void ES::Mutation_Gauss()
{
	int i;
	double tx[20] ;

	for(i=0; i<popSize; i++)
	{
		for(int j=0; j<20; j++)
		{
			do{
				tx[j] = vecInd[i].xval[j] +  N(0,sigma); // 高斯分布变化	

			}while(!fit_x(tx[j]));

			vecInd[i+popSize].xval[j] = tx[j];

		}

		vecInd[i+popSize].fval = F(tx);
	}
	
}


//变异算子,基于高斯分布和柯西分布
void ES::Mutation_Gauss_Cauchy()
{
	
	int i;
	double tx[20];
    

	for(i=0; i<popSize; i++)
	{
		if (i < popSize/2)  // 适应度小的个体
		{
        
			for(int j=0; j<20; j++)
			{
				do{
					tx[j] = vecInd[i].xval[j] +  N(0,sigma); // 高斯分布变化	

				}while(!fit_x(tx[j]));

				vecInd[i+popSize].xval[j] = tx[j];

			}
       
		  
		}// end if
		else  // 适应度小的个体
		{
			for(int j=0; j<20; j++)
			{
				do{
					tx[j] = vecInd[i].xval[j] +  cauchy(0,sigma); // 柯西分布变化	

				}while(!fit_x(tx[j]));

				vecInd[i+popSize].xval[j] = tx[j];

			}

		}//end else

		vecInd[i+popSize].fval = F(tx);
	}// end for 

	
}// Mutation_mix


//变异算子,基于双种群
void ES::Mutation_twoPop()  // 双种群进化
{

	int i;
	double tx[20],  tw;


	for(i=0; i<popSize; i++)
	{
		if(i<popSize/4)
		{
			for(int j=0; j<20; j++)
			{
				do{
					tw = sigma * exp(-0.01*g);

					tx[j] =  vecInd[i].xval[j] + N(0,fabs(tw));

				}while(!fit_x(tx[j]));

				vecInd[i+popSize].xval[j] = tx[j];
			}//for
		}//if
		else
		{

			for(int j=0; j<20; j++)
			{
				do{
					tx[j] = vecInd[i].xval[j] +  cauchy(0,sigma); // 柯西分布变化	

				}while(!fit_x(tx[j]));

				vecInd[i+popSize].xval[j] = tx[j];
			}//for

		}//else

		vecInd[i+popSize].fval = F(tx);
	}//for
	
}//Mutation_twoPop




// 选择算子
void ES::Selection()
{
    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].fval << endl;

    Save_all << "第" << g << "代: f() = " << vecInd[0].fval << endl;
    
	for(int i=0; i<20; i++)
	{
		if(i%5 == 0) Save_all << endl; 
		Save_all << setw(8)<< vecInd[0].xval[i] << "\t";
	}
	Save_all << endl << "----------------------------------------" << 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));//随机种子
   showPop();
    
  bool flag = false;
  double tx;

  for(int j=0; j<20; j++)
  {
    tx = fabs(vecInd[0].xval[j]);

	if(tx > epsilon ) flag = true;
  }

   while(g<Gen &&  flag ) 
   {
	   ++g;
	   
	 //  Mutation_twoPop(); 
	  //Mutation_Gauss(); 
	  // Mutation_Gauss_Cauchy();   
	  Mutation_Cauchy(); 
       Selection();
	   showPop();
	   
       if ( (g % NGEN)==0 ) // 每进化NGEN代执行1/5成功法则
       {
		   fifthSuccessRule();
		   nSucMut = 0;
       }
	   
		flag = false;

		for(int j=0; j<20; j++)
		{
			tx = fabs(vecInd[0].xval[j]);

			if(tx > epsilon ) flag = true;
		}

   }

   numAvgGen += g; 
   if(g < Gen) numConvergence++;

  
     for(int i=0; i<20; i++)
	 {
		   if(i%5 == 0)  Save_result << endl; 
		   Save_result << setw(8)<< vecInd[0].xval[i] << "\t";
	 }

	 Save_result << endl<< "result: " << vecInd[0].fval << endl;
	 Save_result << endl << "----------------------------------------" << endl;

}

// 产生满足柯西分布的随机数
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 + -