【MDVRP】Python+Gurobi求解运输问题建模实践四

只基于全局搜索的多车场车辆路由问题(MDVRP)的仿真实验 我们介绍的是多车场的车辆路由问题研究,其只要研究的问题是,在给定客户和车场的坐标和编号和需求的情况下,找到一种解决方案,使得每个客户有且仅有属于一个车场,由该车场出发走过所有的客户最后回到车场,目标是找到一种最优分配使走过的总距离最小。这里介绍的简单的问题模型,随着研究的深入每个车场可以有多路线(即有多个快递员),或者和其他限制条件比如带时间窗、周期性的限制条件进行结合产生更多问题的变种,不过问题的难度也会随之上升,这不是本篇文章需要讨论的范围。 阅读详情
AI摘要

该博客分享了Python调用运筹优化求解器Gurobi求解VRP扩展问题之MDVRP问题的教程。介绍了MDVRP问题,它针对多货物中转点运输场景,需解决客户需求分配等问题,还提及数学模型、数据结构、Gurobi源码及不同车场的求解结果。

今天的主题是分享Python调用运筹优化求解器(Gurobi)求解VRP扩展问题之MDVRP问题的教程。

1. 模型

1.1 MDVRP问题介绍

MDVRP 作为 VRP 研究的一个扩展问题,主要是针对有多个货物中转点运输的场景。相比于单车场问题,多车场问题需要解决客户需求分配、车辆运输路径选择、车辆运输模式、车场货物容量等一系列问题。
在这里插入图片描述

1.2 数学模型

在这里插入图片描述

2. 数据结构

(1)demand文件结构
在这里插入图片描述
(2)depot文件结构

在这里插入图片描述

3. Gurobi源码

import math
import csv
import copy
import xlsxwriter
import matplotlib.pyplot as plt
from gurobipy import quicksum,Model,GRB

# 读取文件
def read_csv_file(demand_file,depot_file):
    """
    :param demand_file: 需求文件
    :param depot_file: 车场文件
    :return:
    """
    I = []
    J = []
    Q = {}
    C = {}
    XY = {}
    with open(demand_file, 'r') as f:
        demand_reader = csv.DictReader(f)
        for row in demand_reader:
            I.append(row['id'])
            Q[row['id']] = float(row['demand'])
            XY[row['id']] = (float(row['x_coord']), float(row['y_coord']))
    with open(depot_file, 'r') as f:
        depot_reader = csv.DictReader(f)
        for row in depot_reader:
            J.append(row['id'])
            XY[row['id']] = (float(row['x_coord']), float(row['y_coord']))
    N = I + J
    for i in N:
        x1, y1 = XY[i][0], XY[i][1]
        for j in N:
            x2, y2 = XY[j][0], XY[j][1]
            C[i, j] = math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
    return N,I,J,C,Q,XY
# 提取路径
def extract_routes(I,J,X,K):
    I = copy.deepcopy(I)
    route_list = []
    for k in K:
        # 提取 派送阶段路径
        cur_node = None
        for j in J:
            for i in I:
                if X[j, i,k].x > 0:
                    cur_node = i
                    route = [j,i]
                    I.remove(i)
                    break
        if cur_node is None:
            continue
        while cur_node not in J:
            for i in I+J:
                if X[cur_node, i, k].x > 0:
                    cur_node = i
                    route.append(i)
                    if i not in J:
                        I.remove(i)
                    break
        route_list.append(route)
    return route_list
def draw_routes(route_list,XY,I,J):
    for route in route_list:
        path_x = []
        path_y = []
        for n in route:
            path_x.append(XY[n][0])
            path_y.append(XY[n][1])
        plt.plot(path_x, path_y, ms=5)
    demand_point_x = [XY[n][0] for n in I]
    demand_point_y = [XY[n][1] for n in I]
    depot_point_x = [XY[n][0] for n in J]
    depot_point_y = [XY[n][1] for n in J]
    plt.scatter( demand_point_x, demand_point_y, marker='s', c='b', s=30,zorder=0)
    plt.scatter( depot_point_x, depot_point_y, marker='*', c='r', s=100,zorder=1)
    plt.show()
# 保存结果
def save_file(route_list,total_cost,C):
    wb = xlsxwriter.Workbook('路径方案.xlsx')
    ws = wb.add_worksheet()
    ws.write(0,0,'总费用')
    ws.write(0,1,total_cost)
    ws.write(1,0,'车辆')
    ws.write(1,1,'路径')
    ws.write(1,2,'距离')
    for row,route in enumerate(route_list):
        route_str = [str(i) for i in route]
        dist = sum(C[route[i], route[i + 1]] for i in range(len(route) - 1))
        ws.write(row + 2, 0, f'{row + 1}')
        ws.write(row+2,1,'-'.join(route_str))
        ws.write(row + 2, 2, dist)
        row += 1
    wb.close()
# 建模和求解
def solve_model(N,I,J,K,Q,V_CAP,C,XY):
    """
    :param N: 所有节点
    :param I: 客户节点
    :param J: 车场节点
    :param K: 车辆节点
    :param Q: 客户需求
    :param V_CAP: 车辆容量
    :param C: 成本矩阵
    :param XY: 节点坐标
    :return: nan
    """
    model = Model('MDVRP')
    # 添加变量
    X = model.addVars(N,N,K,vtype=GRB.BINARY,name='X[i,j,k]')
    U = model.addVars(K, N, vtype=GRB.CONTINUOUS, name='U[k,i]')
    # 目标函数
    obj = quicksum(X[i,j,k]*C[i,j] for i in N for j in N for k in K)
    model.setObjective(obj,GRB.MINIMIZE)
    # 需求覆盖约束
    model.addConstrs( (quicksum(X[i,j,k] for j in N for k in K if i != j) == 1 for i in I),name='eq1' )
    # 车辆容量约束
    model.addConstrs( (quicksum(X[i,j,k]*Q[i] for i in I for j in N if i != j) <= V_CAP for k in K),name= 'eq2')
    # 车辆起点约束
    model.addConstrs( (quicksum(X[j,i,k] for j in J for i in I if i != j) == 1 for k in K),name='eq3' )
    # 中间节点流平衡约束
    model.addConstrs( (quicksum(X[i, j, k] for j in N if i != j) == quicksum(X[j, i, k] for j in N if i != j) for i in I for k in K),name='eq4' )
    # 车辆终点约束
    model.addConstrs( (quicksum(X[i,j,k] for i in I for j in J if i != j) == 1 for k in K), name='eq5' ) # 开放式
    # model.addConstrs( (quicksum(X[j,i,k] for i in I) == quicksum(X[i,j,k] for i in I) for k in K for j in J), name='eq5')  # 不开放式
    # 破除子环
    model.addConstrs(U[k, i] - U[k, j] + V_CAP * X[i, j, k] <= V_CAP - Q[i] for i in I for j in I for k in K)
    model.addConstrs(Q[i] <= U[k, i] for k in K for i in I)
    model.addConstrs(U[k, i] <= V_CAP for k in K for i in I)
    # 避免车辆直接在车场间移动
    model.addConstrs( X[i,j,k] == 0 for i in J for j in J for k in K )
    # 求解
    model.Params.TimeLimit = 300  # 设置求解时间上限
    model.optimize()
    if model.status == GRB.Status.OPTIMAL or model.status == GRB.Status.TIME_LIMIT:
        route_list = extract_routes(I,J,X,K)
        draw_routes(route_list, XY, I,J)
        save_file(route_list, model.objVal, C)
    else:
        model.computeIIS()
        model.write('model.ilp')
        for c in model.getConstrs():
            if c.IISConstr:
                print(f'{c.constrName}')
        print("no solution")
if __name__ == '__main__':
    demand_file = r'./input/demand2.csv'
    depot_file = r'./input/depot.csv'
    N, I, J, C, Q, XY = read_csv_file(demand_file=demand_file, depot_file=depot_file)
    K = list(range(0,10))
    V_CAP = 80
    solve_model(N, I, J, K, Q, V_CAP, C,XY)

4. 求解结果

4.1 开放式车场

在这里插入图片描述

4.2 非开放式车场

在这里插入图片描述

参考

  1. Ramos, T. R. P., Gomes, M. I., & Póvoa, A. P. B. (2019). Multi-depot vehicle routing problem: a comparative study of alternative formulations. International Journal of Logistics Research and Applications, 23(2), 103–120. https://doi.org/10.1080/13675567.2019.1630374
优化模型验证关键代码04:VRP两小标模型及其gurobipy实现 两下标VRP模型及其实现源码 阅读详情

相关推荐

【MDVRP】遗传算法求解多车辆路径规划问题【含Matlab源码 704期】

遗传算法求解多车辆路径规划问题 完整的代码,方可运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 1043

【MDVRP】基于matlab遗传算法求解带距离的多车场车辆路径规划问题(含单线路局部优化)【含Matlab源码 1170期】

遗传算法求解带距离的多车场车辆路径规划问题(含单线路局部优化). 完整代码,直接运行,适合小白!可提供运行操作视频!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 5901

【MDVRP】遗传算法求解带距离的多车场车辆路径规划问题(含单线路局部优化)【含Matlab源码 1170期】

1 VRP基本原理车辆路径规划问题(Vehicle Routing Problem,VRP)是运筹学里重要的研究问题之一。VRP关注有一个供货商与K个销售点的路径规划的情况,可以简述为:对一系列发货点和收货点,组织调用一定的车辆,安排适当的行车路线,使车辆有序地通过它们,在满足指定的约束条件下(例如:货物的需求量与发货量,交发货时间,车辆容量限制,行驶里程限制,行驶时间限制等),力争实现一定的目标(如车辆空驶总里程最短,运输总费用最低,车辆按一定时间到达,使用的车辆数最小等)。2 问题属性与常见问题。

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 298

多车场路径优化丨遗传算法求解MDCVRP问题

python语言编写遗传算法求解多车场有载重约束的路径优化问题MDCVRP

喜欢玩算法的老学长,致力于运筹优化算法的研究 3764

mdvrp:解决多站点车辆路径问题

mdvrp 使用 Cordeau 基准通过智能水滴元启发式解决多站点车辆路由问题。 运行说明 代码最初使用 Matlab 2014a 运行,因此我们不保证它可以在任何其他版本上运行。 脚步: 打开 Matlab 2014a 将您的目录更改为“代码”目录 打开 IWD.m 文件 根据需要更改 IWD.m 文件中的以下变量: pind -- 问题索引(1-5;设置运行哪个问题) oilMat = (weighting) * globalSoilMat -- 土壤的边长权重 (通过取消注释将“权重”更改为以下三个中的任何一个) 日志(distMat + 1) 分布垫 exp(distMat) 运行 IWD.m 代码

用51单片机和LD3320语音模块DIY一个会说话的温度报警器(附完整代码)

本文详细介绍了如何使用51单片机和LD3320语音模块DIY一个智能温度报警器,包括硬件选型、电路设计、软件开发及核心功能实现。通过DS18B20温度传感器和语音模块的结合,实现温度超标时的语音报警功能,适合智能家居系统等应用场景。附完整代码,方便开发者快速复现。

weixin_42525632的博客 420

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

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

Better.C的博客 1万+

【东华大学oj】找到最大数(一维数组->中等)

一天,老师布置了一个作业,要求对一串数字各不相同的数字串进行排序,大的在前,小的在后。接着,我从数字串中的第二个数字开始往后找,找到最大的一个,然后与第二个数字交换,这样的话我就能够确定排序后数字串中的第二个数字;明明研究发现,他的这个想法中最重要的一环就是在一串数字中找到最大的那个,然后与第一个数字交换,可是明明毕竟刚刚开始学习程序设计不久,无法写出较复杂的程序,所以明明想让你这位程序设计专家帮他的忙,帮助他把这段核心程序写出来,然后明明只需模仿着写就可以了。时间限制: 1S类别: 一维数组->中等。

的博客 525

gurobi使用系列之一——gurobi+Python的实例使用(简单整数规划)

gurobi是由美国Gurobi公司开发的新一代大规模数学规划优化器,在 Decision Tree for Optimization Software 网站举行的第三方优化器评估中,展示出更快的优化速度和精度,成为优化器领域的新翘楚。 一个简单的整数规划实例,感受一下gurobi的魅力。 题目图片中缺少一个约束条件——每部电影至少放映一次。 ![整数规划题目](https://img-blog.csdnimg.cn/20200623101845260.jpg?x-oss-p....

sanpi329的博客 3万+

ISP——坏点矫正(Defective Pixel Correction,DPC)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录一、出现原因二、坏点分类三、矫正方法动态矫正1.PINTO算法2.梯度法3.DPC和demosaic结合法4.行检测法 一、出现原因 1.感光元件芯片自身工艺技术瑕疵造成以及长期使用造成的瑕疵; 2.光线采集存在缺陷; 二、坏点分类 1.hot pixel: 固定保持较高的像素值,一般呈现为画面高亮的点; 2.dead pixel: 固定保持较低的像素值,一般在画面中呈现为暗点; 3.noise pixel:信号强度随光照呈现的.

qq_41939460的博客 9424

halcon与QT联合:(5.1)瓶盖检测以及QT界面搭建

halcon实现瓶盖检测与定位代码: dev_close_window() dev_open_window(0, 0, 1024, 1024, 'black', WindowHandle) list_image_files('C:/Users/TIMI/Desktop/picture/circle', 'default', [], ImageFiles) for J := 1 to 4 by 1 *read image read_image(halconImage, ImageFil

m0_37957160的博客 1044

车辆路径问题的(资源)探索与归纳

目前,我所知道的关于车辆路径规划问题的有几个种类,以及对应的求解器.在这里将资料分类整理. 以便学习和归纳.

panbaoran913的博客 720

量化 insider 爆料! 散户打板必亏?(打板必看!量化资金如何“隔日砸盘”收割散户)

量化开发 insider 爆料💥 散户追的涨停板📉,可能是机构故意做的陷阱!本文从技术视角拆解“涨停陷阱”,帮你看清市场真实逻辑🧠。

XiaoqiangClub的博客 454

物流路线优化实战:基于整数规划与图论的车辆路径问题(VRP)求解

车辆路径问题(VRP)是运筹学与组合优化领域的经典问题,旨在为多辆车辆规划访问一系列客户点的最优路线,以最小化总成本或距离。其核心原理是通过图论将现实路网抽象为顶点与边构成的网络,并运用整数规划(特别是0-1整数规划)建立数学模型,定义决策变量、目标函数及容量、时间窗等约束条件。该技术的核心价值在于通过数学建模与优化算法,实现物流配送资源的科学配置,从而显著降低运输成本、提升车辆利用率和客户服务水平。其应用场景广泛,涵盖快递配送、城市货运、生鲜冷链及共享出行调度等领域。本文将以带容量约束(CVRP)和时间窗

weixin_33861800的博客 409

LeRobot 入门教程(一)软件环境、部署流程及摄像头配置

🤖 LeRobot:开源机器人学习平台 摘要:LeRobot是一个基于PyTorch的开源机器人学习平台,提供模型、数据集和工具,旨在降低机器人技术门槛。平台包含经过验证的模仿学习和强化学习方法,并提供预训练模型、人类演示数据集及模拟环境。安装需从源码获取,支持Python 3.10环境,可选扩展包括仿真环境(如gym-aloha)、电机控制(Dynamixel/Feetech SDK)和实验跟踪(Weights & Biases)。该平台托管在HuggingFace,并设有社区Discord频道

2506_90492529的博客 3417

73、结合无人机进行rk3588oak-lite跟踪目标物体进行识别、跟踪

搭建仿真转换模型环境,主要python版本和我下载的rknn2的版本。截取shape节点,输出模型。so库也要对应转模型的whl。其中安装的whl版本。

sxj731533730 1624

组合优化入门:从NP-hard到排产、路径规划与求解器选型

组合优化是运筹优化中处理离散决策的核心分支,广泛出现在排产、车辆路径规划、资源分配与人员指派等场景。其难点在于决策变量只能取0/1或整数,可行域离散且随规模指数膨胀,很多问题属于NP-hard,暴力枚举不可行。工程上常借助整数规划、约束规划、分支定界与启发式/元启发式,在有限时间内求取可接受的近似最优解。求解器如OR-Tools CP-SAT、Gurobi等,结合时间窗、容量、不重叠等约束,可把业务问题转化为可计算模型。从建模、求解器选型到LP松弛、整数间隙与上线避坑,这条链路正是组合优化工程落地的关键。

weixin_34009794的博客 262

目标检测基础

目标检测是计算机视觉的核心任务,需同时对图像中的物体进行定位与识别。传统方法存在速度慢、精度低等问题,而深度学习显著推动了该领域发展,使实时高精度检测成为可能。检测的核心是为每个物体预测边界框坐标和类别标签。为实现高效检测,引入了锚框机制,通过预设多尺度、多宽高比的候选区域,缩小预测偏移量,提升定位精度。训练时,通过计算锚框与真实边界框的交并比 (IoU) 确定正负样本,并基于此生成类别标签和坐标偏移量作为监督信号。该方法提升了检测器对多尺度目标和复杂场景的鲁棒性。

盼小辉丶的博客 2774

旅行商问题(TSP)、车辆路径问题(VRP,MDVRP,VRPTW)模型介绍

即将面临毕业之际,把研究生期间的研究工作的基础好好整理了一下,方便以后能快速地捡起来。写了一部分,剩下的之后继续更新。 1.旅行商问题 旅行商问题 (Traveling Salesman Problem,TSP),又叫货郎担问题,它是图论中一个经典的组合优化问题。经典的TSP可以描述为:一个商品推销员要去若干个城市推销商品,该推销员从一个城市出发,需要经过所有城市一次并且仅一次之后,回到出发城市。问他应如何选择在城市之间的行程路线,以使他走过的总路程最短。 从图论的角度来看,该问题其实就是在一个赋权的

chc960609的博客 6万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

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

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

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

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Matlab实现PSO算法求解MDVRP问题(部分)

Matlab实现PSO算法求解MDVRP问题(部分) 主函数main.m clc clear %位置矩阵 Pos = Pos_init(); [n,~] = size(Pos); x = 3; client = n - x; %粒子个数 N = 1000; %每个车场拥有的车辆数 car_count = 2; car = (1:x*car_count); %初始化粒子位置和速度 P = cell(N,1);%每个维度是2*(client-x)的向量 V = cell(N,1);%维度与位置维度保持一致 %

xiyehutao的博客 915

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

遗传算法解决MDVRP问题(MATLAB)

实验数据包括15个服务点和3个车场。 main.m如下 clc clear %导入数据 global request; global v_Pos; global d_Pos; [request,v_Pos,d_Pos] = Pos_init; %客户数,车场数,各车场车辆数,最大装载量、货物需求表request v_num = length(v_Pos); d_num = length(d_Pos); global max_car_num; global max_load; max_car_num = 5;

xiyehutao的博客 1773

【MDVRP】遗传算法求解多仓库车辆路径规划问题【含Matlab源码 1481期】

遗传算法求解多仓库车辆路径规划问题 完整的代码,方可运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版)或下载付费资源,可赠送奶茶价版付费专栏指定代码1份; 1123

通过深度学习中的Attention机制求解TSP问题

Attention机制求解TSP问题 1. 基础知识   深度学习中Attention机制的出现,使得NLP的发展取得了重大突破。 Attention机制模仿了生物观察行为的内部过程,即一种将内部经验和外部感觉对齐从而增加部分区域的观察精细度的机制。例如人的视觉在处理一张图片时,会通过快速扫描全局图像,获得需要重点关注的目标区域,也就是注意力焦点。然后对这一区域投入更多的注意力资源,以获得更多所需要关注的目标的细节信息,并抑制其它无用信息。   VRP的本质就是序列决策问题,这意味着深度学习技术在VRP上也

zhangkkit的博客 4503

优化 | 考虑随机性的车辆路径规划问题详解(Stochastic VRP):模型、理论推导及Python调用Gurobi实现)

考虑随机性的车辆路径规划问题详解(Stochastic VRP):模型、理论推导及Python调用Gurobi实现

m0_45008035的博客 2851
上一篇: 【VRPCB】Python+Gurobi求解运输问题建模实践三
下一篇: 最短路问题求解 | Python+Gurobi-COPT-SCIP
Better.C
博客等级 码龄9年 1万+粉丝 72原创
评论 1
成就一亿技术人!
拼手气红包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、付费专栏及课程。

余额充值