【CVRP&VRPTW】Python+Gurobi求解运输问题建模实践二

关于CVRP问题的研究 # Routing-problem--CVRP # 项目准备阶段 # 准备相关论文,设计准备数据集,最终决定采用CVRPLIB (opens new window)上的标准数据集作为实验用数据。 # 项目第一阶段 # 参考论文用各种元启发式算法求解CVRP问题 # 采取的算法主要有: # 贪心 (opens new window)、遗传 (opens new window)、蚁群 (op... 阅读详情
AI摘要

本文介绍使用Python结合Gurobi求解器解决经典的车辆路径规划问题(CVRP)及带有时间窗口的车辆路径规划问题(VRPTW)的方法。包括数学模型构建、数据结构定义及编程实现全过程。

采用Python+Gurobi实现车辆路径规划问题建模求解【CVRP&VRPTW】

今天以经典CVRP和VRPTW为例,讲解如何采用python+gurobi编程求解。个人认为采用求解器求解数学模型的关键在于拿到一个正确的数学模型!本人在求解CVRP时,通过文献库搜索了很多文章,限于个人能力,无法采用gurobi对其模型进行求解。最后借用了微信博文中提到的数学模型。(文末给出链接)

往期资料

1. CVRP

1.1 适用场景

  • 求解CVRP
  • python+gurobi

1.2 数学模型

后续代码所对应的数学模型源自以下文章:

https://mp.weixin.qq.com/s/DYh-5WkrYxk1gCKo8ZjvAw

1.3 数据结构

采用.xlsx文件储存数据文件,共包含两个sheet,命名为:node,link。
在 ‘node’ sheet中内容如下:
在这里插入图片描述

在 ‘link’ sheet中内容如下:
在这里插入图片描述

1.4 编程实现

(1)读取文件

def readXlsxFile(filename):
    df=pd.read_excel(filename,sheet_name=None)
    "读取节点信息"
    df_node=df['node']
    depot=df_node['id'][0]
    N = [depot]
    C = []
    Q = {}
    for i in range(df_node.shape[0]):
        id=df_node['id'][i]
        demand=df_node['demand'][i]
        N.append(id)
        C.append(id)
        Q[id]=int(demand)
    N = tuplelist(N)
    C = tuplelist(C)
    Q=tupledict(Q)

    "读取网络弧信息"
    Cost={}
    df_link=df['link']
    for i in range(df_link.shape[0]):
        from_node_id=df_link['from_node_id'][i]
        to_node_id=df_link['to_node_id'][i]
        cost=df_link['link_cost'][i]
        Cost[from_node_id,to_node_id]=cost
    Cost=tupledict(Cost)
    return depot,C,N,Q,Cost

(2)模型构建与求解

def solveCVRPModel(depot,C,N,Q,Cost,n_vehicles=20,CAP=100):
    """
    :param depot: 车场索引
    :param C: 需求点集合
    :param N: 所有点集合
    :param Q: 需求集合
    :param Cost: 弧运输成本集合
    :param n_vehicles: 最大车辆数量
    :param CAP: 车辆容量
    :return:
    """
    "构建车队"
    K=tuplelist([f'v'+str(k) for k in range(n_vehicles)])
    "实例化模型"
    model=Model('cvrp')
    "添加变量"
    X=model.addVars( N,N,K,vtype=GRB.BINARY,name='X[i,j,k]')
    Y=model.addVars( K,N,vtype=GRB.BINARY,name='Y[k,i]')
    U=model.addVars( K,N,vtype=GRB.CONTINUOUS,name='U[k,i]')
    "目标函数:最小化路径成本"
    z1=quicksum( Cost[i,j]*X[i,j,k] for i in N for j in N for k in K if i!=j)
    model.setObjective(z1,GRB.MINIMIZE)
    "约束:需求覆盖约束"
    model.addConstrs( quicksum( Y[k,i] for k in K ) ==1 for i in C )
    "约束:车辆数量约束"
    model.addConstr( quicksum( Y[k,depot] for k in K) == n_vehicles )
    "约束:流平衡"
    model.addConstrs( quicksum( X[i,j,k] for j in N ) == quicksum( X[j,i,k] for j in N ) for i in N for k in K )
    "约束:决策变量关联"
    model.addConstrs( quicksum( X[i,j,k] for j in N ) == Y[k,i] for i in N for k in K )
    "约束:容量限制"
    model.addConstrs( quicksum( Q[i]*Y[k,i] for i in C ) <= CAP for k in K )
    "约束:破除子环"
    model.addConstrs( U[k,i]-U[k,j]+CAP*X[i,j,k] <= CAP-Q[i] for i in C for j in C for k in K )
    model.addConstrs( Q[i] <= U[k,i] for k in K for i in C )
    model.addConstrs( U[k,i] <= CAP for k in K for i in C)
    "求解"
    model.Params.TimeLimit = 300 # 设置求解时间上限
    model.optimize()
    if model.status == GRB.Status.OPTIMAL or model.status == GRB.Status.TIME_LIMIT:
        for k in K:
            for i in N:
                for j in N:
                    if i!=j :
                        if X[i,j,k].x>0:
                            print("X[{},{},{}]=1".format(i,j,k))
        print("obj:{}".format(model.objVal))
    else:
        print("no solution")

2. VRPTW

2.1 适用场景

  • 求解VRPTW
  • python+gurobi

2.2 数学模型

后续代码所对应的数学模型源自以下文章:

https://mp.weixin.qq.com/s/tF-ayzjpZfuZvelvItuecw

2.3 数据结构

采用.csv文件格式储存数据文件,分别为:node.csv 和link.csv
在 ‘node.csv’ 中内容如下:
在这里插入图片描述
在 ‘link.csv’ 中内容如下:
在这里插入图片描述

2.4 编程实现

(1)读取文件

def readCsvFile(node_file,link_file):
    """
    :param node_file: 节点文件,
    :param link_file: 网络弧文件
    :return:
    """
    N=[] #所有节点
    Q={} #节点需求
    TT={} #节点旅行时间
    ET={} #节点最早开始服务时间
    LT={} #节点最晚结束服务时间
    ST={} #节点服务时间
    Cost={}
    with open(node_file,'r') as f:
        node_reader=csv.DictReader(f)
        for row in node_reader:
            node_id = row['id']
            demand = float(row['demand'])
            start_time = float(row['start_time'])
            end_time = float(row['end_time'])
            service_time = float(row['service_time'])
            N.append(node_id)
            Q[node_id] = demand
            ET[node_id] = start_time
            LT[node_id] = end_time
            ST[node_id] = service_time
    with open(link_file,'r') as f:
        link_reader = csv.DictReader(f)
        for row in link_reader:
            from_node_id = row['from_node_id']
            to_node_id = row['to_node_id']
            travel_time = float(row['travel_time'])
            travel_cost = float(row['link_cost'])
            TT[from_node_id,to_node_id] = travel_time
            Cost[from_node_id,to_node_id] = travel_cost
    return N,Q,TT,ET,LT,ST,Cost

(2)模型构建与求解

def solveVRPTWModel(N,Q,TT,ET,LT,ST,Cost,CAP,K):
    """
    :param N: 所有节点集合,其中N[0]为车场
    :param Q: 节点需求集合
    :param TT: 旅行时间
    :param ET: 节点最早开始服务时间
    :param LT:节点最晚结束服务时间
    :param ST: 节点服务时间
    :param CAP: 车辆容量
    :param Cost: 旅行费用
    :param K: 车队数量
    :return:
    """
    C=tuplelist(N[1:]) #需求节点
    N=tuplelist(N)
    Q=tupledict(Q)
    TT=tupledict(TT)
    E=tupledict(ET)
    L=tupledict(LT)
    S=tupledict(ST)
    K=tuplelist([f'v'+str(i) for i in range(K)])
    M=10**5
    depot = N[0]
    "创建模型"
    model=Model()
    "添加变量"
    X=model.addVars(N,N,K,vtype=GRB.BINARY,name='X(i,j,k)')
    T=model.addVars( N,K,vtype=GRB.CONTINUOUS,lb=0,name='T[i,k]')
    "设置目标函数"
    z1=quicksum( Cost[i,j]*X[i,j,k] for i in N for j in N for k in K if i!=j)
    model.setObjective(z1,GRB.MINIMIZE)
    "车辆起点约束"
    model.addConstrs(quicksum(X[depot, j, k] for j in N) == 1 for k in K)
    "车辆路径连续约束"
    model.addConstrs( quicksum(X[i,j,k] for j in N if j!=i)==quicksum(X[j,i,k] for j in N if j!=i) for i in C for k in K)
    "车辆终点约束"
    model.addConstrs(quicksum(X[j, depot, k] for j in N) == 1 for k in K)
    "需求服务约束"
    model.addConstrs( quicksum(X[i,j,k] for k in K for j in N if j!=i)==1 for i in C)
    "车辆容量约束"
    model.addConstrs( quicksum(Q[i]*X[i,j,k] for i in C for j in N if i!=j)<=CAP for k in K )
    "时间窗约束"
    model.addConstrs( T[i,k]+S[i]+TT[i,j]-(1-X[i,j,k])*M<=T[j,k] for i in C for j in C for k in K if i!=j )
    model.addConstrs( T[i,k] >= E[i] for i in N for k in K)
    model.addConstrs( T[i,k] <= L[i] for i in N for k in K)
    "设置模型参数"
    model.Params.TimeLimit = 300 # 规模较大时可设置求解时间限制
    # model.setParam('OutputFlag', 0) #是否输出求解日志
    "模型求解"
    model.optimize()
    "判断求解状态"
    if model.status == GRB.Status.OPTIMAL or model.status == GRB.Status.TIME_LIMIT:
        print('obj={}'.format(model.objVal))
        res=[]
        for k in K:
            for i in N:
                for j in N:
                    if i!=j:
                        if X[i,j,k].x>0:
                            print("X[{},{},{}]=1".format(i,j,k))
                            res.append([i,j,k,T[i,k].x,T[j,k].x])
        saveFile(res)
    else:
        print("no solution")

(3)保存结果

def saveFile(data):
    outfile = open('results.csv', 'w', newline='', errors='ignore')
    write = csv.writer(outfile)
    write.writerow(['from_node_id', 'to_node_id', 'vehicle','Ti','Tj'])
    for v in data:
        write.writerow(v)
    outfile.close()

3. 完整代码

如有错误,欢迎交流。
代码和数据文件可从github主页免费获取:

https://github.com/PariseC/modeling_examples_using_gurobi_in_python

可关注微信公众号,及时获取新内容(推送内容正在准备中):

Python助力交通

参考

  1. https://mp.weixin.qq.com/s/DYh-5WkrYxk1gCKo8ZjvAw
  2. https://mp.weixin.qq.com/s/tF-ayzjpZfuZvelvItuecw
  3. http://www.gurobi.cn/pic.asp?bigclassname=%D1%A7%CF%B0%D7%CA%C1%CF
运筹学经典问题(八):CVRP和VRP-TW 给定一个图,图上的点代表客户,边代表客户之间的路线,边的权重代表客户之间的距离,点上的数字代表每个用户的需求量。如果只是上面的模型,可能会出现下图这种解,: 假设我们的问题是车辆去客户那里取货,需要一个约束去消除这种不包含仓库的子环。这也是VRP建模的一个略难的约束。会有图上的哪些边被选中,形成。没有约束车辆的容量限制! 阅读详情

相关推荐

CVPR 2024 数据集整理

是一个用于目标检测、分割和图像字幕等计算机视觉任务的常用数据集。它包含了超过118,000张图像,其中有80个类别被标注了对象的位置、大小和类别信息,同时还有部分图像进行了实例分割和语义分割的标注。

qq_42854305的博客 2913

【运筹优化】带时间窗约束的车辆路径规划问题(VRPTW)详解 + Python 调用 Gurobi 建模求解

车辆路径规划问题(Vehicle Routing Problem,VRP)一般指的是:对一系列发货点和收货点,组织调用一定的车辆,安排适当的行车路线,使车辆有序地通过它们,在满足指定的约束条件下(例如:货物的需求量与发货量,交发货时间,车辆容量限制,行驶里程限制,行驶时间限制等),力争实现一定的目标(如车辆空驶总里程最短,运输总费用最低,车辆按一定时间到达,使用的车辆数最小等)。下图给出了一个简单的VRP的例子最基本的VRP问题叫做带容量约束的车辆路径规划问题(Capacitated Vehicle Rou

知不足而奋进,望远山而前行 4万+

基于Gurobi编程开发教程01:python环境配置及列生成求解CVRP示例

介绍Pycharm和Ananconda下的gurobi配置,并使用CVRP的列生成算法进行测试说明

m1m2m3mmm的博客 1660

软件工具 | Python调用运筹优化求解器(一):以CVRP&VRPTW为例

以CVRP & VRPTW问题为例,介绍Python调用Gurobi,COPT,SCIP的方法。

Better.C的博客 7639

【VRP问题】基于遗传结合粒子群求解VRPTW问题

一、粒子群算法简介 粒子群算法是在1995年由Eberhart博士和Kennedy博士一起提出的,它源于对鸟群捕食行为的研究。它的基本核心是利用群体中的个体对信息的共享从而使整个群体的运动在问题求解空间中产生从无序到有序的演化过程,从而获得问题的最优解。设想这么一个场景:一群鸟进行觅食,而远处有一片玉米地,所有的鸟都不知道玉米地到底在哪里,但是它们知道自己当前的位置距离玉米地有多远。那么找到玉米地的最佳策略,也是最简单有效的策略就是搜寻目前距离玉米地最近的鸟群的周围区域。 在PSO中,每个优化问题的..

qq_59747472的博客 437

Python调用vrplib库解析具有VRPLIB标准格式的CVRP实例数据

介绍了可以解析和编写VRPLIB格式数据的vrplib库

Linshaodan520的博客 2397

CVRP建模与求解-基于粒子群算法(python实现)

本文为单配送中心、单车型、车辆封闭、非满载、需求不可拆分的VRP场景建立数学模型,并设计粒子群算法进行求解。

_2312 1万+

A-VRP.zip_A-VRP_CVRP问题_cvrp_vrp 数据_vrp 测试

CVRP问题数据集,可供测试CVRP问题算法

基于遗传算法的CVRP建模求解(Python)

单向:纯取货/纯送货; 单配送中心:只有一个配送中心/车场; 单车型:只考虑一种车型, 需求不可拆分:客户需求只能有一辆车满足; 车辆封闭:完成配送任务的车辆需回到配送中心; 车辆充足:不限制车辆数量,即配送车辆需求均能满足; 非满载:任意客户点的需求量小于车辆最大载重;优化目标:最小化车辆启动成本和车辆行驶成本之和; 约束条件:车辆行驶距离约束,重量约束; 已知信息:配送中心位置、客户点位置、客户点需求、车辆最大载重、车辆最大行驶距离、车辆启动成本、车辆单位距离行驶成本;min⁡Z=C0K+C1∑i=0N

博客简介 1万+

AI全景之第八章第三节:时间序列分析与预测技术

摘要 时间序列分析与预测技术从传统统计模型发展到深度学习方法。传统方法包括ARIMA模型(处理趋势和季节性)、指数平滑(加权平均预测)和状态空间模型(概率框架分解)。机器学习方法通过特征工程和树模型提升非线性建模能力。深度学习方法中,RNN/LSTM处理序列依赖,TCN利用因果卷积,Transformer通过注意力机制捕获长程依赖。当前研究趋势结合神经符号方法和生成模型,以提高预测精度和可解释性。不同方法各具优势,需根据数据特性和预测需求选择。

技术引领业务创新 991

基于陀螺仪航向反馈的轮式机器人PID直线控制

航向角控制是移动机器人实现稳定直线运动的基础技术,其本质是通过实时感知机体朝向偏差并动态调节驱动输出,以抵消机械不对称、轮径误差等固有扰动。该方法依托陀螺仪测量角速度并积分解算航向角,结合离散化PID算法生成补偿性PWM指令,在嵌入式平台(如STM32)上构建低延迟闭环。相比依赖编码器的速度闭环,它规避了轮径标定与安装偏心等误差源,显著提升低成本平台的工程鲁棒性与部署效率。典型应用场景包括教育机器人直线循迹、AGV基础导航模块开发及IMU-PID融合控制原型验证。

web39explorer的博客 1110

手把手教你用Gurobi求解一个数学模型

手把手教你用Gurobi求解一个数学模型手把手教你用Gurobi求解一个数学模型带时间窗的车辆路径规划问题(Vrptw)python调用Gurobi求解Vrptw首先我们定义一下需要用到的参数:定义一个读取数据的函数,并对节点之间的距离进行计算:读取数据,并定义一些参数:调用gurobi进行模型的建立与求解:根据式(9)定义决策变量,并加入模型当中:根据式(1)定义目标函数,并加入模型当中:根据式(2)~(8)定义决策变量,并加入模型当中: 手把手教你用Gurobi求解一个数学模型 在接触Gurobi之前,

旸的博客 2万+

从零开始:如何用PSINS工具箱构建你的第一个IMU误差模型

本文详细介绍了如何使用严恭敏教授开发的PSINS工具箱构建IMU误差模型,涵盖从基础参数设置到高级误差建模的全过程。通过imuerrset函数配置陀螺零偏、随机游走等核心参数,并结合实战案例展示消费级MEMS器件的误差建模方法,帮助用户提升惯性导航系统的精度与可靠性。

weixin_29284885的博客 322

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

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

Better.C的博客 2160

用AT7456E给监控摄像头加OSD?5步搞定时间水印和Logo叠加

本文详细解析了如何使用AT7456E视频字符叠加芯片为监控系统添加专业级OSD功能,涵盖硬件设计、字符库编程和系统集成等关键步骤。通过5步操作实现时间水印和Logo叠加,提升监控系统的可用性和专业性,特别适合安防和工业视觉应用。

sea99的博客 1014

Python-编写点云处理软件(二)点云软件ui制作之仿CC界面

至本篇结束,我们已经能够获得一个有点模子的界面了,但是具体的功能还没有编写,后续的文章将逐渐完善功能。

weixin_43894929的博客 3953

从3D人脸到自动驾驶,CVPR2020十个顶级开源数据集

CVPR2020数据集 CVPR2020上开源的十个最有用的数据集,用数据来构建更好的人工智能,数据搬运工从来不应该缺席!下面就是十个数据集的分别解释: 01 FaceScape 一个大规模高质量的3D人脸数据集,包括18760张高质量3D人脸模型,对938名志愿者实现20种表情采集,该数据训练可以实现对单张图像预测3D人脸的细节。适应于非商业开源项目。数据集下载地址: https://facescape.nju.edu.cn/ 02 OASIS 全称是...

m0_37909240的博客 664

SAP 固定资产采购简介

SAP 固定资产采购是指企业通过采购流程获取长期使用并记录为固定资产的物品。固定资产是企业为长期使用而购置的资产,如机器设备、办公设备、建筑物、车辆等,通常这些资产的使用期限较长,并且在资产负债表上记录。在SAP系统中,固定资产采购流程通常与物料管理(MM)模块和固定资产管理(FI-AA)模块相结合。这个过程涉及从需求的提出、采购订单的创建,到货物接收、发票校验和资产激活的多个步骤。

我小时候很黑的博客 1731

VRPTW

带时间窗的VRP问题是在该基础上,还需要满足服务时间约束,即配送人员需要在一定的时间窗内到达客户需求点进行服务。带时间窗的VRP问题分为硬时间窗和软时间窗两种,硬时间窗是车辆一定要在时间窗范围内到达指定用户处,不能早于时间窗要求的最早时间,也不能晚于时间窗的最晚时间;VRP问题一般是指从物流配送中心用多辆车向多个客户需求点送货,每个客户需求点的位置和需求量是已知的,车辆的最大载质量是一定的,要求合理安排配送路线使得目标函数最优,并且满足以下条件:每个客户需求点只能被一辆车访问,并且只能访问一次;

FanSunshineboy的博客 2936

提示词编写:从新手到专家的进阶之路

本文旨在为提示词编写者提供一条从新手到专家的进阶之路。我们将详细探讨提示词编写的背景与意义、基础与进阶技巧、实战应用以及最佳实践。通过逐步深入的分析与实操,读者将掌握提示词编写的核心要点,提高编写效率和作品质量。提示词是用于引导人工智能生成文本的关键词或短语,它包含了作者想要传达的主题、情感和细节。随着人工智能技术的普及,自动化写作工具逐渐应用于各行各业。为了提高写作效率,项目团队决定开发一款基于人工智能的自动化写作工具。成功开发了一款自动化写作工具,生成文本质量较高。

AI天才研究院 1087

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

c++和gurobi_数学优化求解器|python调用gurobi解决车辆路径问题

No.1前言本文介绍单车型燃油车静态车辆路径问题,建模并利用python调用gurobi求解。No.2问题描述物流企业组建一只燃油车车队对客户进行配送。假设配送系统存在一个配送中心和K辆燃油车(车辆同质),需为n个已知位置、需求量和服务时间的客户配送货物,且每个客户都具有服务时间窗约束,即车辆需在时间段[ei,li]内对顾客i进行服务。现假设每辆车都从配送中心出发,并在完成配送后返回起点...

weixin_39684235的博客 1591

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

数据集: CVRPLIB容量约束车辆路径问题数据集

CVRPLIB是运筹学领域经典的容量约束车辆路径问题(CVRP)标准数据集库,包含Augerat、Christofides等学者提出的16组基准实例,涵盖从16到1000个客户的不同规模问题。数据集按提出时间分类,包含1969年的经典小规模测试集(如SetE)、1990年代中等规模集合(如SetM)、2000年后的大规模实例(如Li et al.)以及2014年Uchoa提出的高难度X系列。该库支持精确算法与启发式方法的性能比较,包含车辆容量、客户需求等关键参数,部分实例已获最优解。数据集格式包含xlsx和

张陈亚的博客 1597

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

运筹系列17:routing模型之CVRP问题

1. CVRP模型 CVRP指的是有容量(capacity)限制的VRP模型,是最常见的VRP模型。 2. 示例 依旧用上一章节的点,不同的是每个点多了一个送货需求。每辆车的最大容量是15,最小化总运输距离。 dimension可以使用AddDimensionWithVehicleCapacity方法,和AddDimension唯一的区别就是,第三个参数从一个固定值变成了一个列表,表示每一辆车有自...

kittyzc的博客 1万+
上一篇: 《车辆路径规划问题》专栏_安全提示——关于抄袭并通过其本人有偿获取内容的安全提示
下一篇: 【功能上新】Python实现OSM地图数据解析——OSM2Rail
Better.C
博客等级 码龄9年 1万+粉丝 72原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Better.C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值