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

📄 佳点集算法.cpp

📁 理解普通的遗传算法和佳点集遗传算法的基本思想和不同点,用遗传算法测试一标准函数。佳点集算法测试一标准函数,理解普通的遗传算法和佳点集遗传算法的基本思想和不同点
💻 CPP
字号:
//用佳点集遗传算法求解函数最大值问题
// f(x)=x1^2+x2^2+x3^2    其中-5.12<=xi<=5.12
#include<iostream.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include<iomanip.h>
#define N 50               //种群规模
#define c3length 18        // 三个编码的总编码长度 
int  generation;            //遗传代数
double pc ;                //交叉的概率(%)
double pm ;                //变异的概率

typedef struct  individual     //定义个体的结构
{
	char code[c3length+1];   //三个分量分别用6位二进制码表示
	double fitness;            // 适应值
	float Ps,Ecount;           //选择概率,期望次数
	
	int Scount;                 //选中次数
}individual;

individual population[N];

long Decode(char * string,int start,int length)  //解码
	                            //表示对string字符串的从start位置开始的length个字符进行解码
{
	 int i;
	 long value=0;
	 int temp=1;
	 for (i=length+start-1 ;i>=start;i--)
	 {
		 value+=(string[i]-48)*temp;
		 temp*=2;
	 }
	 return value;
}

double CalculateValue(char * s)  //计算函数值
{
	 long temp1,temp2,temp3;
	 double x1,x2,x3;
	 temp1=Decode(s,0,6);
	 temp2=Decode(s,6,6);
	 temp3=Decode(s,12,6);
	 x1=-5.12+(temp1*(5.12-(-5.12)))/(64-1);
	 x2=-5.12+(temp2*(5.12-(-5.12)))/(64-1);
	 x3=-5.12+(temp3*(5.12-(-5.12)))/(64-1);
	 return (x1*x1+x2*x2+x3*x3);
}

void InitialPopulation()     //初始化种群
{
	   int i,j;
	   cout<<"产生的初始种群为:"<<endl;
	   for(i=0;i<N;i++)
	   {
		   for(j=0;j<c3length;j++)
		   {
			   population[i].code[j]=((rand()%10)>5)?'1':'0';
		       cout<<population[i].code[j];
		   }
		   cout<<endl;
		   
		   population[i].code[c3length]='\0';
	   }
}

void SelectCount()   //对期望次数排序,求选中次数
{
	   int i,t;
	   float temp1,temp2,a[N];
	   int b[N];
	   int SHave=0;
	   population[0].Scount=(int)population[0].Ecount;
       population[1].Scount=(int)population[1].Ecount;
  	   population[2].Scount=(int)population[2].Ecount;
		population[3].Scount=(int)population[3].Ecount;
		population[4].Scount=(int)population[4].Ecount;
		population[5].Scount=(int)population[5].Ecount;
		population[6].Scount=(int)population[6].Ecount;
		population[7].Scount=(int)population[7].Ecount;
		population[8].Scount=(int)population[8].Ecount;
		population[9].Scount=(int)population[9].Ecount;

	   for (i=0;i<N;i++)
			SHave+=population[i].Scount;
	  
	   for(i=0;i<N;i++)
		  a[i]=population[i].Ecount-population[i].Scount;
	 
	   if (a[0]<a[1])
	   {  
		   temp1=a[0]; a[0]=a[1];a[1]=temp1;
		   b[0]=1;b[1]=0;
	   }
	   else
	   {
		   b[0]=0;b[1]=1;
	   }
	   for(i=2;i<N;i++)
	   {
		   temp2=a[i];
		   int j=0;
		   while((j<i) && (a[i]<a[j]))
				 j++;
		   if(j==i)
			     b[i]=i;
		   else if(j<i)
			 {
			   for (int k=i;k>j;k--)
			   {
				 a[k]=a[k-1]; b[k]=b[k-1];
			   }
			   a[j]=temp2; b[j]=i;
			 }
	   }

	   for (i=1,t=0;i<=(N-SHave);i++,t++)
		   population[b[t]].Scount++;  
}

void EvaluationIndividual()  //对个体进行评价
{
     int i;
	 double sum=0;
	 for(i=0;i<N;i++)           
	 {
		 population[i].fitness=CalculateValue(population[i].code);
		 sum+=population[i].fitness;
	 }
	 for (i=0;i<N;i++)
	 {
		 population[i].Ps=(float)(population[i].fitness/sum);
		 population[i].Ecount=population[i].Ps*N;
	 }
     SelectCount();


	 cout<<endl<<"                第"<<generation<<"代种群情况"<<endl;
	 cout<<"序号      种     群         适应值      选择概率(%)   期望次数   选中次数"<<endl;
	 for(i=0;i<N;i++)
	 {
		 cout<<setw(2)<<i+1<<"    ";
		 for(int j=0;j<c3length;j++)
			  cout<<population[i].code[j];
		 cout<<setprecision(7);
		 cout<<setw(11)<<population[i].fitness<<setw(12)<<setprecision(5)<<population[i].Ps*100<<setw(14)<<setprecision(4)<<population[i].Ecount<<setw(8)<<population[i].Scount;
		 cout<<endl; 
	 }
}

void SelectAlgorithm()    //选择操作的算法
{
	   int i,j=0;
	   for(i=0;i<N;i++)
	   {
		   while(population[i].Scount>0)
		   {
			   for(int k=0;k<c3length;k++)
				   population[j].code[k]=population[i].code[k];
			   population[j].code[c3length]='\0';
			   j++;
			   population[i].Scount--;
		   }
	   }
}

int MinNum(int x)      //求符合要求的最小素数
{
	   int i=2;
       TAB: while(i<x)
			{
				if(x%i==0)
				{ x++;  i=2;  goto TAB; }
				i++;
			}
		return x;
}
  
float GetDecimal(float x)     //返回小数部分
{
	   int y=(int)x;
	   return (x-y);
}

char GetChromosomeCode(float x)     //获得交叉后产生的n个后代中的第k个染色体
{   
	   char ch;
	   if (x>0.5)
		   ch='0';
	   else
		   ch='1';
	   return ch;
}

void CrossAlgorithm()      //交叉操作
{
	int Randpc;           //产生随机交叉概率看是否执行交叉
	char s[N];            //保存是否交叉状态Y or N
	int i,j;
	int c[N];             //记录与之交叉的个体
	for(i=0;i<N;i++)
		s[i]='N';
                        	//保存交叉前的个体,便于输出
	individual p[N];
	for(i=0;i<N;i++)
	{
		for(j=0;j<c3length;j++)
           p[i].code[j]=population[i].code[j];
	    p[i].code[c3length]='\0';
	}
                        	//执行交叉
	for(i=0;i<N;i++)
	{   
		Randpc=rand()%100;
		if ((Randpc<pc) && (s[i]=='N') )
		{   
			int cross;
		 //   char ch;
			s[i]='Y';

	    	char codes[c3length+1];  //二个个体对应位置值相同用原码值,不同记为'*'
			individual B[2]; 
			int t=0;                   //记录二个交叉个体不同分量的个数,从而方便求素数p
			int p;                     //最小素数
			int k1,k2,k3=1;
		    float tp,t1;
			do
			{
				cross=rand()%N;
			}while((s[cross]=='Y') || (cross==i));
			s[cross]='Y';
			c[i]=cross;
			c[cross]=i;

            for (int k=0;k<c3length;k++)
			{
				if (population[i].code[k]==population[cross].code[k])
					codes[k]=population[i].code[k];
				else
				{
					codes[k]='*';
					++t;
				}
			}
			p=MinNum(2*t+3);
			for(k1=0;k1<2;k1++)
				for(k2=0;k2<c3length;k2++)
				{
					if (codes[k2]=='*')
					{
					    t1=(float)(2*cos((2*3.14*k3)/p));
						tp=GetDecimal(t1);
						B[k1].code[k2]=GetChromosomeCode(tp);

						++k3;
					}
					else
						B[k1].code[k2]=codes[k2];
				}
		
		    for(k2=0;k2<c3length;k2++)
				population[i].code[k2]=B[0].code[k2];
			for(k2=0;k2<c3length;k2++)
				population[cross].code[k2]=B[0].code[k2];
		}
	}
	for (i=0;i<N;i++)
		population[i].fitness=CalculateValue(population[i].code);

	cout<<endl<<"                 第"<<generation<<"代种群交叉情况"<<endl;
	cout<<"序号      种      群     交叉否 交叉       子     代         适应值"<<endl;
	for(i=0;i<N;i++)
	{
		cout<<setw(2)<<i+1<<"   ";
        for (j=0;j<c3length;j++)
			cout<<p[i].code[j];
		cout<<"   "<<s[i];
		cout<<"     "<<setw(2)<<c[i]+1<<"    ";
        for (j=0;j<c3length;j++)
		    cout<<population[i].code[j];
		cout<<" "<<setw(9)<<setprecision(6)<<population[i].fitness;
		cout<<endl;
	}
}

void MutationAlgorithm()   //变异算法.这里默认只有一个个体变异
{ 
     int i,j;
     int MutationLocate=rand()%c3length;   //变异的位置
	 int MutationIndividual=rand()%N;      //变异的个体
	 char yesno[N];
	 if ((rand()%100)>pm)
		 goto T;	 
	 for (i=0;i<N;i++)
	 {
		 if (i==MutationIndividual)
			 yesno[i]='Y';
		 else 
			 yesno[i]='N';
	 }                                      //保存变异前的个体,便于输出
	individual p[N];
	for(i=0;i<N;i++)
	{
		for(j=0;j<c3length;j++)
           p[i].code[j]=population[i].code[j];
	    p[i].code[c3length]='\0';
	}
     //执行变异过程
	 population[MutationIndividual].code[MutationLocate]=(population[MutationIndividual].code[MutationLocate]=='0')?'1':'0';
	 population[MutationIndividual].fitness=CalculateValue(population[MutationIndividual].code);
	 cout<<endl<<"                第"<<generation<<"代种群变异情况"<<endl;
	 cout<<"序号      种     群       是否变异   变异位        新种群           适应值"<<endl;
	 for (i=0;i<N;i++)
	 {
		 cout<<setw(3)<<i+1<<"   ";
		 for(j=0;j<c3length;j++)
			 cout<<p[i].code[j];
		 cout<<"   "<<yesno[i];
		 if (yesno[i]=='Y')
			 cout<<setw(10)<<setprecision(2)<<MutationLocate;
		 else 
			 cout<<setw(10)<<" ";
		 cout<<"      ";
		 for(j=0;j<c3length;j++)
			 cout<<population[i].code[j];
		 cout<<setw(12)<<setprecision(6)<<population[i].fitness;
		 cout<<endl;
	 }
T: 	 ; 
}

void output()    //输出最后结果
{
	   int i;
	   double max=population[0].fitness;
	   int temp=0;
	   for(i=1;i<N;i++)
		   if (population[i].fitness>max)
		   {
			   max=population[i].fitness;
			   temp=i;
		   }
	   cout<<endl<<endl<<"               最 后 结 果 为:      "<<endl;
	   cout<<"x1染色体编码为:";
	   for(i=0;i<6;i++)
		   cout<<population[temp].code[i];
       cout<<endl<<"x2染色体编码为:";
	   for(i=6;i<12;i++)
		   cout<<population[temp].code[i];
	   cout<<endl<<"x3染色体编码为:";
	   for(i=12;i<c3length;i++)
		   cout<<population[temp].code[i];	   
	   cout<<endl<<"f(x)取得最大值:"<<population[temp].fitness<<endl;

}
void main()
{
   cout<<"本程序用佳点集遗传算法求解函数最大值问题   "<<endl;
   cout<<"           f(x)=x1^2+x2^2+x3^2    -5.12<=xi<=5.12"<<endl;
   generation =0; 
   int gene;
   cout<<"请输入操作参数 :";
   cout<<endl<<"        请输入最大遗传代数(100-500):";
   cin>>gene;
   cout<<endl<<"        请输入交叉概率(40-99):";
   cin>>pc;
   cout<<endl<<"        请输入变异概率(1-50):";
   cin>>pm;
   cout<<endl<<endl;  
   srand((unsigned)   time   (NULL));
   InitialPopulation();
   while(generation<gene)
   {
     EvaluationIndividual();
     SelectAlgorithm();
     CrossAlgorithm();
     MutationAlgorithm();
	 generation++;
   } 
   output();
  
  int jixu;
  cout<<"是否继续(1/0):";
  cin>>jixu;
  if (jixu==1) {main();}
  else  exit(0);
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -