VRPSolverEasy:支持VRP问题快速建模的精确算法Python包

文章目录

  • 前言
  • 一步步安装免费版
  • 主要模块介绍
    • 1. depot point
    • 2. customer point
    • 3. links
    • 4. vehicle type
  • VRPTW 算例
    • 数据说明
    • 模型建立
    • 输出求解状态及结果


前言

VRPSolverEasy 是用于车辆路径问题(VRP)的最先进的分支切割和定价算法求解器1,它的一大特点是,即使没有运筹学背景的用户,也可以直观地通过Python接口定义出VRP问题,无需知道模型是如何建立为 MIP 问题以及底层进行的线性处理,只需要通过配置好的方法,向模型中添加高度抽象的VehicleTypePoint(衍生出depotcustomer)、links 即可。

VRPSolver将VRP问题进行了高度抽象,尽管较大程度方便使用,但代价是限制了VRPSolver只能建模常见的标准的VRP变体问题,例如:

  1. 车辆带容量限制;
  2. 客户点带时间窗;
  3. 车辆不同质;
  4. 多depot发车;
  5. 客户点指定车辆资质;
  6. 时间依赖…

VRPSolver的内核是分支切割定价算法,其高效性在于对可行解最优界(下界)的优化上,而在初始可行解的寻找方面效率较低,因此由外部启发式求解器获得非常好的初始解(上界)时,VRPSolver的求解性能可以得到改善。

目前的VRPSolver仍然是proof-of-concept的代码,容易出现问题,因此建议仅用于研究、教学、测试等非生产环境。

一步步安装免费版

VRPSolverEasy有两种安装模式,一种是免费版本,直接安装VRPSolverEasy库(内嵌了COIN-OR CLP线性规划求解器),以及下载Bapcod发行版即可。另一种是学术版本,该版本使用了商业CPLEX MIP求解器,由于CPLEX可以免费用于学术目的,因此这个版本下的VRPSolverEasy也被称为学术版,该版本提高了求解性能,并提供了内置的基于MIP的启发式算法,对寻找可行的初始解非常有用。

这里我们仅介绍安装免费版的 VRPSolverEasy,操作系统默认为Windows。(学术版的安装请参考 官方文档)

(1)确认python版本及更新pip

VRPSolverEasy库要求python版本不小于 3.6,因此在开始安装前,先确认好python的版本,并建议更新 pip 库:

python -m pip install --upgrade pip

(2)安装VRPSolverEasy库

VRPSolverEasy库的安装可以直接用pip安装:

python -m pip install VRPSolverEasy

(3)安装Bapcod依赖的环境

由于内嵌的 CLP 仅是线性规划求解器,要用 B&C&P 求解MIP问题,还需安装Bapcod,由于Bapcod的底层是C++,因此要用Python接口使用,就还需下载能对该库进行编译和管理的工具CMake,该工具的官网下载地址为:Download CMake,具体的安装细节可以参考:Windows 安装CMake。在cmd控制台输入 cmake --version 即可查看CMake的版本。

接着还需安装 Bapcod 依赖的python库:

  1. Boost库版本1.76 pip install boost
  2. LEMON 库版本 1.3.1 pip install lemon

(4)申请Bapcod并替换相应文件

尽管Bapcod是免费开源的库,但是需要学术机构的电子邮箱才能下载Bapcod的源码,在 BaPCod官方网站 填写相应信息并回车进行申请。系统会自动验证该邮箱,并向该邮箱发送下载链接。

解压下载的文件,例如为 bapcod-v0.82.5,找到该文件夹下的 VRPSolverEasy 文件夹,复制该文件夹下的 Windows 文件夹到 VRPSolverEasy 库下面的 lib 文件夹中替换 Windows 即可。

主要模块介绍

关于主要模块的介绍我们截取翻译自VRPSolverEasy的技术报告1

导入VRPSolverEasy库,并通过以下命令创建模型。

import VRPSolverEasy
model = VRPSolverEasy.Model()

VRPSolverEasy库模型由四组实体对象定义:depot pointscustomer pointslinksvehicle types

1. depot point

depot 可以通过如下命令添加

model.add_depot(id=<id>, name='', service_time=0.0, tw_begin=0.0, tw_end=0.0)

添加 depot 方法的参数说明如下:

Characterization of a depot point v

2. customer point

customer 可以通过如下命令添加:

model.add_customer(id=<id>, id_customer=<id>, name ='', demand=0, penalty=0.0, service_time=0.0, tw_begin=0.0, tw_end=0.0, incompatible_vehicles=[])

添加 customer 方法的参数说明如下:

Characterization of a customer point v
不论是 depot point 还是 customer point,都应该有一个唯一的点 id,且每个 customer 都与一个或多个点相关联,其中 idid_customer 可以不同。

对于一些特殊的问题,例如同一个客户点具有不同的时间窗,且每个时间窗所兼容的车辆可能不同,常见于时间依赖的VRPTW问题,这类问题中,客户点可能会被多辆车访问(同时或者有时间前后约束),这时候为了避免与子环路消除约束相冲突,往往会创建虚拟点,在这里,如果我们要创建 customer point 的额外点,可以通过以下命令添加:

model.add_point(id=<id>, id_customer=<id>, name ='', demand=0, penalty=0.0, service_time=0.0, tw_begin=0.0, tw_end=0.0, incompatible_vehicles=[])

3. links

link 可以通过如下命令添加:

model.add_link(start_point_id=<id>, end_point_id=<id>, name='', is_directed=False, distance=0.0, time=0.0, fixed_cost=0.0)

添加 link 方法的参数说明如下:

Characterization of a link l
每一条 link 代表有向图G当中的一条弧,如果 is_directed=True,则说明该弧具有方向,只能从 start_point_idend_point_id 方向;如果 is_directed=False,则说明该弧是双向的(若不设置该参数默认为双向的)。

4. vehicle type

vehicle type 可以通过如下命令添加:

model.add_vehicle_type(id=<id>, start_point_id=-1, end_point_id=-1, name='', capacity=0, fixed_cost=0.0, var_cost_dist=0.0, var_cost_time=0.0, max_number=1, tw_begin=0.0, tw_end=0.0) 

添加 vehicle type 方法的参数说明如下:

Characterization of a vehicle type k
当车辆的开始点和结束点都为 -1 时,说明该车辆可以在任意节点处出发,和返回任意节点处。

VRPTW 算例

数据说明

如下设置 7 个节点,以第 1 个节点 Wisconsin, USAdepot point,其余节点为 customer point,除了 depot 其余节点都有大于0需求量,车辆的时间窗为 [ 0 , 5000 ] [0, 5000] [0,5000],每辆车单位距离成本为 10,节点与节点之间的距离通过欧式距离公式计算 compute_euclidean_distance

import VRPSolverEasy as vrpse
import mathdef compute_euclidean_distance(x_i, x_j, y_i, y_j):"""compute the euclidean distance between 2 points from graph"""return round(math.sqrt((x_i - x_j)**2 + (y_i - y_j)**2), 3)# Data
cost_per_distance = 10
begin_time = 0
end_time = 5000
nb_point = 7# Map with names and coordinates
coordinates = {"Wisconsin, USA": (44.50, -89.50),  # depot"West Virginia, USA": (39.000000, -80.500000),"Vermont, USA": (44.000000, -72.699997),"Texas, the USA": (31.000000, -100.000000),"South Dakota, the US": (44.500000, -100.000000),"Rhode Island, the US": (41.742325, -71.742332),"Oregon, the US": (44.000000, -120.500000)}# Demands of points
demands = [0, 500, 300, 600, 658, 741, 436]

模型建立

依次建立求解车辆路径网络流问题的要素:车辆、节点、弧。要素的参数值可以自定义配置。

# Initialisation
model = vrpse.Model()# Add vehicle type
model.add_vehicle_type(id=1,start_point_id=0,end_point_id=0,name="VEH1",capacity=1100,max_number=6,var_cost_dist=cost_per_distance,tw_end=5000)# Add depot
model.add_depot(id=0, name="D1", tw_begin=0, tw_end=5000)coordinates_keys = list(coordinates.keys())
# Add customers
for i in range(1, nb_point):model.add_customer(id=i,name=coordinates_keys[i],demand=demands[i],tw_begin=begin_time,tw_end=end_time)# Add links
coordinates_values = list(coordinates.values())
for i in range(0, 7):for j in range(i + 1, 7):dist = compute_euclidean_distance(coordinates_values[i][0],coordinates_values[j][0],coordinates_values[i][1],coordinates_values[j][1])model.add_link(start_point_id=i,end_point_id=j,distance=dist,time=dist)

输出求解状态及结果

当建立模型后,通过以下命令即可实现求解,求解的结果都会保存在 model 的属性当中。

# solve model
model.solve()

打印模型信息可以通过以下命令,默认将模型信息保存在 instance.json 文件中。

model.export()

通过 model.status 可以返回模型的求解状态码:

状态码说明
0找到一个解并证明了最优性
1求解过程被时间限制打断,但找到了优于截断值的解
2求解器证明不存在由于截断值的解
3求解过程被时间限制打断,且没找到由于截断值的解

判断求解状态码是一种输出结果的前置判断,在该库中也可以用 model.solution.is_defined() 进行判断,后者表示找到了可行解,且解的信息会保存到模型的属性当中:

if model.solution.is_defined():# 打印解的目标值及方案的全部信息print(model.solution)# 仅打印路线方案print(model.solution.routes)# 仅打印目标值print(model.solution.value)    # 打印解的求解时间和上下界信息等print(model.statistics)

打印解的目标值及方案的全部信息如下:

Solution cost : 1479.6800000008684Route for vehicle 1:ID : 0 --> 2 --> 5 --> 0Name : D1 --> Vermont, USA --> Rhode Island, the US --> D1End time : 0.0 --> 16.807 --> 19.259 --> 37.230000000000004Load : 0.0 --> 300.0 --> 1041.0 --> 1041.0
Total cost : 372.29999999999995Route for vehicle 1:ID : 0 --> 1 --> 3 --> 0Name : D1 --> West Virginia, USA --> Texas, the USA --> D1End time : 0.0 --> 10.548 --> 31.625 --> 48.728Load : 0.0 --> 500.0 --> 1100.0 --> 1100.0
Total cost : 487.2800000000001Route for vehicle 1:ID : 0 --> 4 --> 6 --> 0Name : D1 --> South Dakota, the US --> Oregon, the US --> D1End time : 0.0 --> 10.5 --> 31.006 --> 62.010000000000005Load : 0.0 --> 658.0 --> 1094.0 --> 1094.0
Total cost : 620.1

  1. N. Errami, E. Queiroga, R. Sadykov, E. Uchoa. “VRPSolverEasy: a Python library for the exact solution of a rich vehicle routing problem”, Technical report HAL-04057985, 2023. ↩︎ ↩︎

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

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

相关文章

某国产沙盒游戏的启动器逆向

游戏近期改变了登录方式&#xff0c;于是把之前的研究成果分享一下研究仅供学习交流&#xff0c;如有侵权请联系删除 抓包 启动启动器&#xff0c;输入账号密码&#xff0c;点击登录&#xff0c;抓包得到一些信息 接口 1 https://wskacchm.mini1.cn:14100/login/auth_secur…

命令行参数环境变量和进程空间地址

文章目录 命令行参数环境变量进程地址空间 正文开始前给大家推荐个网站&#xff0c;前些天发现了一个巨牛的 人工智能学习网站&#xff0c; 通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站。 命令行参数 什么是命令行参数&#xff1f; 我…

存储任意类型

code /* * c17 std::any */#include <cstdint> #include <cstring> #include <cstdlib> #include <iostream> #include <thread> #include <chrono>namespace lxz {// T不为指针时 template<typename T> struct Data {Data(): data…

QT第六天

要求&#xff1a;使用QT绘图&#xff0c;完成仪表盘绘制&#xff0c;如下图。 素材 运行效果&#xff1a; 代码&#xff1a; widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPainter> #include <QPen>QT_BEGIN_NAMESPACE name…

网络端口映射和端口转发的区别和联系

目 录 一、端口映射技术 1.1 原理 1.2 应用场景 1、远程访问 2、游戏主机 3、文件共享 4、监控视频共享 二、端口转发技术 2.1 原理 2.2 应用场景 1、网络负载均衡 2、网络安全 3、网络代理 三、端口映射和转发的实现方法 3.1 路由器配置 3.2 网络防火墙 …

跨平台兼容,无限可能:Apple Remote Desktop for Mac让远程控制更简单

Apple Remote Desktop for Mac是一款远程桌面管理软件&#xff0c;提供了一系列强大的功能&#xff0c;让用户可以轻松地管理和控制远程计算机。以下是该软件的一些主要功能和特点&#xff1a; 实时远程访问和控制&#xff1a;使用Apple Remote Desktop&#xff0c;用户可以在…

跟着pink老师前端入门教程-day05

七、CSS的引入方式 根据CSS样式书写的位置&#xff08;或者引入的方式&#xff09;&#xff0c;CSS样式表可以分为三大类 1. 行内样式表&#xff08;行内式&#xff09; 内部样式表&#xff08;内嵌样式表&#xff09;是写到HTML页面内部&#xff0c;将所有的CSS代码抽取出…

【Proteus仿真】【Arduino单片机】智能助眠机系统设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使用蜂鸣器闹铃模块、LCD1602显示模块、心率血氧模块、ADC模块、按键模块等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示传感器采…

HackTheBox - Medium - Linux - Mentor

Mentor Mentor 是一台中等难度的 Linux 机器&#xff0c;其路径包括在到达 root 之前在四个不同的用户之间切换。使用可暴力破解的社区字符串扫描“SNMP”服务后&#xff0c;会发现用于“API”端点的明文凭据&#xff0c;该端点被证明容易受到盲目远程代码执行的影响&#xff…

如何实现无公网ip远程访问内网本地BUG管理服务【内网穿透】

文章目录 前言1. 本地安装配置BUG管理系统2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射本地服务3. 测试公网远程访问4. 配置固定二级子域名4.1 保留一个二级子域名5.1 配置二级子域名6. 使用固定二级子域名远程 前言 BUG管理软件,作为软件测试工程师的必备工具之一。在…

精通Discord营销:多账号注册与管理,高效打造矩阵

Discord虽然是一个海外小众平台&#xff0c;但在Z世代群体来说却非常受欢迎。通常在游戏行业、年轻化的电商特定品类、软件等业务中&#xff0c;Discord的社群营销可以起到非常卓越的效果。但是&#xff0c;您必须学会管理不同的帐户&#xff0c;以构成矩阵打造社区&#xff0c…

更适合3D项目的UI、事件交互!纯国产数字孪生引擎持续升级中!!!

UI和事件交互是3D可视化项目中最常见的模块&#xff0c;主要用于信息添加、展示&#xff0c;用来确保按照用户需求呈现内容并完成交互。 平时工作在进行UI和交互设计时&#xff0c;经常出现以下问题&#xff1a;UI过于复杂导致3D项目内交互效率低下&#xff0c;或者是结合3D项目…

简单了解【多智能体强化学习(MARL)】

我们的现实生活中有着许多多智能体共同决策的场景&#xff0c;比如多机械臂协同&#xff0c;多个无人机或多个机器人完成某共同目标。下面介绍单智能体强化学习的进化&#xff0c;多智能体强化学习。 含义 多智能体系统中包含 m 个智能体&#xff0c;智能体共享环境&#xff…

【vsan数据恢复】vsan逻辑架构出现故障的数据恢复案例

VSAN数据恢复环境&#xff1a; 一套有三台服务器节点的VSAN超融合基础架构&#xff0c;每台服务器节点上配置2块SSD硬盘和4块机械硬盘。 每个服务器节点上配置有两个磁盘组&#xff0c;每个磁盘组使用1个SSD硬盘作为缓存盘&#xff0c;2个机械硬盘作为容量盘。三台服务器节点上…

c/c++的指针函数与函数指针

函数 定义&#xff1a; 函数是数学中的一个概念&#xff0c;它是定义在某个数集上的一个特殊的映射关系。函数将输入值&#xff08;或自变量&#xff09;映射到输出值&#xff08;或因变量&#xff09;。函数的输入和输出可以是任何类型的数据&#xff0c;如数字、字符串、数组…

ArcGIS Pro 如何新建布局

你是否已经习惯了在ArcGIS中数据视图和布局视图之间来回切换&#xff0c;到了ArcGIS Pro中却找不到二者之间切换的按钮&#xff0c;即使新建布局后却发现地图怎么却是一片空白。 这一切的一切都是因为ArcGIS Pro的功能框架完全不同&#xff0c;这里为大家介绍一下在ArcGIS Pro…

前端react入门day04-useEffect与Hook函数

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 useEffect 的使用 useEffect 的概念理解 useEffect 依赖项参数说明 useEffect — 清除副作用 自定义Ho…

Baichuan2百川模型部署的bug汇总

1.4bit的量化版本最好不要在Windows系统中运行&#xff0c;大概原因报错原因是bitsandbytes不支持window&#xff0c;bitsandbytes-windows目前仅支持8bit量化。 2. 报错原因是机器没有足够的内存和显存&#xff0c;offload_folder设置一个文件夹来保存那些离线加载到硬盘的权…

【DC-DC】APS54085降压恒流 高辉度调光降压恒流芯片

产品描述 APS54085 是一款 PWM 工作模式,高效率、 外围简单、内置功率 MOS 管&#xff0c;适用于 5-100V 输入的高精度降压 LED 恒流驱动芯片。最大电流 2.0A。 APS54085 可实现线性调光和 PWM 调光&#xff0c; 线性调光有效电压范围 0.52-2.55V. PWM 调光频率范围 100…

React Native实现QQ等级皇冠太阳星星的展示-代码示例

代码 function LevelGetImages(level: number) {let res []const marks [{ mod: 20, image: Images.setting.level_king },{ mod: 15, image: Images.setting.level_queen },{ mod: 10, image: Images.setting.level_moon },{ mod: 5, image: Images.setting.level_star },…