问题描述
计算函数 ∑ni=0x2i (−20≤xi≤20) 的最小值,其中n=10.
问题分析
利用实数编码,10个数对应染色体上10个基因,适应度即为每条染色体的基因平方和。对染色体升序排列,适应度最低的染色体作为纯父方与不同母方交配(君主方案),再经过变异后产生下一代染色体。
代码
初始化参数
clear all; %清除所有变量
close all; %清图
clc; %清屏
NP=50; %染色体数目
D=10; %基因数目
Pc=0.8; %交叉率,一般取0.25~1
Pm=0.1; %变异率,一般取0.001~0.1
G=1000; %最大遗传代数,一般100~1000
Xs=20; %定义域上限
Xx=-20; %定义域下限
f=rand(D,NP)*(Xs-Xx)+Xx; %随机获得初始种群
trace=zeros(1,G); %预先分配内存
Fit=zeros(1,NP); %预先分配内存
按适应度升序排列
for np=1:NP Fit(np)=func2(f(:,np)); end [SortFit,Index]=sort(Fit); Sortf=f(:,Index);
sort()默认是升序(ascending order)排列函数,如果降序sort( ,’ascend’)
假设A=[2012,2060,1993]
[B,I] = sort(A)
那么
B=[1993,2012,2060]
I=[3,1,2]
采用君主方案交叉
Emper=Sortf(:,1);
NoPoint=round(D*Pc);
PoPoint=randi([1 D],NoPoint,NP/2);
nf=Sortf;
for i=1:NP/2
nf(:,2*i-1)=Emper; %父方
nf(:,2*i)=Sortf(:,2*i); %母方
%随机交换一定数目的基因
for k=1:NoPoint
nf(PoPoint(k,i),2*i-1)=nf(PoPoint(k,i),2*i);
nf(PoPoint(k,i),2*i)=Emper(PoPoint(k,i));
end
end
与轮盘赌的区别是:轮盘赌的父母方染色体都是根据适应度越大越容易被选中的原理随机筛选出来的。而君主方案是父方染色体全部是本代最占优的一条,母方是按一定顺序(升序)排列的一群染色体。
变异操作
for m=1:NP
for n=1:D
r=rand(1,1);
if r<Pm
nf(n,m)=rand(1,1)*(Xs-Xx)+Xx;
end
end
end
适应度函数
function result=func2(x) result=sum(x.^2);
end
完整代码
%%%%%实值遗传算法求函数极值%%%%
%%%%%初始化参数%%%%%
clear all; %清除所有变量
close all; %清图
clc; %清屏
NP=50; %染色体数目
D=10; %基因数目
Pc=0.8; %交叉率,一般取0.25~1
Pm=0.1; %变异率,一般取0.001~0.1
G=1000; %最大遗传代数,一般100~1000
Xs=20; %定义域上限
Xx=-20; %定义域下限
f=rand(D,NP)*(Xs-Xx)+Xx; %随机获得初始种群
trace=zeros(1,G); %预先分配内存
Fit=zeros(1,NP); %预先分配内存
%%%%%遗传算法循环%%%%%
for gen=1:G
%%%%%按适应度升序排列%%%%%
for np=1:NP
Fit(np)=func2(f(:,np));
end
[SortFit,Index]=sort(Fit);
Sortf=f(:,Index);
%%%%%采用君主方案进行选择交叉操作%%%%%
Emper=Sortf(:,1);
NoPoint=round(D*Pc);
PoPoint=randi([1 D],NoPoint,NP/2);
nf=Sortf;
for i=1:NP/2
nf(:,2*i-1)=Emper;
nf(:,2*i)=Sortf(:,2*i);
for k=1:NoPoint
nf(PoPoint(k,i),2*i-1)=nf(PoPoint(k,i),2*i);
nf(PoPoint(k,i),2*i)=Emper(PoPoint(k,i));
end
end
%%%%%变异操作%%%%%
for m=1:NP
for n=1:D
r=rand(1,1);
if r<Pm
nf(n,m)=rand(1,1)*(Xs-Xx)+Xx;
end
end
end
f=nf;
trace(gen)=SortFit(1);
end
Bestf=Sortf(:,1)
summ=func2(Bestf)
trace(end);
figure
plot(trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')