|
|
用遺傳算法求f=sin(x)sin(y)/x*y的最大值,x、y在-10到10之間
#include<iostream.h>
#include<stdlib.h>
#include<fstream.h>
#include<math.h>
#include<time.h>
//********************************************************//
# define Size 50 //種群數(shù)量
# define Iter 100 //迭代次數(shù)
# define Bitlen 16 //二進(jìn)制位數(shù)
# define Nc 28 //交換的個(gè)數(shù)
# define Nm 10 //變異的個(gè)數(shù)
# define Bm 4 //變異的位數(shù)統(tǒng)一為4
# define Max 10
# define Min -10
//********************************************************//
int Pop[Iter][Size][2*Bitlen];
double X[Size],Y[Size],F[Size],F_sum[Size],Fitness[Size];//x,y及適應(yīng)值
double MaxF; //記錄所有代中的最大值
int iMax; //最大值的下標(biāo)
struct Geninfo //記錄每一代的最優(yōu)基因
{
int generi;
double BestX,BestY;
double MaxF;
int BestGener[2*Bitlen];
}Info[Iter];
//*******************************************************//函數(shù)聲明
void InitialGroup();
void Uncoding(int);
void Calu(int);
void Select(int);
void Cross(int);
void Mutation(int);
void BestOfAll(int);
void Output();
//**********************************************************主函數(shù)
int main()
{
int gener=0;
InitialGroup();
cout<<"Iteration is starting."<<"\n";
cout<<"數(shù)據(jù)保存在'data.txt'中!"<<endl;
while(gener<=Iter)
{
Uncoding(gener);
Calu(gener);
Select(gener);
Cross(gener);
Mutation(gener);
BestOfAll(gener);
gener++;
}
Output();
return 0;
}
//********************************************************//初始生成種群
void InitialGroup()
{
srand(time(NULL));
for(int i=0;i<Size;i++)
for(int j=0;j<2*Bitlen;j++)
Pop[0][i][j]=rand()%2;
}
//********************************************************////對(duì)基因序列進(jìn)行解碼
void Uncoding(int gener)
{
int i;
for(i=0;i<Size;i++)
{
X[i]=0;
for(int j=0;j<Bitlen;j++)
X[i]+=pow(2,j)*Pop[gener][i][Bitlen-j-1];
X[i]=Min+(Max-Min)*X[i]/(pow(2,Bitlen)-1);
}
for(i=0;i<Size;i++)
{
Y[i]=0;
for(int j=0;j<Bitlen;j++)
Y[i]+=pow(2,j)*Pop[gener][i][2*Bitlen-j-1];
Y[i]=Min+(Max-Min)*Y[i]/(pow(2,Bitlen)-1);
}
}
//********************************************************//計(jì)算適應(yīng)值
void Calu(int gener)
{
double temp=0;
int Imax=0;
for(int i=0;i<Size;i++)
{
F[i]=(sin(X[i])*sin(Y[i]))/(X[i]*Y[i]);
if(F[i]<0) F[i]=0;
if(F[i]>temp)
{ temp=F[i];Imax=i;}
}
for(i=0;i<2*Bitlen;i++)
Info[gener].BestGener[i]=Pop[gener][Imax][i];
Info[gener].generi=gener;
Info[gener].MaxF=temp;
Info[gener].BestX=X[Imax];
Info[gener].BestY=Y[Imax];
}
//********************************************************適應(yīng)度選擇,賭輪盤法
void Select(int gener)
{
int i,j,k;
int select;
for(i=0;i<Size;i++)
{
if(i==0) F_sum[i]=F[i];
else F_sum[i]=F_sum[i-1]+F[i];
}
for(i=0;i<Size;i++)
Fitness[i]=F[i]/F_sum[Size-1];
double randnum;
for(i=0;i<Size;i++)
{
srand(rand());
select=0;
randnum=(double)rand()/RAND_MAX;
double psum=0;
while(randnum>psum)
{
psum=psum+Fitness[select];
select++;
}
for(j=0;j<2*Bitlen;j++)
Pop[gener+1][i][j]=Pop[gener][select-1][j];
}
//****************************************保護(hù)最優(yōu)個(gè)體
int a[5];
for(i=0;i<5;i++)
a[i]=rand()%Size;
for(j=0;j<5;j++)
for(k=0;k<2*Bitlen;k++)
Pop[gener+1][a[j]][k]=Info[gener].BestGener[k];
}
//********************************************************
void swap(int * a,int *b)
{
int p;
p=*a;*a=*b;*b=p;
}
//********************************************************
//********************************************************//交叉運(yùn)算
void Cross(int gener)
{
int i,C[Size],P[Bitlen];
int j=0;
srand(rand());
for(i=0;i<Size;i++)
C[i]=i;
for(i=Size-1;i>=1;--i)
swap(&C[i], &C[rand()%i]);
//*************************產(chǎn)生Nc個(gè)不同的個(gè)體
//*************************產(chǎn)生不重復(fù)的隨機(jī)位置
for(i=0;i<Bitlen;i++)
P[i]=i;
for(i=Bitlen-1;i>=1;--i)
swap(&P[i], &P[rand()%i]);
//************************
for(i=0;i<=Nc-2;i=i+2)
for(j=0;j<Bitlen/2;j++)
Pop[gener+1][C[i]][P[j]]=Pop[gener+1][C[i+1]][P[j]];
//*************************產(chǎn)生不重復(fù)的隨機(jī)位置
for(i=Bitlen;i<2*Bitlen;i++)
P[i]=i;
for(i=2*Bitlen-1;i>=1+Bitlen;--i)
swap(&P[i], &P[rand()%i]);
//**************************
for(i=0;i<=Nc-2;i=i+2)
for(j=0;j<Bitlen/2;j++)
Pop[gener+1][C[i]][P[j]]=Pop[gener+1][C[i+1]][P[j]];
}
//********************************************************//變異
void Mutation(int gener)
{
int i,k,M[Size],P[2*Bitlen];
srand(rand());
for(i=0;i<Size;i++)
M[i]=i;
for(i=Size-1;i>=1;--i)
swap(&M[i], &M[rand()%i]); //產(chǎn)生隨機(jī)變異個(gè)體
//********************************************************
for(i=0;i<2*Bitlen;i++)
P[i]=i;
for(i=2*Bitlen-1;i>=1;--i)
swap(&P[i], &P[rand()%i]); //產(chǎn)生變異位置
for(i=0;i<Nc;i++)
{
for(k=0;k<Bm;k++)
{
if(Pop[gener+1][M[i]][P[k]]==0 ) Pop[gener+1][M[i]][P[k]]=1;
else Pop[gener+1][M[i]][P[k]]=0;
}
}
}
//**************************************************尋找所有代中的最優(yōu)個(gè)體
void BestOfAll(int gener)
{
MaxF=0;
iMax=0;
for(int i=0;i<gener;i++)
if(Info[i].MaxF>=MaxF) {MaxF=Info[i].MaxF;iMax=i;}
}
//**************************************************將每一代的信息輸入到txt中
void Output()
{
ofstream outfile("data.txt");
outfile<<Iter<<"代中最優(yōu)值為:"<<MaxF<<" ";
outfile<<"\t"<<"x="<<Info[iMax-1].BestX<<" \t"<<"y="<<Info[iMax-1].BestY<<endl;
outfile<<"***************************************************************"<<endl;
for(int i=0;i<Iter;i++)
{
outfile<<"第"<<Info[i].generi<<"代的"<<"最優(yōu)值為"<<Info[i].MaxF<<" ";
outfile<<" "<<"\t"<<"x="<<Info[i].BestX<<" \t"<<"y="<<Info[i].BestY;
outfile<<endl;
}
}
clear all;
close all;
Size=50; %種群個(gè)數(shù)
Iter=100; %代數(shù)
Bitlen=18; %二進(jìn)制串位數(shù)
Nc=40; %交換個(gè)體數(shù)
Nm=15; %變異個(gè)體數(shù)
max=10;
min=-10; %個(gè)體取值范圍
%隨機(jī)生成種群
P=round(rand(Size,2*Bitlen));
%進(jìn)化開始
for k=1:Iter %迭代步數(shù)
time(k)=k;
for j=1:Size %生成50組 x和y,即所有的個(gè)體組成的種群
M=P(j,:); %生成個(gè)體,即取P的每一行
x1=0;y1=0;
%計(jì)算 x
for i=1:Bitlen
x1=x1+M(i)*2^(Bitlen-i); %計(jì)算前Bitlen列變成十進(jìn)制數(shù)
end
x=(max-min)*x1/(2^Bitlen-1)+min;
%計(jì)算y
for i=1:Bitlen
y1=y1+M(Bitlen+i)*2^(Bitlen-i);%計(jì)算后Bitlen列變成十進(jìn)制數(shù)
end
y=(max-min)*y1/(2^Bitlen-1)+min;
%計(jì)算適應(yīng)值,并尋找當(dāng)代最優(yōu)個(gè)體及最優(yōu)適應(yīng)值
F(j)=0.9*exp(-((x+5)^2+(y+5)^2)/10)+0.99996*exp(-((x-5)^2+(y-5)^2)/20);
%F(j)=sin(x)*sin(y)/(x*y);
if j==1
BestF(k)=F(j);
BestX(k)=x;
BestY(k)=y;
BestM=M;
else
if F(j)>BestF(k)
BestF(k)=F(j);
BestX(k)=x;
BestY(k)=y;
BestM=M;
end
end
end
%計(jì)算所有個(gè)體的適應(yīng)值之和
sum=0;
for i=1:Size
sum=sum+F(i);
end
%計(jì)算個(gè)體的適應(yīng)度
for i=1:Size
Fitness(i)=F(i)/sum;
end
%選擇,賭輪盤算法,每次產(chǎn)生一個(gè)選擇因子bet
for j=1:1:Size
bet=rand(1); %產(chǎn)生隨機(jī)因子
psum=0;select=1;
while(psum<bet)
psum=psum+Fitness(select);
select=select+1;
end
tempP(i,:)=P(i,:);
end
%保護(hù)最優(yōu)個(gè)體
tempP2=randint(1,5,[1,Size]); % 隨機(jī)產(chǎn)生5個(gè)位置
for i=1:5
tempP(tempP2(i),:)=BestM;
end
%交叉
C=randint(1,Nc,[1,Size]); %隨機(jī)選擇交換個(gè)體
for i=1:2:(Nc-1)
p=randint(1,1,[1,2*Bitlen-Bitlen/2]);%從1-Bitlen中產(chǎn)生一個(gè)交叉點(diǎn)
temp=tempP(C(i),p:p+Bitlen/2);
tempP(C(i),p:p+Bitlen/2)=tempP(C(i+1),p:p+Bitlen/2);
tempP(C(i+1),p:p+Bitlen/2)=temp;
end
%變異
M=randint(1,Nm,[1,Size]);%隨機(jī)選擇變異個(gè)體
for i=1:Nm
P=randint(1,4,[1,2*Bitlen]);%產(chǎn)生4個(gè)變異位置
for j=1:4
if(tempP(M(i),P(j))==0)
tempP(M(i),P(j))=1;
else tempP(M(i),P(j))=0;
end
end
end
P=tempP;
disp(['迭代第' num2str(k) '步的最優(yōu)值'])
[BestX(k) BestY(k) BestF(k)]
end
figure(1);
plot(time,BestF);
xlabel('Times');ylabel('BestF');
figure(2);
plot(time,BestX);
xlabel('times');ylabel('BestX');
figure(3);
plot(time,BestY);
xlabel('time');ylabel('BestY')
|
|