首页 > 代码库 > Matlab微分进化算法及优化函数测试

Matlab微分进化算法及优化函数测试

微分进化(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 秒。