差分進化算法求函數 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
MATLAB
初始化種羣
目標函數有兩個參數,生成每個個體有兩個基因的種羣:
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
MATLAB
變異
變異函數如下:
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,:));endend
MATLAB
交叉
交叉函數如下:
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
MATLAB
在交叉操作之後,應約束邊界:
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
MATLAB
選擇
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
MATLAB
主程序
主程序如下:
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);endfprintf('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('目標函數值變化圖');
MATLAB
執行結果
bestX = -3.947841, bestY = -4.000000, bestZ = -10.937414