这两天在看M.Tim Jones的《人工智能》,书中不只介绍原理,而且都有相应的c代码实现。
虽然代码不完全,不过缺少的部分完全可以自己补完。
差异演化和昨天实现的PSO很类似,都属于优化算法。
算法步骤:
1.设定种群个体个数和需要迭代的次数。当然也可以设定条件,然后判断是否停止迭代。
2.定义交叉概率CR,个体有一定概率进行变异,如果变异则进行第3步,如果不变异则下一代个体和当前个体一样。
3.在种群中随机选出三个互不相同的个体进行变异,变异公式如下(有博士论文总结了一大堆变异公式):
X=X+F(X-X)
其中X是种群中个体特征向量,这里就是x和y坐标。g是种群的代数。i代表当前个体,r1,r2,r3是和i不同,并且也互不相同的个体。
4.计算变异后个体的适应度,如果变异后适应度不如变异前,那么将变异后个体重新恢复为变异前个体。
5.比较变异后个体适应度和种群最优个体适应度,将适应度高的个体赋给种群最优个体。
最后当然还是需要目标函数才能计算适应度。
算法结果如下图,小绿点代表种群最优个体适应度:
matlab代码如下:
main.m
clear all;close all;clc; [x y]=meshgrid(-:,-:);
sigma=;
img = (/(*pi*sigma^))*exp(-(x.^+y.^)/(*sigma^)); %目标函数,高斯函数
mesh(img);
hold on;
n=; %种群个体的数量 %初始化种群,定义结构体
par=struct([]);
for i=:n
par(i).x=-+*rand(); %个体的x特征在[- ]随机初始化
par(i).y=-+*rand(); %个体的y特征在[- ]随机初始化
par(i).fit=; %个体适应度为0初始化
end
par_best=par(); %初始化种群中最佳个体 for k=: %迭代次数
plot3(par_best.x+,par_best.y+,par_best.fit,'g*'); %画出最佳个体的位置,+为相对偏移
[par par_best]=select_and_recombine(par,par_best,n); %差异演化函数
end
select_and_recombine.m
function [next_par par_best]=select_and_recombine(par,par_best,n)
F=0.5; %加速因子
CR=0.8; %变异率
next_par=par; %新种群
for i=:n while %在原种群中任选三个互不相同的个体进行交叉变异
r1=floor(+*rand());
r2=floor(+*rand());
r3=floor(+*rand());
if i~=r1 && i~=r2 && i~=r3 &&...
r1~=r2 && r1~=r3 && r2~=r3
break;
end
end if rand()<CR %变异率,可以对每一个特征分别设置,我这里要变一起变了
next_par(i).x=par(r1).x+F*(par(r2).x-par(r3).x); %交叉变异准则
next_par(i).y=par(r1).y+F*(par(r2).y-par(r3).y);
end %计算变异后个体的适应度
next_par(i).fit=compute_fit(next_par(i));
%如果新个体没有变异前个体适应度高,新个体还原为旧个体
if par(i).fit>next_par(i).fit
next_par(i)=par(i);
end
%如果变异后适应度高于种群最高适应个体,则更新种群适应度最高个体
if next_par(i).fit>par_best.fit
par_best=next_par(i);
end
end
end
compute_fit.m
function re=compute_fit(par)
x=par.x;
y=par.y;
sigma=;
if x<- || x> || y<- || y>
re=; %超出范围适应度为0
else %否则适应度按目标函数求解
re=(/(*pi*sigma^))*exp(-(x.^+y.^)/(*sigma^));
end
end