读书使人充实,讨论使人机智,笔记使人准确…。凡有所学,皆成性格。
———— (英国)培根
文章目录
遗传学与遗传算法术语表
遗传学术语 | 遗传算法术语 |
---|---|
群体 | 可行解集 |
个体 | 可行解 |
染色体 | 可行解的编码 |
基因 | 可行解编码的分量 |
基因形式 | 遗传编码 |
适应度 | 评价函数值 |
选择 | 选择操作 |
交叉 | 交叉操作 |
变异 | 变异操作 |
关键参数说明
参数 | 取值 |
---|---|
群体规模 N p N_{p} Np | 一般 N p N_{p} Np取10~200 |
交叉概率 P c P_{c} Pc | 一般 P c P_{c} Pc取0.25~1.00 |
变异概率 P m P_{m} Pm | 通常 P m P_{m} Pm取0.001~0.1 |
遗传运算的终止进化代数 G G G | G G G的取值可在100~1000之间 |
MATLAB仿真实例
[求最大值]用标准遗传算法求函数 f ( x ) = x + 10 s i n ( 5 x ) + 7 c o s ( 4 x ) f(x)=x+10sin(5x)+7cos(4x) f(x)=x+10sin(5x)+7cos(4x)的最大值,其中x的取值范围为[0,10]。这是一个有多个局部极值的函数,其函数值图形如图2.2所示,其MATLAB实现程序如下:
%%%%%%%%%%%%f(x)=x+10sin(5x)+7cos(4x)%%%%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %清图
clc; %清屏
x=0:0.01:10;
y=x+10*sin(5*x)+7*cos(4*x);
max_y=max(y);
max_x=x(find(y==max_y));
plot(x,y,max_x,max_y,'ro')
xlabel('x')
ylabel('f(x)')
title('f(×)=×+10sin(5×)+7cos(4x)')
仿真过程如下:
(1)初始化种群数目为 N p N_{p} Np=50,染色体二进制编码长度为L=20,最大进化代数为G=100,交叉概率为 P c P_{c} Pc=0.8,变异概率为 P m P_{m} Pm=0.1。(2)产生初始种群,将二进制编码转换成十进制,计算个体适应度值,并进行归一化;采用基于轮盘赌的选择操作、基于概率的交叉和变异操作,产生新的种群,并把历代的最优个体保留在新种群中,进行下一步遗传操作
(3)判断是否满足终止条件:若满足,则结束搜索过程,输出优化值;若不满足,则继续进行迭代优化。优化结束后,其适应度进化曲线如图所示,优化结果为x=7.8567,函数f(x)的最大值为24.86。
MATLAB源程序如下:
%%%%%%%%%%%%标准遗传算法求函数极值%%%%%%%%%%%%
%%%%%%%%%%%%%%%%初始化参数%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %种群数量
clc; %清屏
NP=50; %种群数量
L=20; %二进制位串长度
Pc=0.8; %交叉率
Pm=0.1; %变异率
G=100; %最大遗传代数
Xs=10; %上限
Xx=0; %下限
f=randi([0, 1], NP, L); %随机获得初始种群
%%%%%%%%%%%%%%%%%%遗传算法循环%%%%%%%%%%%%%%%%%%
for k=1: G
%%%%%%%%%将二进制解码为定义域范围内十进制%%%%%%%%%
for i=1:NP
U=f(i,:);
m=0;
for j=1:L
m=U(j)*2^(j-1)+m;
end
x(i)=Xx+m*(Xs-Xx)/(2^L-1);
Fit(i)= funcl(x(i));
end
maxFit=max(Fit); %最大值
minFit=min(Fit); %最小值
rr= find (Fit==maxFit);
fBest=f(rr(1,1),:); %历代最优个体
xBest=x(rr(1,1));
Fit=(Fit- minFit)/( maxFit- minFit); %归一化适应度值
%%%%%%%%%%%%%基于轮盘赌的复制操作%%%%%%%%%%%%%
sum_Fit=sum(Fit);
fitvalue=Fit./sum_Fit;
fitvalue=cumsum(fitvalue);
ms=sort(rand(NP,1));
fiti=1;
newi=1;
while newi<=NP
if (ms(newi))< fitvalue(fiti)
nf(newi,:)= f(fiti,:);
newi=newi+1;
else
fiti=fiti+1;
end
end
%%%%%%%%%%%%%%%基于概率的交叉作%%%%%%%%%%%%%%%%%
for i =1:2: NP
p= rand;
if p< Pc
q= randi([0,1],1,L);
for j=1:L
if q(j)==1
temp=nf(i+1,j);
nf(i+1, j)= nf(i,j);
nf(i,j)=temp;
end
end
end
end
%%%%%%%%%%%%%基于概率的变异操作%%%%%%%%%%%%%
i=1;
while i <= round (NP*Pm)
h= randi([1,NP],1,1); %随机选取一个需要变异的染色体
for j= 1: round(L*Pm)
g= randi([1,L],1,1); %随机选取需要变异的基因数
nf(h, g)=~ nf(h, g);
end
i=i+1;
end
f=nf;
f(1,:)= fBest; %保留最优个体在新种群中
trace(k)= maxFit; %历代最优适应度
end
xBest; %最优个体
figure
plot (trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
%%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%
function result=funcl(x)
fit =x+10*sin(5*x)+7*cos(4*x);
result=fit;
end
[求最小值]计算函数 f ( x ) = ∑ i = 1 n x i 2 ( − 20 ≤ x i ≤ 20 ) f(x)=\sum_{i=1}^nx_{i}^2\quad(-20 \leq x_{i} \leq 20) f(x)=∑i=1nxi2(−20≤xi≤20) 的最小值,其中个体x的维数n=10。这是一个简单的平方和函数,只有一个极小点x=(0,0,…,0),理论最小值f(0,0,…,0)=0
解:仿真过程如下:
(1)初始化种群数目为 N p N_{p} Np=100,染色体基因维数为D=10,最大进化代数为G=1000,交叉概率为 P c P_{c} Pc=0.8,变异概率为 P m P_{m} Pm=0.1。
(2)产生初始种群,计算个体适应度值;进行实数编码的选择以及交叉和变异操作。选择和交叉操作采用“君主方案”,即在对群体根据适应度值高低进行排序的基础上,用最优个体与其他偶数位的所有个体进行交叉,每次交叉产生两个新的个体。在交叉过后,对新产生的群体进行多点变异产生子群体,再计算其适应度值,然后和父群体合并,并且根据适应度值进行排序,取前 N p N_{p} Np个个体为新群体,进行下一次遗传操作。
(3)判断是否满足终止条件:若满足,则结束搜索过程,输出优化值;若不满足,则继续进行迭代优化。
优化结束后,其适应度进化曲线如图所示,优化后的结果为x=[0.0003 -0.0037 0.0069 -0.0000 -0.0020 0.0001 -0.0009 0.0056 0.0052 0.0003],函数f(x)的最小值为1.24×10-4
MATLAB源程序如下:
%%%%%%%%%%%%实值遗传算法求函数极值%%%%%%%%%%%%
%%%%%%%%%%%%%%%%初始化参数%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %种群数量
clc; %清屏
D=10; %基因数目
NP=100; %染色体数目
Pc=0.8; %交叉率
Pm=0.1; %变异率
G=1000; %最大遗传代数
Xs=20; %上限
Xx=-20; %下限
f=zeros(D,NP); %初始种群赋空间
nf=zeros(D,NP); %子种群赋空间
f=rand(D,NP)*(Xs-Xx)+Xx; %随机获得初始种群
%%%%%%%%%%%%%%%%%%按适应度升序排列%%%%%%%%%%%%%%%%%%
for np=1:NP
FIT(np)= func2(f(:,np));
end
[SortFIT, Index]= sort(FIT);
Sortf=f(:, Index);
%%%%%%%%%%%%%%%%%%遗传算法循环%%%%%%%%%%%%%%%%%%%%
for gen =1:G
%%%%%%%%%%%%%%%%%%采用君主方案进行选择交叉操作%%%%%%%%%%%%%
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
%%%%%%%%%%%%%%%%子种群按适应度升序排列%%%%%%%%%%%%%%%%
for np=1: NP
NFIT(np)= func2(nf(:,np));
end
[NSortFIT,Index]= sort(NFIT);
NSortf=nf(:,Index);
%%%%%%%%%%%%%%%%产生新种群%%%%%%%%%%%%%%%%%%%%%%%
f1=[Sortf,NSortf]; %子代和父代合并
FIT1= [SortFIT, NSortFIT]; %子代和父代的适应度值合并
[SortFIT1, Index]= sort(FIT1); %适应度按升序排列
Sortf1=f1(:,Index); %按适应度排列个体
SortFIT=SortFIT1(1:NP); %取前NP个适应度值
Sortf=Sortf1(:,1:NP); %取前NP个个体
trace(gen)= SortFIT(1); %历代最优适应度值
end
Bestf=Sortf(:,1) %最优个体
trace(end); %最优值
figure
plot(trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
%%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%
function result=func2(x)
summ=sum(x.^2);
result=summ;
end
[旅行商问题](TSP)。假设有一个旅行商人要拜访全国31个省会城市,他需要选择所要走的路径,路径的限制是每个城市只能拜访一次,而且最后要回到原来出发的城市。对路径选择的要求是:所选路径的路程为所有路径之中的最小值。全国31个省会城市的坐标为[1304 2312;3639 1315;4177 2244;37121399;3488 1535;3326 1556;3238 1229;4196 1004;4312 790;4386 570;3007 1970;2562 1756;2788 1491;2381 1676;1332695;3715 1678;3918 2179;4061 2370;3780 2212;3676 2578;4029 2838;4263 2931;3429 1908;3507 2367;3394 2643;34393201;2935 3240;3140 3550;2545 2357;2778 2826;2370 2975]。
解:仿真过程如下:
(1)初始化种群数目为 N p N_{p} Np=200,染色体基因维数为N=31,最大进化代数为G=1000。
(2)产生初始种群,计算个体适应度值,即路径长度;采用基于概率的方式选择进行操作的个体;对选中的成对个体,随机交叉所选中的成对城市坐标,以确保交叉后路径每个城市只到访一次;对选中的单个个体,随机交换其一对城市坐标作为变异操作,产生新的种群,进行下一次遗传操作。
(3)判断是否满足终止条件:若满足,则结束搜索过程,输出优化值;若不满足,则继续进行迭代优化。
优化后的路径如图所示
其适应度进化曲线如图所示
MATLAB源程序如下:
%%%%%%%%%%%%%%%%%%%%%%%%%遗传算法解决TSP问题%%%%%%%%%%%%%%%%%%%%%%%
clear all; %清除所有变量
close all; %清图
clc; %清屏
C=[1304 2312;3639 1315;4177 2244;3712 1399;3488 1535;3326 1556;...
3238 1229;4196 1044;4312 790;4386 570;3007 1970;2562 1756;...
2788 1491;2381 1676;1332 695;3715 1678;3918 2179;4061 2370;...
3780 2212;3676 2578;4029 2838;4263 2931;3429 1908;3507 2376;...
3394 2643;3439 3201;2935 3240;3140 3550;2545 2357;2778 2826;...
2370 2975]; %31个省会城市坐标
N=size(C,1); %TSP问题的规模,即城市数目
D=zeros(N); %任意两个城市距离间隔矩阵
%%%%%%%%%%%%%%%%%%%%%求任意两个城市距离间隔矩阵%%%%%%%%%%%%%%%%%%%%%
for i=1:N
for j=1:N
D(i,j)=((C(i,1)-C(j,1))^2+(C(i,2)-C(j,2))^2)^0.5;
end
end
NP=200; %种群规模
G=1000; %最大遗传代数
f=zeros(NP,N); %用于存储种群
F=[]; %种群更新中间存储
for i=1:NP
f(i,:)=randperm(N); %随机生成初始种群
end
R=f(1,:); %存储最优种群
len=zeros(NP,1); %存储路径长度
fitness=zeros(NP,1); %存储归一化适应值
gen=0;
%%%%%%%%%%%%%%%%%%%%%%%%%遗传算法循环%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
while gen<G
%%%%%%%%%%%%%%%%%%%%%计算路径长度%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i=1:NP
len(i,1)=D(f(i,N),f(i,1));
for j=1:(N-1)
len(i,1)=len(i,1)+D(f(i,j),f(i,j+1));
end
end
maxlen=max(len); %最长路径
minlen=min(len); %最短路径
%%%%%%%%%%%%%%%%%%%%%%%%%更新最短路径%%%%%%%%%%%%%%%%%%%%%%%%%%
rr=find(len==minlen);
R=f(rr(1,1),:);
%%%%%%%%%%%%%%%%%%%%%计算归一化适应值%%%%%%%%%%%%%%%%%%%%%%%%%%
for i=1:length(len)
fitness(i,1)=(1-((len(i,1)-minlen)/(maxlen-minlen+0.001)));
end
%%%%%%%%%%%%%%%%%%%%%%%%%%选择操作%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nn=0;
for i=1:NP
if fitness(i,1)>=rand
nn=nn+1;
F(nn,:)=f(i,:);
end
end
[aa,bb]=size(F);
while aa<NP
nnper=randperm(nn);
A=F(nnper(1),:);
B=F(nnper(2),:);
%%%%%%%%%%%%%%%%%%%%%%%交叉操作%%%%%%%%%%%%%%%%%%%%%%%%%%%%
W=ceil(N/10); %交叉点个数
p=unidrnd(N-W+1); %随机选择交叉范围,从p到p+W
for i=1:W
x=find(A==B(p+i-1));
y=find(B==A(p+i-1));
temp=A(p+i-1);
A(p+i-1)=B(p+i-1);
B(p+i-1)=temp;
temp=A(x);
A(x)=B(y);
B(y)=temp;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%变异操作%%%%%%%%%%%%%%%%%%%%%%%%%
p1=floor(1+N*rand());
p2=floor(1+N*rand());
while p1==p2
p1=floor(1+N*rand());
p2=floor(1+N*rand());
end
tmp=A(p1);
A(p1)=A(p2);
A(p2)=tmp;
tmp=B(p1);
B(p1)=B(p2);
B(p2)=tmp;
F=[F;A;B];
[aa,bb]=size(F);
end
if aa>NP
F=F(1:NP,:); %保持种群规模为n
end
f=F; %更新种群
f(1,:)=R; %保留每代最优个体
clear F;
gen=gen+1
Rlength(gen)=minlen;
end
figure
for i=1:N-1
plot([C(R(i),1),C(R(i+1),1)],[C(R(i),2),C(R(i+1),2)],'bo-');
hold on;
end
plot([C(R(N),1),C(R(1),1)],[C(R(N),2),C(R(1),2)],'ro-');
title(['优化最短距离:',num2str(minlen)]);
figure
plot(Rlength)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
[0-1背包问题]。有N件物品和一个容量为V的背包。第i件物品的体积是c(i),价值是w(i)。求解将哪些物品放入背包可使物品的体积总和不超过背包的容量,且价值总和最大。假设物品数量为10,背包的容量为300。每件物品的体积为[95,75,23,73,50,22,6,57,89,98],价值为[89,59,19,43,100,72,44,16,7,64]。
解:仿真过程如下:
(1)初始化种群数目为 N p N_{p} Np=50,染色体基因维数为L=10,最大进化代数为G=100。
(2)产生二进制初始种群,其中1表示选择该物品,0表示不选择该物品。取适应度值为选择物品的价值总和,计算个体适应度值,当物品体积总和大于背包容量时,对适应度值进行惩罚计算。
(3)对适应度进行归一化,采用基于轮盘赌的选择操作、基于概率的交叉和变异操作,产生新的种群,并把历代的最优个体保留在新种群中,进行下一步遗传操作。
(4)判断是否满足终止条件:若满足,则结束搜索过程,输出优化值;若不满足,则继续进行迭代优化。
优化结果为[1 0 1 0 1 1 1 0 0 1],1表示选择相应物品,0表示不选择相应物品,价值总和为388。
其适应度进化曲线如图所示
MATLAB源程序如下:
%%%%%%%%%%%%%%%遗传算法解决0-1背包问题%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%初始化参数%%%%%%%%%%%%%%%%%%%%%%
clear all; %清变量
close all; %清图
clc; %清屏
NP = 50; %种群规模
L = 10; %物品件数
Pc = 0.8; %交叉率
Pm = 0.05; %变异率
G = 100; %最大遗传代数
V = 300; %背包容量
C = [95,75,23,73,50,22,6,57,89,98]; %物品体积
W = [89,59,19,43,100,72,44,16,7,64]; %物品价值
afa = 2; %惩罚函数系数
f = randi([0,1],NP,L); %随机获得初始种群
%%%%%%%%%%%%%%%%%%%%%遗传算法循环%%%%%%%%%%%%%%%%%%%%%
for k = 1:G
%%%%%%%%%%%%%%%%%%适应度计算%%%%%%%%%%%%%%%%%
for i = 1:NP
Fit(i) = func4(f(i,:),C,W,V,afa);
end
maxFit = max(Fit); %最大值
minFit = min(Fit); %最小值
rr = find(Fit==maxFit);
fBest = f(rr(1,1),:); %历代最优个体
Fit = (Fit - minFit)/(maxFit - minFit); %归一化适应度值
%%%%%%%%%%%%%%基于轮盘赌的复制操作%%%%%%%%%%%%%
sum_Fit = sum(Fit);
fitvalue = Fit./sum_Fit;
fitvalue = cumsum(fitvalue);
ms = sort(rand(NP,1));
fiti = 1;
newi = 1;
while newi <= NP
if (ms(newi)) < fitvalue(fiti)
nf(newi,:) = f(fiti,:);
newi = newi + 1;
else
fiti = fiti + 1;
end
end
%%%%%%%%%%%%%%%基于概率的交叉操作%%%%%%%%%%%%%
for i = 1:2:NP
p = rand;
if p < Pc
q = randi([0,1],1,L);
for j = 1:L
if q(j)==1;
temp = nf(i + 1,j);
nf(i + 1,j) = nf(i,j);
nf(i,j) = temp;
end
end
end
end
%%%%%%%%%%%%%基于概率的变异操作%%%%%%%%%%%%%%
for m = 1:NP
for n = 1:L
r = rand(1,1);
if r < Pm
nf(m,n) = ~nf(m,n);
end
end
end
f = nf;
f(1,:) = fBest; %保留最优个体在新种群中
trace(k) = maxFit; %历代最优适应度
end
fBest; %最优个体
figure
plot(trace)
xlabel('迭代次数')
ylabel('目标函数值')
title('适应度进化曲线')
%%%%%%%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%%%%%
function result = func4(f,C,W,V,afa)
fit = sum(f.*W);
TotalSize = sum(f.*C);
if TotalSize <= V
fit = fit;
else
fit = fit - afa * (TotalSize - V);
end
result = fit;
end
[1]包子阳 余继周 杨彬.智能优化算法及其MATLAB实例[M]电子工业出版社,2021