- UID
- 58486
- 积分
- 645
- 威望
- 1
- 桐币
- 30
- 激情
- 1574
- 金币
- 0
- 在线时间
- 216 小时
- 注册时间
- 2010-7-22
桐网贡生
- 积分
- 645
鲜花( 0) 鸡蛋( 0)
|
用遗传算法求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 //种群数量
# define Iter 100 //迭代次数
# define Bitlen 16 //二进制位数
# define Nc 28 //交换的个数
# define Nm 10 //变异的个数
# define Bm 4 //变异的位数统一为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及适应值
double MaxF; //记录所有代中的最大值
int iMax; //最大值的下标
struct Geninfo //记录每一代的最优基因
{
int generi;
double BestX,BestY;
double MaxF;
int BestGener[2*Bitlen];
}Info[Iter];
//*******************************************************//函数声明
void InitialGroup();
void Uncoding(int);
void Calu(int);
void Select(int);
void Cross(int);
void Mutation(int);
void BestOfAll(int);
void Output();
//**********************************************************主函数
int main()
{
int gener=0;
InitialGroup();
cout<<"Iteration is starting."<<"\n";
cout<<"数据保存在'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;
}
//********************************************************////对基因序列进行解码
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);
}
}
//********************************************************//计算适应值
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];
}
//********************************************************适应度选择,赌轮盘法
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];
}
//****************************************保护最优个体
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;
}
//********************************************************
//********************************************************//交叉运算
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]);
//*************************产生Nc个不同的个体
//*************************产生不重复的随机位置
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]];
//*************************产生不重复的随机位置
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]); //产生随机变异个体
//********************************************************
for(i=0;i<2*Bitlen;i++)
P[i]=i;
for(i=2*Bitlen-1;i>=1;--i)
swap(&P[i], &P[rand()%i]); //产生变异位置
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;
}
}
}
//**************************************************寻找所有代中的最优个体
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<<"代中最优值为:"<<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<<"代的"<<"最优值为"<<Info[i].MaxF<<" ";
outfile<<" "<<"\t"<<"x="<<Info[i].BestX<<" \t"<<"y="<<Info[i].BestY;
outfile<<endl;
}
}
clear all;
close all;
Size=50; %种群个数
Iter=100; %代数
Bitlen=18; %二进制串位数
Nc=40; %交换个体数
Nm=15; %变异个体数
max=10;
min=-10; %个体取值范围
%随机生成种群
P=round(rand(Size,2*Bitlen));
%进化开始
for k=1:Iter %迭代步数
time(k)=k;
for j=1:Size %生成50组 x和y,即所有的个体组成的种群
M=P(j,:); %生成个体,即取P的每一行
x1=0;y1=0;
%计算 x
for i=1:Bitlen
x1=x1+M(i)*2^(Bitlen-i); %计算前Bitlen列变成十进制数
end
x=(max-min)*x1/(2^Bitlen-1)+min;
%计算y
for i=1:Bitlen
y1=y1+M(Bitlen+i)*2^(Bitlen-i);%计算后Bitlen列变成十进制数
end
y=(max-min)*y1/(2^Bitlen-1)+min;
%计算适应值,并寻找当代最优个体及最优适应值
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
%计算所有个体的适应值之和
sum=0;
for i=1:Size
sum=sum+F(i);
end
%计算个体的适应度
for i=1:Size
Fitness(i)=F(i)/sum;
end
%选择,赌轮盘算法,每次产生一个选择因子bet
for j=1:1:Size
bet=rand(1); %产生随机因子
psum=0;select=1;
while(psum<bet)
psum=psum+Fitness(select);
select=select+1;
end
tempP(i,:)=P(i,:);
end
%保护最优个体
tempP2=randint(1,5,[1,Size]); % 随机产生5个位置
for i=1:5
tempP(tempP2(i),:)=BestM;
end
%交叉
C=randint(1,Nc,[1,Size]); %随机选择交换个体
for i=1:2:(Nc-1)
p=randint(1,1,[1,2*Bitlen-Bitlen/2]);%从1-Bitlen中产生一个交叉点
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]);%随机选择变异个体
for i=1:Nm
P=randint(1,4,[1,2*Bitlen]);%产生4个变异位置
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) '步的最优值'])
[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')
|
|