微分进化(Difference Evolution,DE)算法是一种优化算法,据称其比GA(遗传算法)等更为优秀。
借鉴网上实现的DE算法,用Matlab实现了对若干函数优化问题的解法,代码如下:
function [] = de_test clear all; close all; clc; %解:X = [0, 0, ...] %nVar = 30 %dims: [-30, 30] function fitness = sphere(vals) prod = vals .* vals; fitness = sum(prod, 2); end %f(x) = 1/4000 * sum^n_1(x_i)^2 - prod^n_1 * cos(x_i/sqrt(i)) + 1 %f* = 0, x* = [0, 0, ...]; %nVar = 30 %dims: [-600, 600] function fitness = griewank(vals) [h w] = size(vals); p1 = vals.^2; p1 = 1/4000 .* sum(p1, 2); t = sqrt([1:w]); p2 = vals ./ repmat(t, h, 1); p2 = cos(p2); p2 = prod(p2, 2); fitness = p1 - p2 + 1; end %解: X = [1, 1, 1, ...] function fitness = RosenBroek(vals) [k n] = size(vals); vals1 = vals(:, 1:n-1); vals2 = vals(:, 2:n); tmp = vals2 - vals1 .* vals1; tmp = 100 * tmp .* tmp; tmp1 = (vals1 - 1).^2; fitness = sum(tmp, 2) + sum(tmp1, 2); end %许多局部最小值,最优解:X = [0, 0], 固定2个变量 function fitness = Rastrigin (X) v = X.^2 - 10 .* cos(2 * pi .* X) + 10; fitness = sum(v, 2); %fitness = 20 + X(:, 1).^2 + X(:, 2).^2 - 10 .* (cos(2 * pi * X(:, 1)) + cos(2 * pi * X(:, 2))); end %参数 popSize = 100; % 群规模 F = 0.5; % 突变因子 C = 0.9; % 交叉率 iterTimes = 300;% 迭代次数 Run = 4; % 测试轮次 id = [1:popSize]; %结果 bestFit = 1e5; %设取最小值 bestGene = []; for r = 1:Run %轮次 Func = r; % 测试适应度函数 switch Func case 1 Func = @sphere; Xmin = -100; Xmax = 100; nVar = 30; case 2 Func = @griewank; Xmin = -600; Xmax = 600; nVar = 2; case 3 nVar = 2; Func = @RosenBroek; Xmin = -100; Xmax = 100; case 4 nVar = 2; Func = @Rastrigin Xmin = -5.12; Xmax = 5.12; end; Func tic; %1.初始化种群 X = Xmin + rand(popSize, nVar) * Xmax; %2.每轮迭代 for i = 1:iterTimes X0 = X; % F = 2 * (1 - (i-1)/iterTimes); %个体突变得到V for j = 1:popSize ids = id; ids(j) = []; rids = randperm(popSize - 1, 3); rids = ids(rids); V = X(rids(1), :) + F * (X(rids(2), :) - X(rids(3), :)); %对V(j, :)值域检查 ids = find(V < Xmin); if length(ids) > 0 V(ids) = Xmin; end; ids = find(V > Xmax); if length(ids) > 0 V(ids) = Xmax; end; %对每个X和V的配对,进行交叉操作,结果存在U中 jrand = floor(rand() * nVar + 1); %必交叉项,保证至少一个交叉 for n = 1:nVar R1 = rand(); if (R1 < C || n == jrand) U = V; %保留子代基因 else U = X(j, :); %保留父代基因 end end %在子代和父代间做选择运算 if Func(U) < Func(X(j, :)) Tr = U; else Tr=X(j, :); end % 更新种群基因 X(j,:) = Tr; %计算新的适应度 fitness = Func(X(j,:)); %记录全局最优解 if fitness < bestFit bestFit = fitness; bestGene = X(j, :); end; end %结束个体更新 end bestGene bestFit toc end end
运行结果如下:
Func =
@de_test/sphere
bestGene =
Columns 1 through 15
-7.5570 -11.9099 9.9957 -37.8403 -17.9445 -7.1438 -21.4304 -33.6260 -22.1812 -66.1438 0.9014 -39.6724 -0.3175 -56.4815 26.5422
Columns 16 through 30
6.5446 -31.9653 -9.3640 -37.1629 -23.7325 2.7271 -6.3413 -21.3204 -13.1450 28.7402 -28.8170 -22.6226 10.9031 -16.6128 -14.7637
bestFit =
2.0583e+04 (从此结果看,算法效果不佳)
时间已过 2.285354 秒。
Func =
@de_test/griewank
bestGene =
1.0e-08 *
0.1702 0.1424
bestFit =
0
时间已过 3.337347 秒。
Func =
@de_test/RosenBroek
bestGene =
1.0e-08 *
0.1702 0.1424
bestFit =
0
时间已过 1.747765 秒。
Func =
@de_test/Rastrigin
Func =
@de_test/Rastrigin
bestGene =
1.0e-08 *
0.1702 0.1424
bestFit =
0
时间已过 1.403871 秒。
Matlab微分进化算法及优化函数测试