差分進化算法(DE)求函數(shù)最小值

差分進化算法求函數(shù) Z = 3 * cos(X .* Y) + X + Y , -4 <= X <= 4, -4 <= Y <= 4。

函數(shù)圖片

計算目標函數(shù)值

計算目標函數(shù)值的函數(shù):

function z = calobj (pop)
% 計算目標函數(shù)值
% pop       input  種群
% z         output 目標函數(shù)值
z = 3 * cos(pop(:,1) .* pop(:,2)) + pop(:,1) + pop(:,2);
end

初始化種群

目標函數(shù)有兩個參數(shù),生成每個個體有兩個基因的種群:

function pop = initpop(popsize, chromlength, xl, xu)
% 生成初始種群
% popsize           input  種群規(guī)模
% chromlengt        input  染色體長度
% xl                input  x下限
% xu                input  x上限
% pop               output 種群
pop = rand(popsize, chromlength) * (xu - xl) + xl;
end

變異

變異函數(shù)如下:

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

交叉

交叉函數(shù)如下:

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

在交叉操作之后,應(yīng)約束邊界:

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)
% 選擇(小值優(yōu)化)
% 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;       % 種群規(guī)模
D   = 2;        % 參數(shù)個數(shù)
G   = 30;       % 最大進化代數(shù)
F   = 0.5;      % 縮放因子
Cr  = 0.8;      % 交叉因子

xl  = -4;       % x下限(也是y下限)
xu  = 4;        % x上限(也是y上限)

bestvalue = zeros(3, G);

% 優(yōu)化
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;
    
    % 記錄最優(yōu)
    [~, 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('函數(shù)圖');
hold off;

figure(2);
plot(bestvalue(3,:));
xlabel('進化代數(shù)'); ylabel('最優(yōu)目標函數(shù)值'); title('目標函數(shù)值變化圖');

執(zhí)行結(jié)果

bestX = -3.947841, bestY = -4.000000, bestZ = -10.937414

最優(yōu)點圖
目標值變化圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容