栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

差分进化算法DE(学习笔记

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

差分进化算法DE(学习笔记

1. 特点

采用概率转移规则,不需要确定性的规则。

具有内在的并行性,利用个体局部信息、群体全局信息指导进一步搜索。

算法操作简单,利于求解高维度的函数优化问题。

2. 基本参数

np: 种群规模,np >= 4

f: 变异算子,决定偏差向量的缩放比例。 f∈[0,2]

大 (f>1):差分向量的扰动过大,种群收敛性能差

小:易陷入局部最优

cr: 交叉算子,控制一个实验向量参数来自于随机选择的变异向量而非原向量的概率。cr∈[0,1]

大:加速收敛

3. 基本流程

    初始化参数,随机产生初始种群,进化代数 i = 1

    评价初始种群(计算每个个体的目标函数值)

    for i = 2:iter_max

      变异操作

      交叉操作

      边界条件处理,得到临时种群

      评价临时种群

      选择操作(一对一),得到新种群

    end

    输出结果

4. 差分进化算法的其他形式

符号:DE/x/y/z

x :当前被变异的向量是“随机的”或“最佳的”。

y : 所利用的差向量的个数

z :交叉程序的操作方法 (bin、exp)

5. DE/rand/1/bin

r1 = randi([1,np]);
v(j,:) = x(r1,:) + f * (x(r2,:) - x(r3,:));

源代码如下:

%% DE/rand/1/bin
% DE/被变异的向量是随机的/差向量1个/交叉操作bin

clear;
close all;
clc;

np = 30;  %种群数量
d = 2;  %维度
iter_max = 200;  %最大迭代次数
f = 0.5;  %变异算子
cr = 0.1;  %交叉算子

x_max = 5;
x_min = -5;

x = zeros(np,d);  %初始种群
u = zeros(np,d);  %变异后的种群
v = zeros(np,d);  %交叉后的种群

%% 1.初始化种群
x = rand(np,d) * (x_max - x_min) + x_min;

%% 2.评价初始种群
for i = 1:np
    ob(i) = func(x(i,:));
end
trace(1) = min(ob);

for i = 1:iter_max-1
    %% 3.变异操作
    for j = 1:np
        r1 = randi([1,np]);
        while(r1 == j)
            r1 = randi([1,np]);
        end
        r2 = randi([1,np]);
        while(r2 == j)
            r2 = randi([1,np]);
        end
        r3 = randi([1,np]);
        while(r3 == j)
            r3 = randi([1,np]);
        end
        v(j,:) = x(r1,:) + f * (x(r2,:) - x(r3,:));
    end
    
    %% 4.交叉操作
    r = randi([1,np]);
    for j = 1:d
        cr_t = rand(1);
        if (cr_t <= cr) | (j == r)
            u(j,:) = v(j,:);
        else
            u(j,:) = x(j,:);
        end
    end
    
    %% 5.边界处理(边界吸收)
    for j = 1:d
        for k = 1:np
            if u(k,j) < x_min
                u(k,j) = x_min;
            end
            if u(k,j) > x_max
                u(k,j) = x_max;
            end
        end
    end
    
    %% 6.选择操作
    %计算变异、交叉、边界处理后的种群的适应度值
    for j = 1:np
        f1(j) = func(u(j,:));
    end
    for j = 1:np
        if f1(j) < ob(j)
            x(j,:) = u(j,:);
        end
    end
    %重新计算适应度值
    for j = 1:np
        ob(j) = func(x(j,:));
    end
    trace(i + 1) = min(ob);
end

%% 6.输出
disp( '最小值位置为:');
[sortf,index] = sort(ob);
x = x(index,:);
x = x(1,:);
x
disp( '最小值为:');
min(ob)

figure
plot(trace);
hold on;
legend_str = {'DE/rand/1/bin','DE/best/2/bin','自适应的DE/best/2/bin'};
xlabel('迭代次数');
ylabel('适应度值');
title("适应度进化曲线")

function results = func(x)
    results = 5 * cos(x(1) * x(2))+ x(1) * x(2) + x(2) * x(2) * x(2);
end
6. DE/best/2/bin

v(j,:) = x(best,:) - f * (x(r1,:) - x(r2,:) + x(r3,:) - x(r4,:));

源代码如下:

%% DE/best/2/bin
% DE/被变异的向量是最佳的/差向量2个/交叉操作bin

np = 20;  %种群数量
d = 2;  %维度
iter_max = 200;  %最大迭代次数
f = 0.5;  %变异算子
cr = 0.1;  %交叉算子

x_max = 5;
x_min = -5;

x = zeros(np,d);  %初始种群
u = zeros(np,d);  %变异后的种群
v = zeros(np,d);  %交叉后的种群

%% 1.初始化种群
x = rand(np,d) * (x_max - x_min) + x_min;

%% 2.评价初始种群
for i = 1:np
    ob(i) = func(x(i,:));
end
trace(1) = min(ob);
for i = 1:np
    if ob(i) == trace(1)
        best = i;
        break;
    end
end
    

for i = 1:iter_max-1
    %% 3.变异操作
    for j = 1:np
        r1 = randi([1,np]);
        while(r1 == j)
            r1 = randi([1,np]);
        end
        r2 = randi([1,np]);
        while(r2 == j | r2 == r1)
            r2 = randi([1,np]);
        end
        r3 = randi([1,np]);
        while(r3 == j | r3 == r1 | r3 == r2)
            r3 = randi([1,np]);
        end
        r4 = randi([1,np]);
        while(r4 == j | r4 == r1 | r4 == r2 | r4 == r3)
            r4 = randi([1,np]);
        end
        v(j,:) = x(best,:) - f * (x(r1,:) - x(r2,:) + x(r3,:) - x(r4,:));
    end
    
    %% 4.交叉操作
    r = randi([1,np]);
    for j = 1:d
        cr_t = rand(1);
        if (cr_t <= cr) | (j == r)
            u(j,:) = v(j,:);
        else
            u(j,:) = x(j,:);
        end
    end
    
    %% 5.边界处理(边界吸收)
    for j = 1:d
        for k = 1:np
            if u(k,j) < x_min
                u(k,j) = x_min;
            end
            if u(k,j) > x_max
                u(k,j) = x_max;
            end
        end
    end
    
    %% 6.选择操作
    %计算变异、交叉、边界处理后的种群的适应度值
    for j = 1:np
        f1(j) = func(u(j,:));
    end
    for j = 1:np
        if f1(j) < ob(j)
            x(j,:) = u(j,:);
        end
    end
    %重新计算适应度值
    for j = 1:np
        ob(j) = func(x(j,:));
    end
    trace(i + 1) = min(ob);
    
    for pos = 1:np
        if ob(pos) == trace(i + 1)
            best = pos;
            break;
        end
    end
end

%% 6.输出
disp( '最小值位置为:');
[sortf,index] = sort(ob);
x = x(index,:);
x = x(1,:);
x
disp( '最小值为:');
min(ob)

plot(trace);
hold on;
xlabel('迭代次数');
ylabel('适应度值');
title("适应度进化曲线")

function results = func(x)
    results = 5 * cos(x(1) * x(2))+ x(1) * x(2) + x(2) * x(2) * x(2);
end
7. 自适应差分进化算法( DE/best/2/bin基础上改进 )

自适应的变异算子

lamuda = exp(1)^(1 - iter_max/(iter_max + 1 - i));
f = f0 * 2^lamuda;
v(j,:) = x(best,:) - f * (x(r1,:) - x(r2,:) + x(r3,:) - x(r4,:));

随机范围的交叉算子(平均值0.75),有助于保持群体的多样性

cr = 0.5 * (1 + rand);

源代码如下:

%% 自适应机制 DE/best/2/bin
% DE/被变异的向量是最佳的/差向量1个/交叉操作bin
% 自适应变异算子 + 平均值为0.75的随机交叉算子

np = 30;  %种群数量
d = 2;  %维度
iter_max = 200;  %最大迭代次数
f0 = 2;  %变异算子
cr = 0.75;  %交叉算子

x_max = 5;
x_min = -5;

x = zeros(np,d);  %初始种群
u = zeros(np,d);  %变异后的种群
v = zeros(np,d);  %交叉后的种群

%% 1.初始化种群
x = rand(np,d) * (x_max - x_min) + x_min;

%% 2.评价初始种群
for i = 1:np
    ob(i) = func(x(i,:));
end
trace(1) = min(ob);
for i = 1:np
    if ob(i) == trace(1)
        best = i;
        break;
    end
end
    
for i = 1:iter_max-1
    %% 3.变异操作
    for j = 1:np
        r1 = randi([1,np]);
        while(r1 == j)
            r1 = randi([1,np]);
        end
        r2 = randi([1,np]);
        while(r2 == j | r2 == r1)
            r2 = randi([1,np]);
        end
        r3 = randi([1,np]);
        while(r3 == j | r3 == r1 | r3 == r2)
            r3 = randi([1,np]);
        end
        r4 = randi([1,np]);
        while(r4 == j | r4 == r1 | r4 == r2 | r4 == r3)
            r4 = randi([1,np]);
        end
        %自适应变异算子
        lamuda = exp(1)^(1 - iter_max/(iter_max + 1 - i));
        f = f0 * 2^lamuda;
        v(j,:) = x(best,:) - f * (x(r1,:) - x(r2,:) + x(r3,:) - x(r4,:));
    end
    
    %% 4.交叉操作
    r = randi([1,np]);
    cr = 0.5 * (1 + rand);  %平均值为0.75的随机交叉算子
    for j = 1:d
        cr_t = rand(1);
        if (cr_t <= cr) | (j == r)
            u(j,:) = v(j,:);
        else
            u(j,:) = x(j,:);
        end
    end
    
    %% 5.边界处理(边界吸收)
    for j = 1:d
        for k = 1:np
            if u(k,j) < x_min
                u(k,j) = x_min;
            end
            if u(k,j) > x_max
                u(k,j) = x_max;
            end
        end
    end
    
    %% 6.选择操作
    %计算变异、交叉、边界处理后的种群的适应度值
    for j = 1:np
        f1(j) = func(u(j,:));
    end
    for j = 1:np
        if f1(j) < ob(j)
            x(j,:) = u(j,:);
        end
    end
    %重新计算适应度值
    for j = 1:np
        ob(j) = func(x(j,:));
    end
    trace(i + 1) = min(ob);
    
    for pos = 1:np
        if ob(pos) == trace(i + 1)
            best = pos;
            break;
        end
    end
end

%% 6.输出
disp( '最小值位置为:');
[sortf,index] = sort(ob);
x = x(index,:);
x = x(1,:);
x
disp( '最小值为:');
min(ob)

plot(trace);
xlabel('迭代次数');
ylabel('适应度值');
title("适应度进化曲线");
legend(legend_str);

function results = func(x)
    results = 5 * cos(x(1) * x(2))+ x(1) * x(2) + x(2) * x(2) * x(2);
end
  8. 对比

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/725104.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号