差分优化算法——DE

news2024/11/26 12:36:45
🍎道阻且长,行则将至。🍓

目录

  • 一、DE
    • 1.步骤
    • 2.特点
  • 二、DE Optimiza
    • 1.函数最小值问题
    • 2.差分进化算法求解
    • 2.Java 实现与结果绘图


一、DE

差分进化算法是一种基于群体智能的优化算法,由Storn和Price于1995年提出,最早用来解决切比雪夫多项式问题。它采用实数编码方式,通过变异、交叉和选择等操作,使种群逐渐向全局最优解收敛。
在这里插入图片描述

1.步骤

差分进化算法的主要步骤如下:

  • 初始化参数:设定种群规模 NP,变异因子 F,交叉概率 CR,个体维度 D,决策空间上下界 XuXl,终止条件等。
  • 初始化种群:在决策空间内随机生成NP个D维的个体作为初始种群X。
  • 种群变异:对每个个体X(i),随机选择三个不同的个体X(r1),X(r2),X(r3),并计算变异向量 V ( i ) = X ( r 1 ) + F ∗ ( X ( r 2 ) − X ( r 3 ) ) V(i) = X(r_1) + F * (X(r_2) - X(r_3)) V(i)=X(r1)+F(X(r2)X(r3))
  • 种群交叉:对每个个体X(i)和变异向量V(i),按照交叉概率 CR 进行交叉操作,生成向量 U(i)。交叉操作的方法有多种,一种常用的方法是二项式交叉,即对每个维度 j,如果 rand(j) <= CR 或者 j == jrand(jrand为随机选定的一个维度),则 U ( i , j ) = V ( i , j ) U(i,j) = V(i,j) U(i,j)=V(i,j),否则 U ( i , j ) = X ( i , j ) U(i,j) = X(i,j) U(i,j)=X(i,j)
  • 最优种群选择:对每个个体 X(i) 和向量 U(i),根据目标函数值的大小进行最优选择,即如果 f ( U ( i ) ) < = f ( X ( i ) ) f(U(i)) <= f(X(i)) f(U(i))<=f(X(i)),则保留 U(i) 作为下一代的个体,否则保留 X(i)。
  • 边界条件处理:对每个个体,检查其是否超出决策空间的边界,如果是,则进行相应的处理。处理方法有多种,一种常用的方法是边界吸收,即将超出边界的分量设置为边界值。
  • 终止条件判断:判断是否达到终止条件,如最大迭代次数、目标函数值阈值等。如果是,则停止迭代并输出最优解;如果否,则返回第三步继续迭代。

差分进化算法具有结构简单、性能优越、自适应性强、并行性好等特点。它可以用来求解多种类型的优化问题,如单目标优化、多目标优化、约束优化、大规模优化等。它也可以与其他算法结合或进行改进,以提高其效率和鲁棒性。

2.特点

差分进化算法的优点有:

  • 结构简单,只需要调整三个参数(F,CR,NP),易于实现和使用。
  • 性能优越,具有较快的收敛速度和较高的精度,能够解决复杂的非线性、非凸、多峰的优化问题。
  • 自适应性强,能够根据问题特征和进化过程动态调整变异因子和交叉概率,提高搜索效率和鲁棒性。
  • 并行性好,能够利用多核处理器或分布式计算平台进行并行计算,加速优化过程。

差分进化算法的缺点有:

  • 参数选择依赖于问题特征和经验,没有统一的理论指导,可能影响算法的性能和稳定性。
  • 对于高维、大规模、多约束的优化问题,可能出现收敛速度慢、陷入局部最优、多样性丢失等问题。
  • 对于离散、整数、混合编码等类型的优化问题,需要进行特殊的编码和解码处理,增加了算法的复杂度。

差分进化算法和其他优化算法的区别主要有以下几点:

  • 差分进化算法采用实数编码,而其他优化算法如遗传算法、粒子群优化算法等可能采用二进制编码或混合编码。
  • 差分进化算法的变异操作是利用种群中个体的差向量作为扰动源,而其他优化算法的变异操作可能是随机改变个体的某些分量或基因。
  • 差分进化算法的交叉操作是按照交叉概率进行参数混合,而其他优化算法的交叉操作可能是按照某种规则进行基因重组或交换。
  • 差分进化算法的选择操作是贪婪选择,即试验向量只与目标向量进行比较和替换,而其他优化算法的选择操作可能是轮盘赌选择、锦标赛选择等,即根据适应度值决定个体被选择的概率。
  • 差分进化算法的参数设置相对简单,只需要调整三个参数(F,CR,NP),而其他优化算法的参数设置可能更复杂或依赖于问题特征。

二、DE Optimiza

1.函数最小值问题

假设我们要求解以下函数的最小值:

f ( x , y ) = sin ⁡ ( x ∗ x + y ∗ y ) / ( x ∗ x + y ∗ y + 1 ) f(x,y)=\sin(x * x + y * y) / (x * x + y * y + 1) f(x,y)=sin(xx+yy)/(xx+yy+1)

其中, x , y ∈ [ − 5 , 5 ] x,y\in[-5,5] x,y[5,5]

通过函数绘图工具得出函数分布情况,存在多处的呈现环形分布的局部最小:
在这里插入图片描述

2.差分进化算法求解

  • 初始化参数:设定种群规模 NP=100,变异因子 F=0.5,交叉概率 CR=0.1,个体维度 D=2,决策空间上下界 [-5,5],终止条件为最大迭代次数 maxGen=100 或目标函数值小于阈值 e p s = 1 0 − 8 eps=10^{-8} eps=108
  • 初始化种群:在决策空间内随机生成 NP 个 D 维的个体作为初始种群 X,并计算它们的目标函数值 f i t fit fit
  • 种群变异:对每个个体 X(i),随机选择三个不同的个体 X(r1),X(r2),X(r3) 进行变异操作 → V(i)。
  • 种群交叉:对每个个体 X(i)和变异向量 V(i),按照交叉概率CR进行交叉操作 → U(i)。
  • 最优种群选择:对每个个体X(i)和新个体 U(i),根据目标函数值的大小进行选择。
  • 边界条件处理。
  • 终止条件判断:判断是否达到终止条件,如果是,则停止迭代并输出最优解;否则返回第三步继续迭代。

2.Java 实现与结果绘图

这里添加使用 StdDraw 库进行绘图。图形库下载

  1. 简单介绍
1.设置 x、y 坐标轴
StdDraw.setXscale(a, b);
StdDraw.setYscale(c, d);
2.清空画布
StdDraw.clear();
3.设置粗细、颜色
StdDraw.setPenRadius(0.001);
StdDraw.setPenColor(StdDraw.BLACK);
4.绘制线条、正方形、长方形、点、圆
StdDraw.line(a, 0, b, 0);
StdDraw.square(0, 0, 1);
StdDraw.rectangle(0,0,1,2)//中点 (0,0),中点宽度、长度延伸
StdDraw.point(a, b);
StdDraw.circle(0, 0, r);

2.code

package code;

//Differential Optimization

import edu.princeton.cs.algs4.StdDraw;


public class c0_DEjava {

    //static int n = 100; // 离散化步数
    static double a = -5, b = 5, c = -5, d = 5; // 取值范围

    static double f(double x, double y) { // 待优化的函数
        return Math.sin(x * x + y * y) / (x * x + y * y + 1);
    }

    static int popSize = 100; // 种群大小
    static double F = 0.5, CR = 0.1; // 差分进化算法参数0.5
    static int maxGen = 100; // 最大迭代次数
    static double eps = 1e-8; // 终止条件
    static double[][] pop = new double[popSize][2]; // 种群
    static double[] fit = new double[popSize]; // 种群适应度
    static double[] best = new double[2]; // 最优解
    static double bestFit; // 最优解的适应度

    public static void main(String[] args) {
        // 初始化种群
        for (int i = 0; i < popSize; i++) {
            pop[i][0] = a + (b - a) * Math.random();
            pop[i][1] = c + (d - c) * Math.random();
        }
        // 迭代
        for (int gen = 1; gen <= maxGen; gen++) {
            // 计算种群适应度
            for (int i = 0; i < popSize; i++) {
                fit[i] = f(pop[i][0], pop[i][1]);
            }
            // 找出最优解
            int bestIndex = 0;
            for (int i = 1; i < popSize; i++) {
                if (fit[i] < fit[bestIndex]) {
                    bestIndex = i;
                }
            }
            best[0] = pop[bestIndex][0];
            best[1] = pop[bestIndex][1];
            bestFit = fit[bestIndex];

            System.out.println(gen+"  fit="+bestFit+": x="+best[0]+",y="+best[1]);

            StdDraw.setXscale(a, b);
            StdDraw.setYscale(c, d);

            // 更新种群
            for (int i = 0; i < popSize; i++) {
                double[] trial = new double[2];
                // 差分操作
                int r1, r2, r3;
                do {
                    r1 = (int) (Math.random() * popSize);
                } while (r1 == i);
                do {
                    r2 = (int) (Math.random() * popSize);
                } while (r2 == i || r2 == r1);
                do {
                    r3 = (int) (Math.random() * popSize);
                } while (r3 == i || r3 == r1 || r3 == r2);
                for (int j = 0; j < 2; j++) {
                    trial[j] = pop[r1][j] + F * (pop[r2][j] - pop[r3][j]);
                }
                // 交叉操作
                int jrand = (int) (Math.random() * 2);
                for (int j = 0; j < 2; j++) {
                    if (Math.random() < CR || j == jrand) {
                        trial[j] = Math.max(a, Math.min(b, trial[j]));
                    } else {
                        trial[j] = pop[i][j];
                    }
                }
                // 选择操作
                double trialFit = f(trial[0], trial[1]);
                if (trialFit < fit[i]) {
                    pop[i][0] = trial[0];
                    pop[i][1] = trial[1];
                    fit[i] = trialFit;
                }
            }
            // 绘制迭代过程
            if (gen>0 ){
                StdDraw.clear();
                StdDraw.setXscale(a, b);
                StdDraw.setYscale(c, d);

                StdDraw.setPenRadius(0.001);
                StdDraw.setPenColor(StdDraw.BLACK);
                StdDraw.line(a, 0, b, 0);//x
                StdDraw.line(b-0.1, 0.1, b, 0);
                StdDraw.line(b-0.1, -0.1, b, 0);

                StdDraw.line(0, a, 0, b);//y
                StdDraw.line(0.1, b-0.1, 0, b);
                StdDraw.line(-0.1, b-0.1, 0, b);

                StdDraw.square(0, 0, 1);
                StdDraw.square(0, 0, 2);
                StdDraw.square(0, 0, 3);
                StdDraw.square(0, 0, 4);

                StdDraw.setPenRadius(0.01);
                StdDraw.setPenColor(StdDraw.RED);
                StdDraw.point(best[0], best[1]);
                StdDraw.setPenRadius(0.005);
                StdDraw.setPenColor(StdDraw.BLUE);
                for (int i = 0; i < popSize; i++) {
                    StdDraw.point(pop[i][0], pop[i][1]);
                }
            }

            // 判断终止条件
            if (bestFit < eps) {
               // break;
            }
        }
    }
}

在这里插入图片描述

在这里插入图片描述


☕物有本末,事有终始,知所先后。🍭

🍎☝☝☝☝☝我的CSDN☝☝☝☝☝☝🍓

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

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

相关文章

vue3+ts开发微信小程序----使用FontAwesome图标的步骤(只适用于面性图标)

vue3ts开发微信小程序----使用FontAwesome图标的步骤&#xff08;只适用于面性图标&#xff09; 因为用的vue3ts 但是对于npm引进FontAwesome来说&#xff0c;好像对于小程序不支持&#xff0c;所以用了引入文件的方式。 下载FontAwesome字体&#xff0c;我用的是5版本的。[官方…

从初识RabbitMQ到安装了解

一、同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;但是你却不…

记 SAM React Demo 转 Vue 遇到的一些问题

前言 SegmentAnything Model (SAM) 是 Meta 开源的分割万物 AI 模型&#xff0c;因笔者主要使用 Vue&#xff0c;因此对官方 Demo 进行了工程迁移工作&#xff0c;这里记录了迁移过程遇到的一些问题。 没有使用多线程加速 官方的 React Demo 项目使用ort-wasm-simd-threaded…

态路小课堂丨浅谈IDC数据中心综合布线互联

在数据中心发展过程中&#xff0c;服务器、光模块等设备更新周期短&#xff0c;迭代快。但是&#xff0c;对于IDC数据中心综合布线系统来说&#xff0c;其使用周期一般都比较长。因此&#xff0c;为了能够匹配IDC数据中心的发展&#xff0c;关于综合布线的设计尤为重要。 目前&…

【vue】elementUI中el-table拖动滚动条的时候固定某一列

文章目录 前言&#xff1a;需求 前言&#xff1a; 写项目的时候有一个需求&#xff0c;就是当el-table的滚动条滑动的时候&#xff0c;可见区域如果没有该列则固定到左侧&#xff0c;由elementUi官方网站可知el-table固定一列的代码如下: fixed为主要的标识 头部固定设置的是t…

leetcode 2336. Smallest Number in Infinite Set(有限集中的最小数字)

实现一个SmallestInfiniteSet类(后面用set简称)&#xff0c;满足以下功能&#xff1a; 初始化时&#xff0c;set含有所有的正整数。 pop函数返回set中最小的整数。 add函数在set中添加一个整数。 思路&#xff1a; set具有以下的功能&#xff1a; 可以取出最小的数字。 可以查…

FPGA入门系列13--异步串口通信

文章简介 本系列文章主要针对FPGA初学者编写&#xff0c;包括FPGA的模块书写、基础语法、状态机、RAM、UART、SPI、VGA、以及功能验证等。将每一个知识点作为一个章节进行讲解&#xff0c;旨在更快速的提升初学者在FPGA开发方面的能力&#xff0c;每一个章节中都有针对性的代码…

Baklib如何帮助企业设计并维护FAQ页面?

作为现代企业的一部分&#xff0c;客户支持服务是为客户提供解决方案、回答问题和解决技术难题的关键部分。而其中最重要的一个基本工具是FAQ页面&#xff08;Frequently Asked Questions&#xff09;&#xff0c;它可以有效地减轻客户支持压力和提高工作效率。然而&#xff0c…

Linux——进度条与git的使用

目录 main.c Makefile process.c \r process.h 进度条的演示动图 git的使用 在gitee上创建一个仓库 复制HTTPS到xshell git clone .gitignore ​编辑 git add git commit -m 这里写日志信息 git push sudo yum -y install git git log git status git mv / …

vue2之echarts的封装 折线图,饼图,大图

目录 vue2之echarts的封装 折线图&#xff0c;饼图&#xff0c;大图折线图&#xff0c;饼图chartPan.vue使用 chartPan.vue 之饼图效果使用 chartPan.vue 之折线图效果展开大图大图组件 maxChart.vue大图效果 vue2之echarts的封装 折线图&#xff0c;饼图&#xff0c;大图 折线…

视觉回归测试—UI自动化的最后1分钟

视觉回归测试是一种验证应用GUI是否正确地展示给用户的操作。测试目标是找出应用在可视化上存在的软件缺陷&#xff0c;例如&#xff0c;字体、布局和渲染问题。这使得所发现的软件缺陷可在被最终用户看到前得到修正。此外&#xff0c;视觉测试可用于验证页面的内容&#xff0c…

车道线检测

前言 目前&#xff0c;车道线检测技术已经相当成熟&#xff0c;主要应用在自动驾驶、智能交通等领域。下面列举一些当下最流行的车道线检测方法&#xff1a; 基于图像处理的车道线检测方法。该方法是通过图像处理技术从摄像头传回的图像中提取车道线信息的一种方法&#xff0c…

【AI工具 收藏】

文章目录 miniGPT4&#xff1a;chatGPT&#xff0c;支持图片哔哔终结者 BibiGPT&#xff1a;自动总结视频内容Scribble Diffusion&#xff1a;草图绘画ChatGPT Shortcut&#xff1a;prompt提示词其他 博客总结的工具&#xff1a; miniGPT4&#xff1a;chatGPT&#xff0c;支持图…

ROS2下机械手的手眼标定

最近发现老是有人通过爬虫把文章爬去他们网站&#xff0c;因此先发一遍这个草稿&#xff0c;让他们先爬。爬完我再慢慢修改 0.前期准备 0.1机械手要先映射&#xff08;标定好&#xff09;世界坐标系与用户坐标系 这个基本应该可以通过机械手自带的坐标系建立完成 一般机械手…

若依代码生成器的使用方式

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、代码生成器是什么&#xff1f;二、使用步骤1.菜单目录2.子菜单3.代码生成的方式 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1…

符合业务目标的数据战略建设

我们都知道&#xff0c;战略是通往目的的手段&#xff0c;是企业取得最佳商业成果的方法。处于当今的数字化社会&#xff0c;企业需要满足实现数字化转型及数字社会的需求&#xff0c;提升企业数据资产价值&#xff0c;推动行业甚至社会面的数据流通及数据价值变现。因此企业更…

【数据结构与算法】二、线性表的顺序表示【硬核】

文章目录 二、线性表2.1 线性表的定义和特点2.2 线性表的顺序表示和实现2.3 类C语言有关操作补充2.4 线性表基本操作的实现2.4.1 线性表的基本操作&#xff1a;2.4.2 线性表L的初始化2.4.3 销毁和清空线性表L2.4.4 求线性表L的长度以及判断线性表L是否为空2.4.5 顺序表的取值&a…

Docker --- Docker-Compose、镜像仓库

一、Docker-Compose Docker Compose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器&#xff01; 1.1、初识DockerCompose Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。格式如下&#xff1a; v…

手术机器人企业密集IPO 国产替代寻求突破

原创 | 文 BFT机器人 2023年或为手术机器人国产化元年&#xff0c;谁将成为中国的“达芬奇”&#xff1f;各路资本对中国手术机器人产业热情高涨。 今年以来&#xff0c;多家手术机器人企业启动首次公开发行&#xff08;IPO&#xff09;进程&#xff0c;精锋医疗冲刺港股&#…

09-Node.js—express框架

目录 1、express 介绍2、express 使用2.1 express 下载2.2 express 初体验 3、express 路由3.1 什么是路由3.2 路由的使用3.2.1使用Ajax发送一次post请求 3.3 获取请求参数3.4 获取路由参数3.5 路由参数练习 4、express 响应设置5、express 中间件5.1 什么是中间件5.2 中间件的…