遗传算法求解二元函数极值源码

网上看到了一个比较不错的讲解遗传算法的帖子,链接如下

http://blog.csdn.net/b2b160/article/details/4680853

但是却没有贴源代码,正好最近闲来无事,就尝试写了下代码实现,测试了几次,寻优结果都能达到了二元函数最大值98,如下所示

#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <ctime>
#include <map>
#include <list>
#include <vector>
using namespace std;
#define MAXLENGTH 1000
#define DNANUMBER 30
#define DNALENGTH 6
#define ITERATIONNUMBER 100
int generic[DNANUMBER][MAXLENGTH];
int select[DNANUMBER][MAXLENGTH];
int FitNess[DNANUMBER];
float FitNessProportion[DNANUMBER];
//二次函数为f(x1,x2)=x1^2+x2^2;遗传数组为待求解的串组合
int fitMax;
void InitDna()
{
  //对所有的染色体进行随机初始化
  int i,j;
  fitMax=INT_MIN;
  srand(time(NULL));
  for(i=0;i<DNANUMBER;i++)
  {
	  for(j=0;j<DNALENGTH;j++)
	  {
	    if(rand()%2==0)
		{
		  generic[i][j]=1;
		}
		else
			generic[i][j]=0;
	  }
  }
}
int BinaryToDecimal(int index,int start,int end)
{
  int ret=0;
  int i;
  int mul=1;
  for(i=end;i>=start;i--)
  {
	  if(generic[index][i]==1)
	  {
	    ret+=mul;
	  }
	  mul=mul*2;
  }
  return ret;
}
int Decode(int index)
{
  int i=0;
  int x1,x2;
  x1=BinaryToDecimal(index,0,DNALENGTH/2-1);
  x2=BinaryToDecimal(index,DNALENGTH/2,DNALENGTH-1);
  return x1*x1+x2*x2;
}
void CopyGenericToSelect(int srcIndex,int dstIndex)
{
  int i=0;
  for(i=0;i<DNALENGTH;i++)
  {
	  select[dstIndex][i]=generic[srcIndex][i];
  }
}
void CopySelecToGeneric(int srcIndex,int dstIndex)
{
   int i=0;
  for(i=0;i<DNALENGTH;i++)
  {
	  generic[dstIndex][i]=select[srcIndex][i];
  }
}
void  SelectDna()
{
   //进行适应度计算 然后填充FitNess和FitNessProportion数组
   int i,j;
   int fitSum=0;
   for(i=0;i<DNANUMBER;i++)
   {
	   FitNess[i]=Decode(i);
	   fitMax=std::max(fitMax,FitNess[i]);
	   fitSum+=FitNess[i];
   }
   for(i=0;i<DNANUMBER;i++)
   {
	   FitNessProportion[i]=0;
	   FitNessProportion[i]+=FitNess[i];
   }
   //生成和DNA数目相同的随机数,查看其落在FitNessProprotion哪个区间,并选择其对应的区域,这就是经典的轮盘赌选择方法
   srand(time(NULL));
   int mask[DNANUMBER];
   for(i=0;i<DNANUMBER;i++)
   {
     mask[i]=0;
   }
   float randNumber;
   for(i=0;i<DNANUMBER;i++)
   {
	   randNumber=rand()/RAND_MAX;
	   for(j=0;j<DNANUMBER;j++)
	   {
		   if(randNumber<FitNessProportion[j])
		   {
		     mask[j]++;
			 break;
		   }
	   }
   }
   //根据mask数组情况来进行染色体复制  比如mask数组为 1 1 2 0 1 ,就把1,2,3,5号染色体复制回原染色体组,其中3号染色体复制两次
   int count=0;
   for(i=0;i<DNANUMBER;i++)
   {
     while(mask[i]!=0)
	 {
	   CopyGenericToSelect(mask[i],count);
	   count++;
	   mask[i]--;
	 }
   }
   //将选择后的select矩阵写回到原generic矩阵
   for(i=0;i<DNANUMBER;i++)
   {
	   CopySelecToGeneric(i,i);
   }
}
void Swap(int index)
{
	int i,j;
	int swapIndex;
	int temp;
	srand(time(NULL));
	swapIndex=rand()%DNANUMBER;
	for(i=0;i<DNALENGTH;i++)
	{
		temp=generic[index][i];
		generic[index][i]=generic[swapIndex][i];
		generic[swapIndex][i]=temp;
	}


}
void CrossDna()
{
	//该函数为交叉操作
	//对dna矩阵进行随机分组
	int i,j;
	for(i=0;i<DNANUMBER;i++)
	{
	   Swap(i);
	}
	//两两一组,进行交叉
	srand(time(NULL));
	int crossPoint;
	int temp;
	for(i=0;i<DNANUMBER;i+=2)
	{
		crossPoint=rand()%DNALENGTH;
		for(j=crossPoint;j<DNALENGTH;j++)
		{
			temp=generic[i][j];
			generic[i][j]=generic[i+1][j];
			generic[i+1][j]=temp;
		}

	}
}
void VariateDna()
{
	srand(time(NULL));
	int variaPoint=rand()%DNALENGTH;
	int i;
	for(i=0;i<DNANUMBER;i++)
	{
		if(generic[i][variaPoint]==1)
			generic[i][variaPoint]=0;
		else
			generic[i][variaPoint]=1;
	}
}
void Generic()
{
   int i,j,k;
   InitDna();
   for(i=0;i<ITERATIONNUMBER;i++)
   {
	      SelectDna();
		  CrossDna();
		  VariateDna();
   }
   cout<<"the maxvalue is "<<fitMax<<endl;
}
int main()
{
   int i;
   for(i=0;i<50;i++)
   {
	   Generic();
   }
    return 0;
}

    原文作者:遗传算法
    原文地址: https://blog.csdn.net/lycommand/article/details/53240971
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞