差分进化算法求函数 Z = 3 * cos(X .* Y) + X + Y , -4 <= X <= 4, -4 <= Y <= 4。
计算目标函数值
计算目标函数值的函数:
function z = calobj (pop)
% 计算目标函数值
% pop input 种群
% z output 目标函数值
z = 3 * cos(pop(:,1) .* pop(:,2)) + pop(:,1) + pop(:,2);
end
初始化种群
目标函数有两个参数,生成每个个体有两个基因的种群:
function pop = initpop(popsize, chromlength, xl, xu)
% 生成初始种群
% popsize input 种群规模
% chromlengt input 染色体长度
% xl input x下限
% xu input x上限
% pop output 种群
pop = rand(popsize, chromlength) * (xu - xl) + xl;
end
变异
变异函数如下:
function mutationpop = mutation (pop, F)
% 变异操作
% pop input 种群
% F input 缩放因子
% mutationpop output 变异后种群
[popsize, chromlength] = size(pop);
mutationpop = zeros(popsize, chromlength);
for i = 1:popsize
% 取3个互异的索引 r0 r1 r2
r = randperm(popsize);
index = find (r ~= i);
rn = r(index(1:3));
r0 = rn(1); r1 = rn(2); r2 = rn(3);
% fprintf('i = %d, r0 = %d, r1 = %d, r2 = %d\n', i, r0, r1, r2);
mutationpop(i,:) = pop(r0,:) + F .* (pop(r1,:) - pop(r2,:));
end
end
交叉
交叉函数如下:
function crossoverpop = crossover(pop, mpop, cr)
% 交叉
% pop input 种群
% mpop input 变异后的种群
% cr input 交叉概率
% crossoverpop output 交叉后的种群
[popsize, chromlength] = size(pop);
crossoverpop = mpop;
r = rand(popsize, chromlength);
index = find (r > cr);
crossoverpop(index) = pop(index);
jrand = randi(chromlength, 1, popsize);
crossoverpop(sub2ind(size(crossoverpop), [1:popsize], jrand)) ...
= mpop(sub2ind(size(mpop), [1:popsize], jrand));
end
在交叉操作之后,应约束边界:
function newpop = constrictboundary(pop, xl, xu)
% 约束边界(边界吸收)
% pop input 种群
% xl input 自变量最小值(包含)
% xu input 自变量最大值(包含)
% newpop output 约束边界后的种群
newpop = pop;
newpop(newpop < xl) = xl;
newpop(newpop > xu) = xu;
end
选择
function newpop = selection(pop, npop)
% 选择(小值优化)
% pop input 种群1(原始种群)
% pop input 种群2(变异-交叉种群)
% newpop output 选择后的种群
newpop = pop;
index = find(calobj(npop) <= calobj(pop));
newpop(index, :) = npop(index, :);
end
主程序
主程序如下:
clc;
clear;
NP = 20; % 种群规模
D = 2; % 参数个数
G = 30; % 最大进化代数
F = 0.5; % 缩放因子
Cr = 0.8; % 交叉因子
xl = -4; % x下限(也是y下限)
xu = 4; % x上限(也是y上限)
bestvalue = zeros(3, G);
% 优化
gen = 0;
pop = initpop(NP, D, xl, xu);
objvalue = calobj(pop);
while gen < G
mpop = mutation(pop, F); % 变异
cpop = crossover(pop, mpop, Cr); % 交叉
cpop = constrictboundary(cpop, xl, xu); % 约束边界
pop = selection(pop, cpop); % 选择
objvalue = calobj(pop);
gen = gen + 1;
% 记录最优
[~, index] = min(objvalue);
bestvalue(1:2, gen) = pop(index,:)';
bestvalue(3,gen) = objvalue(index);
end
fprintf('bestX = %f, bestY = %f, bestZ = %f\n', ...
bestvalue(1,end), bestvalue(2,end), bestvalue(3,end));
% 绘图
figure(1);
x = [-4:0.1:4]; y = [-4:0.1:4];
[X, Y] = meshgrid(x, y);
Z = 3 * cos(X .* Y) + X + Y;
surf(X, Y, Z);
hold on;
scatter3(bestvalue(1,:), bestvalue(2,:), bestvalue(3,:), ...
'MarkerEdgeColor','k', 'MarkerFaceColor',[0 .75 .75]);
xlabel('x'); ylabel('y'); zlabel('z'); title('函数图');
hold off;
figure(2);
plot(bestvalue(3,:));
xlabel('进化代数'); ylabel('最优目标函数值'); title('目标函数值变化图');
执行结果
bestX = -3.947841, bestY = -4.000000, bestZ = -10.937414