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

📄 sga(实数编码).cpp

📁 通过javabean实现计算平均数与方差
💻 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 + -