差分进化算法原理及其MATLAB/Python代码

news2024/11/15 13:59:58

1.算法简介

引用自:Storn R, Price K. Differential evolution–a simple and efficient heuristic for global optimization over continuous spaces[J]. Journal of global optimization, 1997, 11: 341-359.

在这里插入图片描述
今天给大家带来的是一个非常经典的智能优化算法–差分进化算法(DE),说它是现有各类优化算法的鼻祖之一也不为过(除此之外还有PSO、GA、蚁群优化算法ACO等)。小编在本科阶段打数学建模竞赛最钟情的算法就是本文介绍的差分进化算法DE,即使它似乎没那么新颖,但小编认为其核心思想与独特的算法设计值得每一位研究优化算法的同学学习,或许会启发你的idea哦~

首先简单介绍一下本文的主角,差分进化算法(Differential Evolution,简称DE)是一种用于求解优化问题的现代启发式算法,尤其擅长于解决高维、非线性、多模态的连续优化问题。DE是由Rainer Storn和Kenneth Price在1995年提出的,它是基于群体智能的策略,类似于遗传算法,但有着自己独特的优势和简化的设计。

2.整体架构流程

在了解差分进化算法之前我建议各位可以看一下有关遗传算法(GA)的原理,因为差分进化算法是基于遗传算法(GA)的改进版,这里我放个我看着还不错的讲解链接:遗传算法原理及其matlab程序实现

相对于遗传而言,其主要改进如下:(遗传算法简称GA,差分进化简称DE)

  • 编码方式:GA使用二进制编码,DE使用实数编码,DE能够直接处理连续优化问题,且无需进行编码和解码的过程。
  • 变异操作:GA的变异通过随机改变染色体上的基因来实现。DE中的变异是通过加权差分向量来生成新个体,具有更强的方向性和探索性。
  • 交叉操作:GA中的交叉操作类似于生物遗传学中的有性繁殖。DE中的交叉则更多地表现为参数混合,即在一定概率下选择突变向量或目标向量的参数,这一过程通常称为“差分交叉”。
  • 参数控制:DE控制参数较少,而GA多,DE的调参更简单。

2.1 差分进化(Differential Evolution, DE)算法概述

差分进化(DE)是一种并行直接搜索方法,它利用NP个D维参数向量作为每一代的种群,形式如下:

x i G ; i = 1 ; 2 ; . . . ; N P ( 1 ) x_i^G ; i = 1 ; 2 ; . . . ; NP \quad (1) xiG;i=1;2;...;NP(1)

其中,(G)代表代数,(NP)在整个最小化过程中保持不变。初始向量种群随机选取,应当覆盖整个参数空间。通常假定所有随机决策遵循均匀概率分布,除非另有说明。如果有初步解存在,初始种群可以通过在标称解(x_{nom};0)上加上正态分布的随机偏差来生成。

DE通过将两个种群向量之差的加权值加上第三个向量来生成新的参数向量,这一操作称为突变。突变向量的参数随后与另一个预设向量(目标向量)的参数混合,产生所谓的试用向量。这一参数混合过程常被称为交叉(crossover)。如果试用向量产生的代价函数值小于目标向量,则试用向量将在下一代中取代目标向量,这一过程称为选择。每个种群向量在一代中都必须至少一次作为目标向量,因此一代中有(NP)次竞争。

2.2 DE的基本策略具体描述如下:

2.2.1 突变

对于每个目标向量(x_i^G ; i = 1 ; 2 ; 3 ; . . . ; NP),根据下式生成突变向量:

v i G + 1 = x r 1 G + F ⋅ ( x r 2 G − x r 3 G ) ( 2 ) v_i^{G+1} = x_{r1}^G + F \cdot (x_{r2}^G - x_{r3}^G) \quad (2) viG+1=xr1G+F(xr2Gxr3G)(2)

2.2.2 交叉

为了增加扰动参数向量的多样性,引入了交叉。为此,形成试用向量:

u i G + 1 = ( u 1 i G + 1 ; u 2 i G + 1 ; . . . ; u D i G + 1 ) u_i^{G+1} = (u_{1i}^{G+1} ; u_{2i}^{G+1} ; . . . ; u_{Di}^{G+1}) uiG+1=(u1iG+1;u2iG+1;...;uDiG+1)

其中,

u j i ; G + 1 = { v j i ; G + 1 if  ( r  andb ( j ) < C R )  or  j = r n b r ( i ) x j i ; G if  ( r  andb ( j ) > C R )  and  j ≠ r n b r ( i ) u_j^{i;G+1} = \begin{cases} v_j^{i;G+1} & \text{if } (r \text{ andb}(j) < C_R ) \text{ or } j = r_{nbr} (i) \\ x_j^{i;G} & \text{if } (r \text{ andb}(j) > C_R ) \text{ and } j \neq r_{nbr} (i) \end{cases} uji;G+1={vji;G+1xji;Gif (r andb(j)<CR) or j=rnbr(i)if (r andb(j)>CR) and j=rnbr(i)

2.2.3 选择

为了决定是否成为下一代(G + 1)的成员,试用向量(u_i{G+1})与目标向量(x_iG)采用贪心准则进行比较。如果(u_i{G+1})产生的代价函数值小于(x_iG),则(x_i{G+1})设置为(u_i{G+1});否则,保留旧值(x_i^G)。

3.伪代码

原论文中使用了基于C语言格式的伪代码:

while (count < gen_max):  # Halt after gen_max generations.
    for (i=0; i<NP; i++):  # Start loop through population.
        a=rnd_uni() * NP; while (a==i);  # Randomly pick 3 vectors, all different.
        b=rnd_uni() * NP; while ((b==i || b==a));
        c=rnd_uni() * NP; while ((c==i || c==a || c==b));
        j=rnd_uni() * D;  # Randomly pick the first parameter.

        for (k=1; k<D; k++):  # Load D parameters into trial[].
            if (rnd_uni() < CR || k==D):
                trial[j]=x1[a][j]+F*(x1[b][j]-x1[c][j]);  # Source for trial[j] is a random vector plus weighted differential.
            else:
                trial[j]=x1[i][j];  # Trial parameter comes from target vector.
            j=(j+1)%D;  # Get next parameter, modulo D.

        score=evaluate(trial);  # Evaluate trial with your function.
        if (score<=cost[i]):  # If trial[] improves on x1[i][].
            for (j=0; j<D; j++) x2[i][j]=trial[j];  # Move trial[] to secondary array and store improved cost.
        else:
            for (j=0; j<D; j++) x2[i][j]=x1[i][j];  # Otherwise, move x1[i][] to secondary array.

    for (i=0; i<NP; i++):  # After each generation.
        for (j=0; j<D; j++) x1[i][j]=x2[i][j];  # Move secondary array into primary array.
    count++;  # End of generation...increment counter.

这个伪代码展示了差分进化算法的核心循环,其中包括了三个主要步骤:突变/重组、评估/选择以及种群更新。在这个循环中,首先从当前种群中随机选择三个不同的个体(a、b、c),然后对每个维度的参数进行突变和重组,生成一个新的候选解(trial)。接着,评估候选解的适应度,并与当前个体的适应度进行比较,若候选解更好,则将其替换掉当前个体。最后,在每一代结束时,将辅助数组中的个体复制回主数组,以便开始新的一代。计数器count记录了已经完成的迭代次数,当达到最大迭代次数gen_max时,算法停止。

4. MATLAB与Python代码

4.1 MATLAB 函数

function [best_solution, best_cost] = differential_evolution(evaluate_func, D, NP, F, CR, gen_max)
    % 差分进化算法
    % 输入参数:
    %   evaluate_func: 评估函数,用于计算解的适应度
    %   D: 问题的维度
    %   NP: 种群大小
    %   F: 缩放因子
    %   CR: 交叉率
    %   gen_max: 最大迭代次数
    % 输出参数:
    %   best_solution: 最优解
    %   best_cost: 最优解的适应度值

    % 初始化种群
    x1 = rand(NP, D);  % 随机生成初始种群
    x2 = zeros(NP, D);  % 用于存储新一代种群
    cost = zeros(NP, 1);  % 存储每个个体的适应度值
    
    % 评估初始种群
    for i = 1:NP
        cost(i) = evaluate_func(x1(i, :));
    end
    
    count = 0;  % 迭代计数器
    while count < gen_max
        for i = 1:NP  % 对每个个体进行操作
            % 随机选择三个不同的向量
            a = randi(NP);
            while a == i
                a = randi(NP);
            end
            
            b = randi(NP);
            while b == i || b == a
                b = randi(NP);
            end
            
            c = randi(NP);
            while c == i || c == a || c == b
                c = randi(NP);
            end
            
            % 创建试验向量
            j = randi(D);  % 随机选择一个维度开始
            trial = x1(i, :);  % 初始化试验向量
            for k = 1:D
                if rand() < CR || k == D  % 判断是否进行交叉
                    % 差分变异
                    trial(j) = x1(a, j) + F * (x1(b, j) - x1(c, j));
                end
                j = mod(j, D) + 1;  % 移动到下一个维度
            end
            
            % 评估试验向量
            trial_cost = evaluate_func(trial);
            
            % 选择:如果试验向量更优,则替换原个体
            if trial_cost <= cost(i)
                x2(i, :) = trial;
                cost(i) = trial_cost;
            else
                x2(i, :) = x1(i, :);
            end
        end
        
        % 更新种群
        x1 = x2;
        count = count + 1;  % 迭代次数加1
    end
    
    % 找到最优解
    [best_cost, idx] = min(cost);
    best_solution = x1(idx, :);
end

4.2 Python 函数

import numpy as np

def differential_evolution(evaluate_func, D, NP, F, CR, gen_max):
    """
    差分进化算法
    
    参数:
    evaluate_func : 函数
        评估函数,用于计算解的适应度
    D : int
        问题的维度
    NP : int
        种群大小
    F : float
        缩放因子
    CR : float
        交叉率
    gen_max : int
        最大迭代次数
    
    返回:
    best_solution : numpy.ndarray
        最优解
    best_cost : float
        最优解的适应度值
    """
    
    # 初始化种群
    x1 = np.random.rand(NP, D)  # 随机生成初始种群
    x2 = np.zeros((NP, D))  # 用于存储新一代种群
    cost = np.zeros(NP)  # 存储每个个体的适应度值
    
    # 评估初始种群
    for i in range(NP):
        cost[i] = evaluate_func(x1[i])
    
    count = 0  # 迭代计数器
    while count < gen_max:
        for i in range(NP):  # 对每个个体进行操作
            # 随机选择三个不同的向量
            a, b, c = np.random.choice(np.delete(np.arange(NP), i), 3, replace=False)
            
            # 创建试验向量
            j = np.random.randint(D)  # 随机选择一个维度开始
            trial = x1[i].copy()  # 初始化试验向量
            for k in range(D):
                if np.random.rand() < CR or k == D-1:  # 判断是否进行交叉
                    # 差分变异
                    trial[j] = x1[a, j] + F * (x1[b, j] - x1[c, j])
                j = (j + 1) % D  # 移动到下一个维度
            
            # 评估试验向量
            trial_cost = evaluate_func(trial)
            
            # 选择:如果试验向量更优,则替换原个体
            if trial_cost <= cost[i]:
                x2[i] = trial
                cost[i] = trial_cost
            else:
                x2[i] = x1[i]
        
        # 更新种群
        x1 = x2.copy()
        count += 1  # 迭代次数加1
    
    # 找到最优解
    best_idx = np.argmin(cost)
    best_solution = x1[best_idx]
    best_cost = cost[best_idx]
    
    return best_solution, best_cost

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1937794.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

buu做题(6)

目录 [GWCTF 2019]我有一个数据库 [WUSTCTF2020]朴实无华 [GWCTF 2019]我有一个数据库 什么都没有, 尝试用dirsearch扫一下目录 可以扫到一个 /phpmyadmin 可以直接进入到数据库里面 但里面没什么东西 可以看到它的版本不是最新的, 搜一下相关的漏洞 phpMyAdmin 4.8.1后台文…

OCR识别采购单小程序管理助手

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

nodejs学习之process.env.NODE_ENV

简介 process对象是 Node 的一个全局对象&#xff0c;提供当前 Node 进程的信息。它可以在脚本的任意位置使用&#xff0c;不必通过require命令加载。该对象部署了EventEmitter接口。 process.env 属性返回包含用户环境的对象 使用 pnpm init新建index.js const { env } r…

在win10上通过WSL和docker安装Ubuntu子系统,并配置Ubuntu可成功使用宿主机GPU

本文主要记录win10系统上,通过WSL的Ubuntu系统以及Docker使用GPU的全部过程。 文章目录 1、 启用hyper-v2、 安装docker3、 安装WSL3.1 安装WSL23.1.1 检查是否安装了WSL23.1.1 安装和配置 WSL 23.2 安装Ubuntu 子系统3.3 检查并修改WSL版本4、docker配置ubuntu20.04 LTS5、下…

linux系统下,matplotlib无法显示中文字体的解决办法

1.查看自己系统是否安装了中文字体 看是否有这个目录&#xff0c;如果没有的话&#xff0c;则进行安装 2.安装中文的字体 sudo apt-get install ttf-wqy-zenhei3.测试matplotlib进行显示中文字体 from matplotlib.font_manager import FontProperties font FontProperties…

什么?突降福利假日——Windows全球蓝屏!

在科技界,任何大型软件公司的产品出现问题都可能成为头条新闻,而当这个问题是“蓝屏死机”(Blue Screen of Death, BSOD),并且影响范围覆盖全球时,其影响力更是无法估量。 近日,微软公司就经历了一场史无前例的全球性蓝屏事件,这一事件不仅考验了微软的技术应对能力,也…

员工泄密公司资料起诉有用吗或者用什么软件管控防止

员工泄密公司资料时&#xff0c;公司采取法律行动起诉员工确实是一种有效的应对方式&#xff0c;尤其是当泄密行为对公司造成了显著的经济或名誉损失时。 因为法律有专门的条款规定。 法律界定 民事责任 当员工泄密对公司造成经济损失时&#xff0c;公司可以依据《中华人民共…

pytorch的17个Loss和10个优化函数

pytorch的17个Loss和10个优化函数 一、 17个Loss 函数二、10个优化器 一、 17个Loss 函数 二、10个优化器 开始&#xff1a;

C#定时发送邮件功能

C#定时发送邮件功能 背景 自动运维监控客户端在自动关闭时&#xff0c;需要给实施同学发送提醒邮件。支持163邮箱、qq邮箱、火狐邮箱等各种通用邮箱。 定时器发送邮件 代码 邮件功能模块 using ITSLog.LogManage; using System; using System.Collections.Generic; using…

FLINK-运行架构

为什么要学习Flink运行架构&#xff1f; 虽然现在大厂的开发工具都非常高效、只需要进行参数配置、Flink-sql写业务逻辑&#xff0c;但是在资源配置逻辑优化上不可避免需要了解底层的组件配置。面试时可能也会被问到FLINK是如何进行资源分配、作业运行的等。 以下是在学习时记录…

【一刷《剑指Offer》】面试题 34:丑数

力扣对应题目链接&#xff1a;264. 丑数 II - 力扣&#xff08;LeetCode&#xff09; 牛客对应题目链接&#xff1a;丑数_牛客题霸_牛客网 (nowcoder.com) 一、《剑指Offer》对应内容 二、分析题目 根据题意&#xff0c;每个丑数都可以由其他较小的丑数通过乘以 2 或 3 或 5 …

C++字体库开发之fontconfig使用五

代码 #include <cassert> #include <algorithm> #include "fontconfig/fontconfig.h" #include <stdexcept> #include <iostream>#define HAS_FALLBACK_CONFIGURATIONenum FontStyle : uint16_t {Regular 0,Italic 0x01,Bold 0x02, };en…

如何在 Mac 上恢复丢失或删除的文件

也许您放错了 Mac 上的某个文件&#xff0c;或者永久删除了现在需要的文件。根据您丢失或删除文件的时间&#xff0c;有多种方法可以恢复 MacOS 上的项目。 我们从最快、最简单的方法开始&#xff0c;然后逐渐采用更耗时或更昂贵的方法来恢复 Mac 上的文件、文件夹和其他项目。…

MySQL添加索引时会锁表吗?

目录 简介Online DDL概念Online DDL用法总结 简介 在MySQL5.5以及之前的版本&#xff0c;通常更改数据表结构操作&#xff08;DDL&#xff09;会阻塞对表数据的增删改操作&#xff08;DML&#xff09;。 MySQL5.6提供Online DDL之后可支持DDL与DML操作同时执行&#xff0c;降低…

CentOS 7 yum官方源失效

问题 2024年7月&#xff0c;官方对centos 7停止了维护&#xff0c;yum的源网址mirror.centos.org也已经无法访问。 在此情况下&#xff0c;无法正常使用yum进行安装和更新工具。 在尝试了更换阿里源之后&#xff0c;仍然有部分工具库无法访问。 通用解决方案 1. 打开/etc/y…

react页面指定dom转pdf导出

1. 使用jsPDFhtml2canvas将页面转成图片然后导出2. 自定义创建iframe调用iframe.print()进行页面打印转pdf导出3. 使用react-to-print插件打印pdf4. 利用media print样式打印页面局部元素 1. 使用jsPDFhtml2canvas将页面转成图片然后导出 缺点&#xff1a;页面过长可能会导出失…

SwarmBrain: 通过大模型玩实时战略游戏《星际争霸II》

人工智能咨询培训老师叶梓 转载标明出处 实时战略&#xff08;RTS&#xff09;游戏如《星际争霸II》一直被视为测试和提升AI能力的绝佳平台。尽管基于强化学习&#xff08;RL&#xff09;的AI代理在《星际争霸II》中取得了显著进展&#xff0c;但它们在处理复杂环境时仍面临挑战…

SpringBoot、SpringCloud、SpringCloud Alibaba版本对应关系

1. 概述 随着SpringBoot和SpringCloud的发展&#xff0c;有些服务进入停更运维状态&#xff0c;一些新的框架出现&#xff0c;在开发微服务的时候不同组件的版本对应关系也是不可忽视的问题&#xff0c;如果版本不对应&#xff0c;可能会出现很多莫名的错误&#xff0c;给开发…

5G mmWave PAAM 开发平台

Avnet-Fujikura-AMD 5G 毫米波相控阵天线模块开发平台 Avnet 和 Fujikura 为毫米波频段创建了一个领先的 5G FR2 相控阵天线开发平台。该平台使开发人员能够使用 AMD Xilinx 的 Zynq UltraScale™ RFSoC Gen3 和 Fujikura 的 FutureAcess™ 相控阵天线模块 (PAAM) 快速创建和制…

AI周报(7.14-7.20)

AI应用-本届欧洲杯的AI技术应用 卢卡库在两场比赛中共有三次庆祝进球的情况&#xff0c;但遗憾的是这三次庆祝均未能转化为有效的进球。这种“吐饼王”的表现也让他成为了本届欧洲杯的一个另类焦点人物。虽然稍显悲情&#xff0c;但有了AI的深度应用&#xff0c;即使这样极端的…