【改进篇】Python实现VRP常见求解算法——蚁群算法(ACO)

news/2023/5/28 8:52:40

基于python语言,实现经典蚁群算法(ACO)对车辆路径规划问题(CVRP)进行求解, 优化代码结构,改进Split函数

目录

  • 往期优质资源
  • 1. 适用场景
  • 2. 改进效果对比
    • 2.1实验结果
    • 2.2 改进前后算法性能对比
  • 3. 求解结果
  • 4. 改进内容
  • 5. 部分代码
  • 6. 完整代码
  • 参考

往期优质资源

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

1. 适用场景

  • 求解CVRP
  • 车辆类型单一
  • 车辆容量不小于需求节点最大需求
  • 单一车辆基地

2. 改进效果对比

这里做了简单的参数敏感性分析,比较不同参数组合下两个版本code的最优值与求解时间的差异。具体为:1)设定信息素挥发因子为0.1,0.3三个不同等级;2)设定信息启发式因子为1,2,3,4,5不同值;3)设定期望启发式因子为1,2,3,4,5不同值,其他参数固定不变:最大迭代次数为300,车辆容量为80。

2.1实验结果

rho=0.1:
在这里插入图片描述
rho=0.3:
在这里插入图片描述

2.2 改进前后算法性能对比

求解时间对比(红色为改进后,蓝色为改进前):
在这里插入图片描述
行驶距离对比(红色为改进后,蓝色为改进前):
在这里插入图片描述

可以直观看出,改进后算法求解时间略有增加, 平均增加3.10%,目标函数平均优化1.38%

3. 求解结果

(1)收敛曲线
在这里插入图片描述

(2)车辆路径
在这里插入图片描述
(3)输出文件

在这里插入图片描述

4. 改进内容

本期代码在前期代码的基础上做了以下改进:

  • 增加距离矩阵,减少代码中重复计算节点间距离代码
  • 引入文献中基于图论的Split方法,在给定节点id序列时,可求得最优分割方案

除了以上关键改动之外,还对代码做了细小调整。

5. 部分代码

(1)数据结构

# 数据结构:解
class Sol():def __init__(self):self.node_no_seq=None # 解的编码self.obj=None # 目标函数self.action_id=None # 算子idself.route_list=None # 解的解码self.route_distance = None  # 车辆路径的长度集合
# 数据结构:网络节点
class Demand():def __init__(self):self.id = 0 # 节点idself.x_coord = 0 # 节点平面横坐标self.y_coord = 0  # 节点平面纵坐标self.demand = 0 # 节点需求
# 数据结构:全局参数
class Model():def __init__(self):self.best_sol = None # 全局最优解self.demand_dict = {}  # 需求节点集合self.demand_id_list = []self.sol_list = []  # 解的集合self.depot = None # 车场节点self.number_of_nodes = 0 # 需求节点数量self.vehicle_cap = 80 # 车辆最大容量self.distance_matrix = {}self.popsize = 100 # 种群规模self.alpha = 2 # 信息启发式因子self.beta = 3 # 期望启发式因子self.Q = 100 # 信息素总量self.rho = 0.5 # 信息素挥发因子self.tau = {} # 弧信息素集合self.vehicle_cap=0  # 车辆最大容量

(2)距离矩阵

def calDistanceMatrix(model):for i in range(len(model.demand_id_list)):f_n = model.demand_id_list[i]for j in range(i + 1, len(model.demand_id_list)):t_n = model.demand_id_list[j]dist = math.sqrt((model.demand_dict[f_n].x_coord - model.demand_dict[t_n].x_coord) ** 2+ (model.demand_dict[f_n].y_coord - model.demand_dict[t_n].y_coord) ** 2)model.distance_matrix[f_n, t_n] = distmodel.distance_matrix[t_n, f_n] = distmodel.tau[f_n, t_n] = 100model.tau[t_n, f_n] = 100dist = math.sqrt((model.demand_dict[f_n].x_coord - model.depot.x_coord) ** 2+ (model.demand_dict[f_n].y_coord - model.depot.y_coord) ** 2)model.distance_matrix[f_n, model.depot.id] = distmodel.distance_matrix[model.depot.id, f_n] = dist

(3)路径提取

def extractRoutes(node_no_seq,P,depot_id):route_list = []route = []p = P[node_no_seq[0]]for node_seq in node_no_seq:if P[node_seq] == p:route.append(node_seq)else:route.insert(0,depot_id)route.append(depot_id)route_list.append(route)route = [node_seq]p = P[node_seq]return route_list

(4)蚁群移动

# 蚂蚁移动
def movePosition(model):sol_list=[]local_sol=Sol()local_sol.obj=float('inf')for _ in range(model.popsize):#随机初始化蚂蚁为止node_no_seq=[random.randint(0,len(model.demand_id_list)-1)]all_node_no_seq=copy.deepcopy(model.demand_id_list)all_node_no_seq.remove(node_no_seq[-1])#确定下一个访问节点while len(all_node_no_seq)>0:next_node_no=searchNextNode(model,node_no_seq[-1],all_node_no_seq)node_no_seq.append(next_node_no)all_node_no_seq.remove(next_node_no)sol=Sol()sol.node_no_seq=node_no_seqsol.obj,sol.route_list,sol.route_distance=calObj(node_no_seq,model)sol_list.append(sol)if sol.obj < local_sol.obj:local_sol = copy.deepcopy(sol)model.sol_list=copy.deepcopy(sol_list)if local_sol.obj<model.best_sol.obj:model.best_sol=copy.deepcopy(local_sol)
# 搜索下一移动节点
def searchNextNode(model,current_node_no,SE_List):if len(SE_List) == 1:return SE_List[0]prob=np.zeros(len(SE_List))for i,node_no in enumerate(SE_List):eta=1/model.distance_matrix[current_node_no,node_no]tau=model.tau[current_node_no,node_no]prob[i]=((eta**model.alpha)*(tau**model.beta))#采用轮盘法选择下一个访问节点cumsumprob=(prob/sum(prob)).cumsum()cumsumprob -= np.random.rand()return SE_List[list(cumsumprob > 0).index(True)]

(5)收敛曲线

# 绘制目标函数收敛曲线
def plotObj(obj_list):plt.rcParams['font.sans-serif'] = ['SimHei']  #show chineseplt.rcParams['axes.unicode_minus'] = False  # Show minus signplt.plot(np.arange(1,len(obj_list)+1),obj_list)plt.xlabel('Iterations')plt.ylabel('Obj Value')plt.grid()plt.xlim(1,len(obj_list)+1)plt.show()

(6)车辆路径

# 绘制优化车辆路径
def plotRoutes(model):for route in model.best_sol.route_list:x_coord=[]y_coord=[]for node_no in route:x_coord.append(model.demand_dict[node_no].x_coord)y_coord.append(model.demand_dict[node_no].y_coord)plt.plot(x_coord,y_coord,marker='s',color='b',linewidth=0.5)plt.show()

(7)输出结果

# 输出结果
def outPut(model):work=xlsxwriter.Workbook('result.xlsx')worksheet=work.add_worksheet()worksheet.write(0, 0, 'id')worksheet.write(0, 1, 'route')worksheet.write(0, 2, 'distance')worksheet.write(0, 3, 'total_distance')worksheet.write(1,3,model.best_sol.obj)for id,route in enumerate(model.best_sol.route_list):r=[str(i)for i in route]worksheet.write(id + 1, 0, f'v{str(id + 1)}')worksheet.write(id + 1, 1, '-'.join(r))worksheet.write(id + 1, 2, model.best_sol.route_distance[id])work.close()

6. 完整代码

如有错误,欢迎交流。
有偿获取

参考

  1. A simple and effective evolutionary algorithm for the vehicle routing problem

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

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

如何实现更换电脑硬盘而不重装系统?

笔者的电脑最近出了问题&#xff0c;异常卡顿&#xff0c;根据经验得出“应该是硬盘坏道了”的结论&#xff0c;使用硬盘查看工具HDtune一看&#xff0c;果不其然。 而且坏道的位置极其坑&#xff0c;搞不好就是引导区&#xff0c;幸亏发现及时&#xff0c;于是用另一块硬盘迅速…

如何改变视频的MD5值?一分钟让你学会操作

肯定很多不是从事自媒体的朋友对MD5不是很熟悉&#xff0c;但其实它类似于人的身份证&#xff0c;只不过我们的身份证是一串数字&#xff0c;而它则是视频的后台编码&#xff0c;所以这也是一些平台用MD5来判断视频是否重复的依据。那么有人会问了&#xff0c;既然MD5这么特殊&…

激光雷达对植被冠层结构和SIF同时探测展望

前言陆表植被在全球碳循环中起着不可替代的作用。但现阶段&#xff0c;人们对气候变化与植被生态理化功能的关系的研究还不够完善。为了提高气候预测以及缓解气候恶化的速率&#xff0c;对植被参数比如&#xff1a;叶面积指数&#xff08;leaf&#xff09;、植被冠层结构&#…

格子玻尔兹曼机(Lattice Boltzmann Method)系列3:LBM在不可压缩流动下的边界条件算法

这篇文章主要整理了在格子玻尔兹曼方法中4个十分重要的边界条件。 1.回弹性边界条件 回弹性边界条件是格子玻尔兹曼算法中最简单也是最重要的一个边界条件&#xff0c;用于模拟固壁。适用于这个边界条件的粒子有两种不同的观点。 第一种观点是将这个边界点列看作固体。比如&…

受限玻尔兹曼机(RBM)原理分析以及在Tensorflow的实现

转自&#xff1a;https://blog.csdn.net/qq_23869697/article/details/80683163 简介 受限玻尔兹曼机是一种无监督&#xff0c;重构原始数据的一个简单的神经网络。 受限玻尔兹曼机先把输入转为可以表示它们的一系列输出&#xff1b;这些输出可以反向重构这些输入。通过前向…

理想气体

目录1. 建模2. 属性(1) 物态方程(2) 压强公式(2) 平均平动能与温度关系(3) 内能3. 循环过程(1) 等体过程(2) 等压过程(3) 等温过程(4) 绝热过程1. 建模 &#xff08;1&#xff09;分子可看作质点&#xff1b; &#xff08;2&#xff09;除碰撞外&#xff0c;分子间的相互作用力…

强化学习算法(二)——深度Q网络DQN

文章目录Reference1. Critic1.1 State Value Function1.1.1 MC1.1.2 TDMC vs TD1.2 State-action Value Function2. DQN2.1 目标网络&#xff08;Target Network&#xff09;2.2 探索&#xff08;Exploration&#xff09;3.2.1 ϵ\epsilonϵ-贪心3.2.2 玻尔兹曼探索&#xff08…

2020-4-17 深度学习笔记20 - 深度生成模型 1 (玻尔兹曼机,受限玻尔兹曼机RBM)

第二十章 深度生成模型 Deep Generative Models 中文 英文 深度生产模型在某种程度上都代表了多个变量的概率分布。 从数据分布生成真实样本是生成模型的目标之一。 有些模型允许显式地计算概率分布函数。 其他模型则不允许直接评估概率分布函数&#xff0c;但支持隐式获取…

【零基础强化学习】基于玻尔兹曼采样的DQN智能体

基于玻尔兹曼采样的DQN智能体&#x1f914;写在前面show me code, no bb结果展示写在最后谢谢点赞交流&#xff01;(❁◡❁)更多代码&#xff1a; Gitee主页&#xff1a;https://gitee.com/GZHzzz博客主页&#xff1a; CSDN&#xff1a;https://blog.csdn.net/gzhzzaa写在前面 …

受限波兹曼机Restricted Boltzmann Machines (RBM)

Note This section assumes the reader has already read through Classifying MNIST digits using Logistic Regression and Multilayer Perceptron. Additionally it uses the following Theano functions and concepts : T.tanh, shared variables, basic arithmetic ops,

【英语】五月,英语如影随形

想写这篇文章很长时间了&#xff0c;一直有这个念头&#xff0c;每次写博客的时候它都在我脑海中挥之不去&#xff0c;但是我想等到月底再写&#xff0c;于是就放到了现在。 这个月虽然没有早起&#xff0c;但是同样也收获了不少。上课下课的途中一直在听英语&#xff0c;感觉很…

5月英语总结—平淡不平凡

5月的英语&#xff0c;只能用平淡来形容&#xff0c;因为在整个5月的氛围中&#xff0c;即将迎来答辩和毕业&#xff0c;我们还有其他的项目需要忙&#xff0c;总感觉我们已经忙惯了&#xff0c;所以完全没有感受到事情突然间变多了&#xff0c;多了的只是对于毕业&#xff0c;…

五月英语总结——让英语成为生活的一部分

上个月因为自考和作品展&#xff0c;自己时间管理做得不好&#xff0c;英语坚持的不好&#xff0c;相对于上个月来说&#xff0c;这个月感觉比较好。 月初的时候为了督促自己好好的坚持学英语&#xff0c;每天晚上固定的时间和秀娟一起去五楼哼调&#xff0c;也许是因为英语基础…

[Arduino]环境安装与配置

最近着迷与Arduio&#xff0c;可以连接控制各种器件帮助人类降低负担&#xff0c;如室内外温度动态采集、声控灯、自动给绿植浇水等各种应用&#xff0c;感觉挺有意思&#xff1b;随着最近两年物联网的推广及“万物互联”的普及&#xff0c;个人觉得物联网还是有点花样的&#…

【English】五月英语总结

五月 英语依然在路上...... 1.有 My Car的陪伴 2.有group的陪伴 3.有Rebecca的陪伴 4.有Charlie的陪伴 其乐融融的一家人&#xff0c;四个宝贝给他们的爸爸妈妈过结婚纪念日。 邓家舞蹈团 5.其他...... 最后想说一下我是如何去学 Mini Story&#xff0c;请看图 你会说套路我…

日本经典电影《罗生门》揭露了人性最丑恶的一面

黑泽明的《罗生门》则是日本电影史和世界电影史上极为经典的作品&#xff0c;根据芥川龙之介的短篇小说《筱竹丛中》改编而成。“罗生门”一词在日本传统文化中有地狱之门的意思&#xff0c;是一个阴森恐怖又涵义丰富的意象。影片主要表现了每个人都会为了自己的利益而歪曲事实…

辞旧迎新 be better---记我的2013

辞旧迎新--be better额 果然是老了。这篇日志放草稿箱里好久&#xff0c;还以为早就发出去了呢。。。之前在空间里发过&#xff0c;略微改了改。 在写这篇日志之前我把13年自己写过的40多篇很水的博客和20多篇日记照片都看了一遍。才发现记录真的能够帮助我们整理生命&#xff…

从Synthesize安装Graphite步骤

问题 按照Graphite官网上用Synthesize安装Graphite的步骤&#xff08;或Synthesize Github上的安装步骤&#xff09;安装后&#xff0c;Graphite的Web UI不能正常工作&#xff0c;经过尝试&#xff0c;发现需要一些额外配置 错误详情及解决方法&#xff1a; 1. 从synthesize…

@synthesize与@dynamic

property有两个对应的词&#xff0c;一个是 synthesize&#xff0c;一个是 dynamic。如果 synthesize和 dynamic都没写&#xff0c;那么默认的就是syntheszie var _var; 在Xcode4.5和以后的版本中&#xff0c;可以省略synthesize,编译器会自动加上setter和getter方法的实现。…