网上看到了一个比较不错的讲解遗传算法的帖子,链接如下
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;
}