差分进化算法(DE)

差分进化算法

差分进化算法(differential evolution, DE)是一类基于群体的自适应全局优化算法,有较强的鲁棒性和全局寻优能力,主要用于求解实数优化问题。它从数学角度看是一种随机搜索算法,从工程角度看是一种自适应的迭代寻优过程。差分进化算法凭借其独特的优势在数据挖掘、模式识别、电磁学等领域被广泛应用。

算法流程

差分进化算法采用实数编码,基于差分的简单变异操作和“一对一”的竞争生存策略,具体步骤如下

  1. 随机初始化种群规模N,进化代数t=1;
  2. 计算初始种群中的每个个体的目标函数值;
  3. 判断是否达到终止条件或达到最大进化代数。若满足,则进化停止,将此时的最佳个体作为解输出;否则执行步骤4;
  4. 进行变异操作和交叉操作,并对边界条件进行处理,得到临时种群;
  5. 对临时种群进行评价,计算临时种群中每个个体的适应度值;
  6. 进行选择操作,得到新的种群;
  7. 进化代数t=t+1,并用新的种群代替旧种群,返回步骤3.

在这里插入图片描述

DE算法流程图
伪代码
初始化N个个体
初始化参数D、N_iter
i=1
while(t<=N_iter)
	for i=1:N
		for j=1:D
			进行变异操作和交叉操作,得到临时种群
		end for j
		计算临时种群中每个个体的适应度值
		对临时种群进行选择操作,得到新种群
	end for i
	t = t+1
end while
输出结果
MATLAB仿真实例

1.计算函数 f ( x ) = ∑ i = 1 n x i 2 ( − 20 ≤ x i ≤ 20 ) f(x)= \sum_{i=1}^n x_i^2(-20\leq x_i\leq20) f(x)=i=1nxi2(20xi20)的最小值,其中个体 x x x的维数 n = 10 n=10 n=10。这是一个简单的平方和函数,只有一个极小点 x = ( 0 , 0 , ⋯   , 0 ) x=(0,0,\cdots,0) x=(0,0,,0),理论最小值 f ( 0 , 0 , ⋯   , 0 ) = 0 f(0,0,\cdots,0)=0 f(0,0,,0)=0

仿真过程如下:

(1)初始化个体数目为 N P = 50 NP=50 NP=50,变量维数为 D = 10 D=10 D=10,最大进化代数为 G = 200 G=200 G=200,初始变异算子 F 0 = 0.4 F_0=0.4 F0=0.4,交叉算子 C R = 0.1 CR=0.1 CR=0.1,阈值 y z = 1 0 − 6 yz=10^{-6} yz=106

(2)产生初始种群,计算个体目标函数;进行变异操作、交叉操作、边界条件处理,产生临时种群,其中变异操作采用自适应变异算子,边界条件处理采用在可行域中随机产生参数向量的方式。

(3)计算临时种群个体目标函数,与原种群对应个体进行“一对一”选择操作,产生新种群。

(4)判断是否满足终止条件:若满足,则结束搜索过程,输出优化值;若不满足,则继续进行迭代优化。

优化结束后,DE目标函数曲线如下图所示

在这里插入图片描述

%% 差分进化算法求极值
clc; clear; close all;
NP = 50;  % 种群数量
D = 10;  % 变量的维数
G = 200;  % 最大的进化代数
F0  = 0.4; % 初始变异算子
CR = 0.1;  % 交叉算子
Xs = 20;   % 上限
Xx = -20;  % 下限
yz = 10^-6;  % 阈值
% 赋初值
x = zeros(D, NP);  % 初始种群
v = zeros(D, NP);  % 变异种群
u = zeros(D, NP);  % 选择种群
x = rand(D, NP) * (Xs - Xx) + Xx;  % 赋初值

%%%%%%%%%%%%%%计算目标函数%%%%%%%%%%%%%%%%
for m=1:NP
    Ob(m) = func1(x(:, m));
end
trace(1) = min(Ob);
%%%%%%%%%%%%%%差分进化循环%%%%%%%%%%%%%%%%
for gen = 1:G
    %%%%%%%%%%%%%%%%%%%%%%%%% 变异操作%%%%%%%%%%%%%%%%
    %%%%%%%%%%%%%%%%%%%%% 自适应变异算子%%%%%%%%%%%%%%%
    lambda = exp(1-G/(G+1-gen));
    F = F0*2^(1-lambda);
    %%%%%%%%%%%%%%%% r1, r2, r3和m互不相同%%%%%%%%%%%%%%%%
    for m = 1:NP
        r1 = randi([1, NP], 1, 1);
        while(r1==m)
            r1 = randi([1, NP], 1, 1);
        end
        r2 = randi([1, NP], 1, 1);
        while(r2==m) || (r2==r1)
            r2 = randi([1, NP], 1, 1);
        end
        r3 = randi([1, NP], 1, 1);
        while (r3==m) || (r3==r1) || (r3==r2)
            r3 = randi([1, NP], 1, 1);
        end
        v(:,m) = x(:,r1) + F*(x(:,r2)-x(:,r3));
    end
    %%%%%%%%%%%%%%%%%%%%%%%交叉操作%%%%%%%%%%%%%%%%%%%%%%%%%%%
    r = randi([1, D], 1, 1);
    for n = 1:D
        cr = rand(1);
        if(cr<=CR) || (n==r)
            u(n, :) = v(n, :);
        else
            u(n, :) = x(n, :);
        end
    end
    %%%%%%%%%%%%%%%%%边界条件的处理%%%%%%%%%%%%%%%%%%%%%%%
    for n = 1:D
        for m = 1:NP
            if(u(n,m)<Xx || u(n,m)>Xs)
                u(n,m) = rand*(Xs-Xx) + Xx;
            end
        end
    end
    %%%%%%%%%%%%%%%%%%%%%选择操作%%%%%%%%%%%%%%%%%%%%%%%%%%
    for m = 1:NP
        Ob1(m) = func1(u(:, m));
    end
    for m = 1:NP
        if Ob1(m) < Ob(m)
            x(:, m) = u(:, m);
        end
    end
    for m = 1:NP
        Ob(m) = func1(x(:, m));
    end
    trace(gen+1) = min(Ob);
    if min(Ob(m)) <yz
        break
    end
end
[SortOb, Index] = sort(Ob);
x = x(:, Index);
X = x(:, 1);  % 最优变量
Y = min(Ob);  % 最优值
%%%%%%%%%%%%%%%%%%画图%%%%%%%%%%%%%%%%%%
figure
plot(trace);
xlabel('迭代次数');
ylabel('目标函数值');
title('DE目标函数曲线')
%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%%%%%%%
function result = func1(x)
summ = sum(x.^2);
result  = summ;
end
  1. 求函数 f ( x , y ) = 3 cos ⁡ ( x y ) + x + y f(x,y)=3\cos(xy)+x+y f(x,y)=3cos(xy)+x+y的最小值,其中x的取值范围为[-4,4],y的取值范围为[-4,4]。这是一个有多个局部极值的函数,其函数值图形如下图所示,其MATLAB实现程序如下:
clc; clear; close all;
%%%%%%%%%%%%%%%f(x,y) =3cos(xy)+x+y%%%%%%%%%%%%%%%%
x = -4:0.02:4;
y = -4:0.02:4;
N = size(x, 2);
for i = 1:N
    for j = 1:N
       z(i,j) = 3*cos(x(i)*y(j))+x(i)+y(j);
    end
end
mesh(x, y, z);
xlabel('x');
ylabel('y');

在这里插入图片描述

仿真过程如下:

(1)初始化个体数目为NP=20,变量维数为D=2,最大进化代数为G=100,变异算子F=0.5,交叉算子CR=0.1;

(2)产生初始种群,计算个体目标函数;进行变异操作、交叉操作、边界条件处理,产生临时种群,其中边界条件处理采用边界吸收方式;

(3)计算临时种群个体目标函数,与原种群对应个体进行“一对一”选择操作,产生新种群;

(4)判断是否满足终止条件:若满足,则结束搜索过程,输出优化值;若不满足,则继续进行迭代优化。、

优化结束后,DE目标函数曲线如下图所示

在这里插入图片描述

clc; clear; close all;
%%%%%%%%%%%%%%%f(x,y) =3cos(xy)+x+y%%%%%%%%%%%%%%%%
x = -4:0.02:4;
y = -4:0.02:4;
N = size(x, 2);
for i = 1:N
    for j = 1:N
       z(i,j) = 3*cos(x(i)*y(j))+x(i)+y(j);
    end
end
mesh(x, y, z);
xlabel('x');
ylabel('y');

%% 差分进化算法求极值
NP = 20;  % 种群数量
D = 2;  % 变量的维数
G = 100;  % 最大的进化代数
F  = 0.5; % 初始变异算子
CR = 0.1;  % 交叉算子
Xs = 4;   % 上限
Xx = -4;  % 下限
yz = 10^-6;  % 阈值
% 赋初值
x = zeros(D, NP);  % 初始种群
v = zeros(D, NP);  % 变异种群
u = zeros(D, NP);  % 选择种群
x = rand(D, NP) * (Xs - Xx) + Xx;  % 赋初值

%%%%%%%%%%%%%%计算目标函数%%%%%%%%%%%%%%%%
for m=1:NP
    Ob(m) = func2(x(:, m));
end
trace(1) = min(Ob);
%%%%%%%%%%%%%%差分进化循环%%%%%%%%%%%%%%%%
for gen = 1:G
    %%%%%%%%%%%%%%%%%%%%%%%%% 变异操作%%%%%%%%%%%%%%%%
    %%%%%%%%%%%%%%%% r1, r2, r3和m互不相同%%%%%%%%%%%%%%%%
    for m = 1:NP
        r1 = randi([1, NP], 1, 1);
        while(r1==m)
            r1 = randi([1, NP], 1, 1);
        end
        r2 = randi([1, NP], 1, 1);
        while(r2==m) || (r2==r1)
            r2 = randi([1, NP], 1, 1);
        end
        r3 = randi([1, NP], 1, 1);
        while (r3==m) || (r3==r1) || (r3==r2)
            r3 = randi([1, NP], 1, 1);
        end
        v(:,m) = x(:,r1) + F*(x(:,r2)-x(:,r3));
    end
    %%%%%%%%%%%%%%%%%%%%%%%交叉操作%%%%%%%%%%%%%%%%%%%%%%%%%%%
    r = randi([1, D], 1, 1);
    for n = 1:D
        cr = rand(1);
        if(cr<=CR) || (n==r)
            u(n, :) = v(n, :);
        else
            u(n, :) = x(n, :);
        end
    end
    %%%%%%%%%%%%%%%%%边界条件的处理%%%%%%%%%%%%%%%%%%%%%%%
    for n = 1:D
        for m = 1:NP
            if(u(n,m)<Xx)
                u(n,m) = Xx;
            end
            if(u(n,m)>Xs)
                u(n,m) = Xs;
            end
        end
    end
    %%%%%%%%%%%%%%%%%%%%%选择操作%%%%%%%%%%%%%%%%%%%%%%%%%%
    for m = 1:NP
        Ob1(m) = func2(u(:, m));
    end
    for m = 1:NP
        if Ob1(m) < Ob(m)
            x(:, m) = u(:, m);
        end
    end
    for m = 1:NP
        Ob(m) = func2(x(:, m));
    end
    trace(gen+1) = min(Ob);
%     if min(Ob(m)) <yz
%         break
%     end
end
[SortOb, Index] = sort(Ob);
x = x(:, Index);
X = x(:, 1);  % 最优变量
Y = min(Ob);  % 最优值
%%%%%%%%%%%%%%%%%%画图%%%%%%%%%%%%%%%%%%
figure
plot(trace);
xlabel('迭代次数');
ylabel('目标函数值');
title('DE目标函数曲线')
%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%%%%%%%
function result = func2(x)
result  = 3*cos(x(1)*x(2))+x(1)+x(2);
end
  1. 用离散差分进化算法求函数 f ( x , y ) = − ( ( x 2 + y − 1 ) 2 + ( x + y 2 − 7 ) 2 ) / 200 + 10 f(x,y)=-((x^2+y-1)^2+(x+y^2-7)^2)/200+10 f(x,y)=((x2+y1)2+(x+y27)2)/200+10的最大值,其中 x x x的取值为-100~100之间的整数, y y y的取值为-100~100之间的整数,其函数值图形如下图所示

在这里插入图片描述

%%%%F(x,y)=-((x~2+y-1).^2+(x+y~2-7)^2)/200+10%%%%
clc; clear; close all;
x=-100:1:100;
y=-100:1:100;
N=size(x,2);
for i=1:N
    for j=1:N
        z(i,j)=-((x(i)^2+y(j)-1).^2+(x(i) +y(j)^2-7)^2)/200+10;
    end
end
mesh(x,y,z);
xlabel('x');
ylabel('y');

仿真过程如下:

(1)初始化个体数目为NP=20,变量维数为D=2,最大进化代数为G=100,变异算子F=0.5,交叉算子CR=0.1

(2)产生数值为[-100,100]内整数的初始种群,计算个体目标函数;进行变异操作,对变异后的种群内数值进行取整操作,然后进行交叉操作、边界条件处理操作,产生临时种群,其中边界条件处理采用边界吸收方式

(3)计算临时种群个体目标函数,与原种群对应个体进行“一对一”选择操作,产生新种群

(4)判断是否满足终止条件:若满足,则结束搜索过程,输出优化值;若不满足,则继续进行迭代优化

优化结束后,DE目标函数曲线如下图所示

在这里插入图片描述

%%%%F(x,y)=-((x~2+y-1).^2+(x+y~2-7)^2)/200+10%%%%
clc; clear; close all;
x=-100:1:100;
y=-100:1:100;
N=size(x,2);
for i=1:N
    for j=1:N
        z(i,j)=-((x(i)^2+y(j)-1).^2+(x(i) +y(j)^2-7)^2)/200+10;
    end
end
mesh(x,y,z);
xlabel('x');
ylabel('y');

%% 差分进化算法求极值
NP = 20;  % 种群数量
D = 2;  % 变量的维数
G = 100;  % 最大的进化代数
F  = 0.5; % 初始变异算子
CR = 0.1;  % 交叉算子
Xs = 100;   % 上限
Xx = -100;  % 下限
yz = 10^-6;  % 阈值
% 赋初值
x = zeros(D, NP);  % 初始种群
v = zeros(D, NP);  % 变异种群
u = zeros(D, NP);  % 选择种群
x = randi([Xx, Xs], D, NP);  % 赋初值

%%%%%%%%%%%%%%计算目标函数%%%%%%%%%%%%%%%%
for m=1:NP
    Ob(m) = func3(x(:, m));
end
trace(1) = max(Ob);
%%%%%%%%%%%%%%差分进化循环%%%%%%%%%%%%%%%%
for gen = 1:G
    %%%%%%%%%%%%%%%%%%%%%%%%% 变异操作%%%%%%%%%%%%%%%%
    %%%%%%%%%%%%%%%% r1, r2, r3和m互不相同%%%%%%%%%%%%%%%%
    for m = 1:NP
        r1 = randi([1, NP], 1, 1);
        while(r1==m)
            r1 = randi([1, NP], 1, 1);
        end
        r2 = randi([1, NP], 1, 1);
        while(r2==m) || (r2==r1)
            r2 = randi([1, NP], 1, 1);
        end
        r3 = randi([1, NP], 1, 1);
        while (r3==m) || (r3==r1) || (r3==r2)
            r3 = randi([1, NP], 1, 1);
        end
        v(:,m) = floor(x(:,r1) + F*(x(:,r2)-x(:,r3)));
    end
    %%%%%%%%%%%%%%%%%%%%%%%交叉操作%%%%%%%%%%%%%%%%%%%%%%%%%%%
    r = randi([1, D], 1, 1);
    for n = 1:D
        cr = rand(1);
        if(cr<=CR) || (n==r)
            u(n, :) = v(n, :);
        else
            u(n, :) = x(n, :);
        end
    end
    %%%%%%%%%%%%%%%%%边界条件的处理%%%%%%%%%%%%%%%%%%%%%%%
    for n = 1:D
        for m = 1:NP
            if(u(n,m)<Xx)
                u(n,m) = Xx;
            end
            if(u(n,m)>Xs)
                u(n,m) = Xs;
            end
        end
    end
    %%%%%%%%%%%%%%%%%%%%%选择操作%%%%%%%%%%%%%%%%%%%%%%%%%%
    for m = 1:NP
        Ob1(m) = func3(u(:, m));
    end
    for m = 1:NP
        if Ob1(m) > Ob(m)
            x(:, m) = u(:, m);
        end
    end
    for m = 1:NP
        Ob(m) = func3(x(:, m));
    end
    trace(gen+1) = max(Ob);
%     if min(Ob(m)) <yz
%         break
%     end
end
[SortOb, Index] = sort(Ob);
x = x(:, Index);
X = x(:, end);  % 最优变量
Y = max(Ob);  % 最优值
%%%%%%%%%%%%%%%%%%画图%%%%%%%%%%%%%%%%%%
figure
plot(trace);
xlabel('迭代次数');
ylabel('目标函数值');
title('DE目标函数曲线')
%%%%%%%%%%%%适应度函数%%%%%%%%%%%%%%%%%%%
function result = func3(x)
result  = -((x(1)^2+x(2)-1).^2+(x(1) +x(2)^2-7)^2)/200+10;
end

参考

[1] 包子阳等. 智能优化算法及其MATLAB实例(第3版)[M]. 北京: 电子工业出版社, 2020.

  • 20
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: DE(Differential Evolution,差分进化)算法是一种常用的全局优化算法,其基本思想是利用种群中个体的差异性进行搜索。 以下是使用Python实现DE算法的完整代码: ```python import numpy as np class DE: def __init__(self, func, bounds, npop, F=0.8, CR=0.9, maxiter=1000, tol=1e-6): """ :param func: 目标函数 :param bounds: 参数边界 :param npop: 种群数量 :param F: 缩放因子 :param CR: 交叉概率 :param maxiter: 最大迭代次数 :param tol: 收敛容差 """ self.func = func self.bounds = bounds self.npop = npop self.F = F self.CR = CR self.maxiter = maxiter self.tol = tol def optimize(self): nparams = len(self.bounds) # 初始化种群 pop = np.random.rand(self.npop, nparams) for i in range(nparams): pop[:, i] = self.bounds[i][0] + pop[:, i] * (self.bounds[i][1] - self.bounds[i][0]) # 计算初始适应度 fitness = np.array([self.func(p) for p in pop]) # 记录最优解 best_params = pop[np.argmin(fitness)] best_fitness = np.min(fitness) # 开始迭代 for i in range(self.maxiter): new_pop = np.zeros((self.npop, nparams)) for j in range(self.npop): # 随机选择3个个体 idxs = np.random.choice(self.npop, 3, replace=False) x1, x2, x3 = pop[idxs] # 生成变异个体 v = x1 + self.F * (x2 - x3) # 交叉操作 u = np.zeros(nparams) jrand = np.random.randint(nparams) for k in range(nparams): if np.random.rand() < self.CR or k == jrand: u[k] = v[k] else: u[k] = pop[j, k] # 边界处理 u = np.clip(u, self.bounds[:, 0], self.bounds[:, 1]) # 选择操作 new_fitness = self.func(u) if new_fitness < fitness[j]: new_pop[j] = u fitness[j] = new_fitness if new_fitness < best_fitness: best_params = u best_fitness = new_fitness else: new_pop[j] = pop[j] # 判断是否收敛 if np.max(np.abs(new_pop - pop)) < self.tol: break pop = new_pop return best_params, best_fitness ``` 使用方法: ```python # 定义目标函数 def func(x): return np.sum(x ** 2) # 定义参数边界 bounds = np.array([[-5.12, 5.12]] * 10) # 定义DE算法对象 de = DE(func, bounds, npop=50, F=0.8, CR=0.9, maxiter=1000, tol=1e-6) # 开始优化 best_params, best_fitness = de.optimize() # 输出最优解和最优适应度 print("最优解:", best_params) print("最优适应度:", best_fitness) ``` 注:上述代码中的目标函数为简单的二次函数,实际使用时需要根据具体问题定义相应的目标函数。 ### 回答2: DE(差分进化)算法是一种全局优化算法,用于解决连续优化问题。其完整的代码如下所示: 1. 导入所需的Python库: ```python import random import numpy as np ``` 2. 定义DE算法的主要函数: ```python def differential_evolution(cost_func, bounds, pop_size, F, CR, max_iter): # 初始化种群 n_params = len(bounds) population = np.zeros((pop_size, n_params)) for i in range(pop_size): for j in range(n_params): population[i, j] = random.uniform(bounds[j][0], bounds[j][1]) # 迭代优化 for i in range(max_iter): for j in range(pop_size): # 选择三个不同的个体 candidates = [k for k in range(pop_size) if k != j] a, b, c = random.sample(candidates, 3) # 生成新个体 mutant = population[a] + F * (population[b] - population[c]) mutant = np.clip(mutant, bounds[:, 0], bounds[:, 1]) # 交叉操作 cross_points = np.random.rand(n_params) < CR if not np.any(cross_points): cross_points[np.random.randint(0, n_params)] = True trial = np.where(cross_points, mutant, population[j]) # 评估新个体的适应度 cost_trial = cost_func(trial) cost_current = cost_func(population[j]) # 更新种群 if cost_trial < cost_current: population[j] = trial # 返回最优个体和最优适应度 best_index = np.argmin([cost_func(ind) for ind in population]) best_individual = population[best_index] best_fitness = cost_func(best_individual) return best_individual, best_fitness ``` 3. 定义一个优化问题的目标函数,示例为Rastringin函数: ```python def rastringin(x): return sum([(xi**2 - 10 * np.cos(2 * np.pi * xi) + 10) for xi in x]) ``` 4. 设置问题的边界和其他参数: ```python bounds = [(-5.12, 5.12)] * 10 # 问题的边界 pop_size = 50 # 种群大小 F = 0.5 # 缩放因子 CR = 0.7 # 交叉概率 max_iter = 100 # 最大迭代次数 ``` 5. 调用DE算法进行优化,得到最优解和最优适应度: ```python best_individual, best_fitness = differential_evolution(rastringin, bounds, pop_size, F, CR, max_iter) print("最优解:", best_individual) print("最优适应度:", best_fitness) ``` 这段代码实现了DE算法的基本框架和一个示例目标函数的优化。可以根据实际问题进行适当的修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值