【CVRP测评篇】 算法性能如何?来测!

news2024/11/17 9:55:38

我跨越了2100015秒的距离,为你送上更全面的算法性能评测。

目录

  • 往期优质资源
  • 1 CVRP数据集
  • 2 实验准备
    • 2.1 计算机配置
    • 2.2 调参方法
    • 2.3 参数设定
    • 2.4 实验方法
  • 3 实验结果
    • 3.1 最优解统计
      • 3.1.1各数据集上的算法性能对比
      • 3.1.2 求解结果汇总
      • 3.1.3小结一下
      • 3.1.4 还有话说
    • 3.2 调参时间统计
      • 3.2.1 各数据集上的运算时间对比
      • 3.2.2 运算时间汇总
      • 3.2.3 小结一下
    • 3.3 最优参数统计
    • 3.4 最优解路径
    • 3.5 调参过程
  • 4 结果分析

往期优质资源

CVRP系列
遗传算法
蚁群算法
禁忌搜索算法
模拟退火算法
自适应大邻域算法
粒子群算法
量子粒子群算法
差分进化算法
MDVRP系列
遗传算法
蚁群算法
禁忌搜索算法
模拟退火算法
自适应大邻域算法
粒子群算法
量子粒子群算法
差分进化算法
VRPTW系列
遗传算法
蚁群算法
禁忌搜索算法
模拟退火算法
自适应大邻域算法
粒子群算法
量子粒子群算法
差分进化算法
HVRP系列
遗传算法
蚁群算法
禁忌搜索算法
模拟退火算法
自适应大邻域算法
粒子群算法
量子粒子群算法
差分进化算法
MDHFVRPTW系列
遗传算法
蚁群算法
禁忌搜索算法
模拟退火算法
自适应大邻域算法
粒子群算法
量子粒子群算法
差分进化算法

     小编推出第一期、第二期《CVRP算法系列》(基础篇+改进篇)后,后台收到了很多粉丝的留言。大家最关心的问题可归结为以下两点:

  1. split算法的作用是什么?为什么要采用它?会降低解的质量吗?
  2. 哪个算法效果最好?有和标准数据集对比吗?结果如何?

     今天,小编将通过累计运行 【2100015秒≈35000分钟≈583小时≈24天】 的实验来回答以上问题。
2100015秒!
也许你只需要花费1分钟完成本文的阅读,但只要能帮助到大家就值得!

1 CVRP数据集

     网络上关于CVRP问题的标准数据集好像挺多的,但好像可用的又没那么多。小编今天采用的是下边这个网站数据
在这里插入图片描述
     小编下载了整个CVRP数据集,里面划分了A,B,E,F,G,M,P,V等8个类别(别担心,小编不会都测评)。考虑到时间成本,这里随机从中抽取了11个数据集。参与测评的11个数据集的最优解信息如下。
在这里插入图片描述
     以上各数据集的数据分布如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2 实验准备

2.1 计算机配置

     本次采用Python3.8编程实现,电脑配置为 Intel® Core™ i7-9700F CPU @ 3.00GHz 3.00 GHz,24G内存。

2.2 调参方法

     元启发式算法的求解效果一方面取决于邻域规则,而另一方面则取决于参数设置。而且同一算法在不同数据集上的最优参数组合也可能是不一样的。
     为了尽可能的找到最优的“算法-参数-算例”组合,小编一开始采用的是网格化调参,虽然可以较为精确的找到最优的参数组合,但需要巧妙的设计搜索空间,否则既浪费了计算资源,又没有找到理想结果。尝试了几次后,发现这种方法太耗时耗力,果断放弃!
     随后想到了机器学习邻域常用的贝叶斯调参工具,简单来说,贝叶斯调参是建立在高斯过程基础之上的,根据历史搜索结果建立目标函数和参数之间的函数关系,然后预测最优的参数位置,再将预测的参数带入算法计算,重复这个过程,直至逼近最优的拟合关系。贝叶斯调参不仅效果好,而且省事!只需设定每个参数的搜索空间即可。于是经过一番探索,搞成了!以ACO调参为例,给出具体代码如下:

import time
import xlsxwriter
from ACO_CVRP_Advance import run
from bayes_opt import BayesianOptimization
​
def F(Q,rho,alpha,beta):
    res = []
    file = f'./{filename}'
    for _ in [1,2]:
        _, obj = run(filepath=file, Q=Q, tau0=tau0, alpha=alpha, beta=beta, rho=rho,epochs=epochs,
                     v_cap=v_cap_dict[filename], popsize=popsize)
        res.append(obj)
    return -min(res)
v_cap_dict = {
    'A-n32-k5.csv':100,
    'A-n46-k7.csv':100,
    'A-n80-k10.csv':100,
    'B-n31-k5.csv':100,
    'B-n50-k7.csv':100,
    'B-n78-k10.csv':100,
    'E-n33-k4.csv':8000,
    'E-n51-k5.csv':160,
    'E-n101-k8.csv':200,
    'E-n101-k14.csv':112,
    'P-n40-k5.csv':140,
    'P-n101-k4.csv':400
}
filename = list(v_cap_dict.keys())[11]
tau0 = 2000
popsize = 100
epochs = 300
start_time = time.time()
rf_bo = BayesianOptimization(f=F,pbounds={'rho':(0.001,0.98),'alpha': (0.001, 5),'beta':(0.001,5),'Q':(1000,2000)})
rf_bo.maximize(n_iter=50, init_points=10)
run_time = time.time() - start_time
sp = rf_bo.space
history_obj = sp.target.tolist()
history_pararm = sp.params.tolist()

贝叶斯调参默认是求最大化,因此这里将目标函数取负数

2.3 参数设定

     不同算法在不同算例上的参数搜索空间基本一样,但由于ALNS算法在大规模算例上的求解较为耗时,因此部分算例上做了缩小,这里仅给出其一种搜索空间。
在这里插入图片描述
在这里插入图片描述

2.4 实验方法

     由于元启发式算法具有很大的随机性,相同的参数设置也可能跑出不同的结果,因此设定每组“算法-参数-算例”组合均运行2次,取最好的一组用于反馈贝叶斯。
     为了加快进度,早一点分享给大家,这里同时运行3组代码,因此可能会对解的质量及求解时间产生干扰。

3 实验结果

3.1 最优解统计

3.1.1各数据集上的算法性能对比

     首先来看看在同一算例上,不同算法的表现如何:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.1.2 求解结果汇总

     以上结果汇总如下:
在这里插入图片描述
     求解误差如下:
在这里插入图片描述

3.1.3小结一下

  1. 整体来看,在实验范围内8个算法均无法找到已知最优解,最小的求解误差为0.39%(ALNS-A-n32-k5)。
  2. ALNS算法在各数据集上的表现大多位列第一(B-n31-k5稍逊于ACO)
  3. ACO算法在各数据集上的表现大多位列第二(在A-n32-k5,B-n31-k5,B-n50-k7三个数据集上稍逊于GA);
  4. GA算法在各数据集上的表现大多位于第三;
  5. 其他算法的性能不再一一列举啦

3.1.4 还有话说

     虽然根据以上结果来看,基于split算法实现的8个算法并未找到已知最优解(虽然很接近啦),但并不代表就无法找到最优解,一方面小编实现的仅是基本的元启发式算法,还有众多改进版本来提升性能。且,加入启发式规则也是不错的想法。这里以文献[A simple and eBective evolutionary algorithm for the vehicle routing problem] 中的数据来佐证:

在这里插入图片描述
     以后再慢慢设计改进策略~

3.2 调参时间统计

3.2.1 各数据集上的运算时间对比

     除了目标函数外,大家肯定也很关注算法的求解时间如何。这里不再具体去分析某一参数组合下的算法运行时间,而是从整个调参过程的时间消耗来评判。这里根据算例的规模大小进行了排序,尝试去看随着问题规模的增大,算法求解时间的变化趋势,并大致做了数据拟合。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.2.2 运算时间汇总

     各算法在不同数据集上的求解时间汇总如下:
在这里插入图片描述

3.2.3 小结一下

     整体来看,随着算例规模的增加,各算法的求解时间都呈现出指数增长趋势,ALNS算法和ACO算法的增长速度明显高于其他算法。

3.3 最优参数统计

     8个算法在不同数据集上的最优参数组合如下所示,未在调参范围的参数被设置为默认值。
(1)ACO
在这里插入图片描述
(2)ALNS
在这里插入图片描述
在这里插入图片描述
(3)DE
在这里插入图片描述
(4)DPSO
在这里插入图片描述
(5)GA
在这里插入图片描述
(6)QDPSO
在这里插入图片描述
(7)SA
在这里插入图片描述
(8)TS
在这里插入图片描述

可以看出同一算法在不同数据集上的最优参数组合还是有很大差异的。所以说:调参工作是很重要的!

3.4 最优解路径

     为了尽快地将优质内容分享给各位读者,这里悄悄偷个懒,仅呈现ACO算法在最优参数组合下的优化结果(ALNS算法实在太耗时啦)。此外,由于算法具有随机性,因此在最优参数组合下,不一定保障能得出上述调参时的结果,但差异不大~。
(1)A-n32-k5
在这里插入图片描述
(2)A-n46-k7
在这里插入图片描述
(3)A-n80-k10
在这里插入图片描述
(4)B-n31-k5
在这里插入图片描述
(5)B-n50-k7
在这里插入图片描述
(6)B-n78-k10
在这里插入图片描述
(7)E-n33-k4
在这里插入图片描述
(8)E-n51-k5
在这里插入图片描述
(9)E-n101-k8
在这里插入图片描述
(10)E-n101-k14
在这里插入图片描述
(11)P-n40-k5
在这里插入图片描述
(12)P-n101-k4
在这里插入图片描述

3.5 调参过程

     12套数据集×8套算法=96组结果,实在太多啦,根本分析不完。这里仅以【A-n32-k5】数据集为例,分析使用贝叶斯调参时个别算法的参数探索过程。
(1)ACO
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
(2)ALNS
在这里插入图片描述
在这里插入图片描述
(3)DE
在这里插入图片描述
在这里插入图片描述
(4)DPSO
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(5)GA
在这里插入图片描述
在这里插入图片描述

从上图可以看出,贝叶斯工具会逐渐形成一个高密度采样区,这也是高斯过程的体现(一人之见)。

4 结果分析

     好了,估计各位读者也看累了。长话短说,这里对开头读者的问题做以下回答。

问题一:为什么使用split?会影响求解质量吗?

  1. split方法允许用户采用无车场信息的编码方式(文献中叫做 ‘TSP-like permutation chromosomes’),把容量、时间、里程等约束交给split处理,这样就无需在迭代中反复检查/修复不可行解,便于直接使用各算法的邻域搜索过程。
  2. 特定的split会建立TSP-like permutation chromosomes’ 与车辆路径集合的唯一映射。反过来思考的话,最优解也对应一个唯一的TSP-like permutation
    chromosomes’,因此找到最优的TSP-like permutation
    chromosomes’,就可以找到原问题的最优解。这里究竟影响多大,小编暂时无从考证。
  3. 学习过小编分享的算法的读者应该知道,小编推出的各系列VRP问题,都具有类似的代码架构,其最大的区别在于split机制不同,代码具有很强的迁移和扩展性,这也是小编推崇的原因。

问题二:与标准数据集对比如何?

  1. 上述实验结果大概率代表了目前的代码版本的求解效果:尚无法找到测试数据集的已知最优解,但很接近啦
  2. 从目标函数来看,ALNS,ACO,GA的效果都是很不错的。兼顾时间的话,ACO和GA可能更占优势。

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

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

相关文章

使用 RedisTemplate 对象的 opsForValue() 方法获取 Redis 中的值获取不到

问题 使用 RedisTemplate 对象的 opsForValue() 方法获取 Redis 中的值获取不到 详细问题 笔者代码如下 1 使用 ValueOperations 对象的 set() 方法将一个键值对存储到 Redis 中 valueOperations.set("order:" user.getId() ":" goods.getId(), sec…

【Redis】2、Redis应用之【根据 Session 和 Redis 进行登录校验和发送短信验证码】

目录 一、基于 Session 实现登录(1) 发送短信验证码① 手机号格式后端校验② 生成短信验证码 (2) 短信验证码登录、注册(3) 登录验证① 通过 SpringMVC 定义拦截器② ThreadLocal (4) 集群 Session 不共享问题 二、基于 Redis 实现共享 session 登录(1) 登录之后,缓…

23款迈巴赫S480升级原厂10°后轮转向系统,减少转弯半径

就是低速的情况下,有更强的机动性,前后车轮的不同转动方向使得车辆可以凭借更更小转弯半径实现转向,在特定的狭窄路段或者停车时,车辆的操控性大大提升,而内轮差也缩小也增大了转向的安全性。 高速的情况下&#xff0…

C. Road Optimization(dp)

Problem - 1625C - Codeforces 火星政府不仅对优化太空飞行感兴趣,还希望改进该行星的道路系统。 火星上最重要的高速公路之一连接着奥林匹克城和西多尼亚的首都Kstolop。在这个问题中,我们只考虑从Kstolop到奥林匹克城的路线,而不考虑相反的…

技术创举!比亚迪-汉上的实景三维导航...

实景三维技术的发展日新月异,但在应用中却一直深陷内存占用、渲染缓慢、加载卡顿和模型塌陷等问题。对此,大势智慧率先推出海量数据轻量化技术,在业内首次实现实景三维模型在车机系统的直接浏览,展示了轻量化技术赋能实景三维应用…

面试Dubbo ,却问我和Springcloud有什么区别?

Dubbo 、Springcloud? 这两有关系? 前言一、RPC 框架的概念1. 什么是RPC框架2. RPC 和 普通通信 的区别 二、常用 RPC 框架1. Dubbo2. gRPC3. Thrift4. Feign 三、dubbo 与 Springcloud1. Dubbo 的模型2. Springcloud3. dubbo 与 Springcloud 的区别 前言 提到Dub…

若隐若现的芯片

先看效果&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>若隐若现的芯片</title><script src"https://unpkg.co/gsap3/dist/gsap.min.js">…

HBase(5):导入测试数据集

1 需求 将ORDER_INFO.txt 中的HBase数据集&#xff0c;我们需要将这些指令放到HBase中执行&#xff0c;将数据导入到HBase中。 可以看到这些都是一堆的put语句。那么如何才能将这些语句全部执行呢&#xff1f; 2 执行command文件 2.1 上传command文件 将该数据集文件上传到指…

单点登录原理

单点登录原理 一、什么是单点登录 单点登录英文全称Single Sign On&#xff0c;简称SSO。指在多系统应用群中登录一个系统&#xff0c;便可在其他所有系统中得到授权而无需再次登录&#xff0c;包括单点登录与单点注销两部分。 二、为什么需要单点登录 在一些子系统用户信息…

初识Go语言25-数据结构与算法【堆、Trie树、用go中的list与map实现LRU算法、用go语言中的map和堆实现超时缓存】

文章目录 堆Trie树练习-用go中的list与map实现LRU算法练习-用go语言中的map和堆实现超时缓存 堆 堆是一棵二叉树。大根堆即任意节点的值都大于等于其子节点。反之为小根堆。   用数组来表示堆&#xff0c;下标为 i 的结点的父结点下标为(i-1)/2&#xff0c;其左右子结点分别为…

Python图像锐化及边缘检测(Roberts、Prewitt、Sobel、Lapllacian、Canny、LOG)

目录 图像锐化概述 算法方法介绍 代码实现 效果展示 图像锐化概述 图像锐化(image sharpening)是补偿图像的轮廓&#xff0c;增强图像的边缘及灰度跳变的部分&#xff0c;使图像变得清晰&#xff0c;分为空间域处理和频域处理两类。图像锐化是为了突出图像上地物的边缘、轮…

Docker|kubernetes|本地镜像批量推送到Harbor私有仓库的脚本

前言&#xff1a; 可能有测试环境&#xff0c;而测试环境下有N多的镜像&#xff0c;需要批量导入到自己搭建的Harbor私有仓库内&#xff0c;一般涉及到批量的操作&#xff0c;自然还是使用脚本比较方便。 本文将介绍如何把某个服务器的本地镜像 推送到带有安全证书的私有Harb…

【P61】JMeter JDBC Connection Configuration

文章目录 一、JDBC Connection Configuration 参数说明二、准备工作 一、JDBC Connection Configuration 参数说明 可以给数据源配置不同的连接池&#xff0c;供后续 JDBC 采样器使用&#xff1b;使用前请将对应的数据库驱动复制到 $JMETER_HOME/lib/ 或者 $JMETER_HOME/lible…

使用注解开发

使用注解开发 为了方便查看测试结果以及方便调试&#xff0c;先熟悉和配置日志。 日志 日志工厂 如果一个数据库操作出现了异常、需要进行排错&#xff0c;可以通过查看日志的方式实现。 Mybatis内置的日志工厂能够提供日志功能&#xff0c;具体的日志实现有以下几种&#xff…

基于Java+Vue前后端分离“魅力”繁峙宣传网站设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

国产MCU-CW32F030开发学习-ST7735 LCD模块

国产MCU-CW32F030开发学习-ST7735 LCD模块 硬件平台 CW32_48F大学计划板CW32_IOT_EVA物联网开发评估套件0.96 IIC oled模块 ST7735 LCD模块 硬件接口使用的 2.54mm 间距的排针接口&#xff0c;这使用杜邦线进行连接. ST7735参数供电电压3.3~5.5V驱动ICST7735分辨率128x1…

基于antdv封装的特殊复杂表格,带通行描述信息、可展示通行的单元格信息、可跨页选择数据功能、分页功能、可编辑单元格功能

基于antdv封装的特殊复杂表格&#xff0c;带通行描述信息 主要功能&#xff1a; 可展示通行的单元格信息可跨页选择数据功能表单插槽、合计插槽、操作按钮区插槽分页功能接口内请求api可编辑单元格表格组件暴漏出的方法&#xff1a;查询、获取选中数据、接口返回数据、当前表…

消防应急照明和疏散指示系统手动控制的设计与应用

摘要&#xff1a;针对非集中控制型消防应急照明和疏散指示系统在火灾确认后如何手动控制系统的应急启动存在的实际问题&#xff1a;在哪里手动控制&#xff1f;由谁来手动控制&#xff1f;什么时候能够手动控制&#xff1f;提出 3 种手动控制应急启动系统的方案&#xff1a;① …

Fluttter的ClipRRect控件

ClipRRect简介 ClipRRect&#xff08;Rounded Rectangle Clip&#xff09;是Flutter中的一个控件&#xff0c;用于将其子控件剪裁为圆角矩形形状。 使用场景 ClipRRect通常在需要给子控件添加圆角效果时使用。它可以用于创建圆角图片、圆角容器等各种UI元素。 主要属性 bo…

uniapp 开发小程序之实现不同身份展示不同的 tabbar(底部导航栏),附带相关问题解答

效果展示&#xff1a; 引言 在开发过程中逐渐意识到uniapp原生的tabbar可能不能满足开发要求&#xff0c;通过浏览博客才选择使用uView的Tabbar 底部导航栏来实现&#xff0c;我选择用的是2X版本 安装 我是使用Hbuilder插件的方式引入的组件库&#xff0c;安装配置可以看这篇…