差分进化算法(DE)求函数最小值

差分进化算法求函数 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

最优点图
目标值变化图

你可能感兴趣的:(差分进化算法(DE)求函数最小值)