链接:https://github.com/VROOM-Project/vroom
docs:vroom

VROOM
是专为解决**车辆路径问题**设计的项目。
- 接收详细描述车辆和任务的问题定义,
集成路径规划
服务获取行程成本,- 运用启发式算法 和局部搜索等优化方法
- 在满足时间窗口 与载重 限制的前提下
寻找高效路径
,
最终提供结构化的解决方案输出。
可视化概览

章节导航
第一章:输入与问题定义
欢迎来到 VROOM !
假设我们经营一家物流公司。
-
每天都有需要取货的地点、送货的目的地,以及随时待命的运输车队。
-
每辆车都有
独特属性
------不同的载重能力、行驶速度、工作时间段,以及驾驶员处理特殊货物的资质(技能要求)。 -
我们的任务是
规划最优路线
,让所有车辆高效完成取送货任务。
这正是 VROOM 要解决的典型问题!但在规划路线前,VROOM 需要全面理解具体问题。
这就是"输入与问题定义"阶段的核心作用,相当于为 VROOM 填写详细订单,明确所有规划所需的信息
。
此阶段主要包含四个核心要素:
- 任务定义 :需要完成的
取货
、送货
或普通停靠点
(VROOM 中称为 Jobs 或 Shipments) - 运输资源定义 :可用车辆的载重能力、工作时间、技能要求及起止位置(VROOM 中称为 Vehicles)
- 规则定义 :
额外约束条件
,如载重限制(Load )、任务时间窗(Time Windows)或特殊技能需求 - 运输成本定义 :通过路径规划引擎_获取的
位置间移动耗时/距离
(使用 Matrices 矩阵)
这个初始阶段至关重要,因为它为 VROOM 提供了场景定制的原始数据。让我们看看如何将信息传递给 VROOM。
问题输入规范
前文传送:What is Json?
VROOM 接受 JSON (JavaScript 对象表示法)格式的结构化数据。JSON 通过键: 值
对组织数据,兼具机器可读性和人类可读性。
输入 JSON 通常包含vehicles
、jobs
,可能还有shipments
和matrices
等部分。以下是一个物流公司的简单示例:
json
{
"vehicles": [
{
"id": 1,
"start": [2.3522, 48.8566],
"end": [2.3522, 48.8566],
"capacity": [100],
"profile": "car"
}
],
"jobs": [
{
"id": 10,
"location": [2.2945, 48.8584],
"service": 300,
"delivery": [10]
},
{
"id": 20,
"location": [2.3490, 48.8641],
"service": 180,
"delivery": [20]
}
]
}
该示例包含:
- 车辆
id:1
- 起终点相同(巴黎某仓库坐标)
- 单品类载重能力
100
单位([100]
表示) - 使用
"car"
配置计算行程时间/距离
- 任务
id:10
位于埃菲尔铁塔(坐标),需300
秒服务时长,配送10
单位货物id:20
位于卢浮宫,需180
秒服务时长,配送20
单位货物
后续章节将扩展更多细节:取货量、时间窗、技能要求、不同配置及预计算矩阵等。
VROOM 的数据加载机制
在 VROOM 内部,JSON 数据被解析为Input
类的对象实例。
以下 C++ 代码演示了基本加载过程:
cpp
#include "structures/vroom/input/input.h" // 包含Input类头文件
#include "utils/input_parser.h" // 包含解析器头文件
// ...(函数内代码)
std::string my_problem_json = R"({
"vehicles": [
{ "id": 1, "start": [2.3522, 48.8566], "end": [2.3522, 48.8566], "capacity": [100], "profile": "car" }
],
"jobs": [
{ "id": 10, "location": [2.2945, 48.8584], "service": 300, "delivery": [10] },
{ "id": 20, "location": [2.3490, 48.8641], "service": 180, "delivery": [20] }
]
})"; // JSON输入字符串
vroom::Input problem_input; // 创建Input对象
// 使用解析器填充Input对象
vroom::io::parse(problem_input, my_problem_json, true); // true表示需要几何数据
// 此时problem_input已包含所有定义信息
// ... 准备进入求解阶段!
代码解析:
- 创建
Input
对象并传入JSON字符串 vroom::io::parse
函数解析JSON并填充problem_input
true
参数表示需要输出路径几何信息(详见路径规划集成)
Input 对象的内部处理
完成解析后,Input
对象执行关键预处理:
- 数据校验:检测重复ID、格式错误、缺失数据等,异常时抛出错误
- 位置管理:处理所有坐标点,建立内部索引系统以优化矩阵计算
- 矩阵准备 :
- 分析各车辆的
profile
配置(如"car"
) - 若未提供预计算矩阵,准备从
OSRM/ORS/Valhalla
等引擎获取 - 若已提供矩阵,进行加载验证
- 分析各车辆的
- 兼容性检查 :
- 技能匹配:车辆是否符合任务技能要求
- 载重检查:车辆是否能承载任务货物量
- 时间可行性 :考虑车辆工作时间能否满足任务时间窗(详见时间窗)
- 成本预估:计算解决方案的最大可能成本上界,优化算法效率
处理流程可视化:

核心代码示例:
cpp
// 摘自 src/problems/vrp.cpp
VRP::VRP(const Input& input) : _input(input) {
// Input已完成基础检查
assert(!_input.vehicles.empty());
}
该代码段展示了基础VRP问题类
如何通过Input对象初始化,确保输入数据经过严格验证。
总结
本章介绍了使用Input
对象定义VROOM问题的基本流程。
-
我们了解了如何通过JSON描述车辆、任务及约束条件,以及
vroom::io::parse
函数如何将JSON转换为内部数据结构。 -
Input对象通过执行数据校验和预处理,为后续优化算法奠定基础。
深入理解输入结构和验证机制是高效使用VROOM的关键。
下一章我们将详细解析输入中的核心实体:任务与车辆。
第二章:任务与运输工具
在第一章:输入与问题定义中,我们学习了如何使用 JSON 等结构化格式向 VROOM 描述配送问题的整体框架。
现在我们将深入解析构成路径规划问题的两大核心要素:任务 (需要执行的操作)和运输工具(执行操作的资源)
任务(Jobs)
任务代表运输工具需要在特定位置执行的具体操作,可能是取货、送货或必要停靠点。
其定义包含以下关键要素:
核心属性
id
:唯一标识符(如:10号任务)location
:执行位置(地理坐标或矩阵索引)service
:现场操作耗时(如装卸货物所需时间,单位:秒)pickup/delivery
:货物存取量(支持多品类货物管理)skills
:特殊技能需求(如冷链运输资质)time_windows
:强制时间窗口(任务执行时段限制)priority
:优先级权重(数值越高越优先分配)
示例 JSON 定义:
json
{
"jobs": [
{
"id": 10,
"location": [2.2945, 48.8584], // 埃菲尔铁塔坐标
"service": 300, // 5分钟服务时长
"delivery": [10] // 配送10单位A类货物
},
{
"id": 20,
"location": [2.3490, 48.8641], // 卢浮宫坐标
"service": 180, // 3分钟服务时长
"delivery": [20] // 配送20单位A类货物
}
]
}
此配置定义了两个配送任务,分别位于巴黎地标位置,涉及不同货物量与服务时长
运输工具(Vehicles)
运输工具定义执行任务的资源能力边界,主要参数包括:
核心属性
id
:唯一标识符(如:1号货车)start/end
:起止位置(支持独立设置仓库坐标)profile
:运输模式(决定路径计算方式,如"car"使用汽车导航数据)capacity
:多品类载货容量(如:[100]表示A类货物最大100单位)skills
:技能清单(限制可执行任务类型)time_window
:作业时间窗(车辆可用时段)costs
:成本模型(包含固定成本与里程/时间系数)
示例 JSON 定义:
json
{
"vehicles": [
{
"id": 1,
"start": [2.3522, 48.8566], // 巴黎仓库坐标
"end": [2.3522, 48.8566], // 返回同一仓库
"capacity": [100], // A类货物最大载量
"profile": "car" // 使用汽车路径配置
}
]
}
该配置定义了一辆从中央仓库出发的配送车辆,具备单日100单位A类货物的运输能力
VROOM 内部建模机制
通过vroom::io::parse
函数解析 JSON 后,系统将生成以下核心数据结构:
cpp
// 任务结构体(src/structures/vroom/job.h)
struct Job {
Location location; // 执行位置
const Id id; // 唯一ID
const Duration default_service; // 标准服务时长
const Amount delivery; // 配送量
const Amount pickup; // 取货量
const Skills skills; // 技能要求
};
cpp
// 运输工具结构体(src/structures/vroom/vehicle.h)
struct Vehicle {
const Id id; // 唯一ID
std::optional<Location> start; // 起始位置
std::optional<Location> end; // 终止位置
const std::string profile; // 运输模式
const Amount capacity; // 载货容量
const Skills skills; // 技能清单
};
这些结构体精确映射 JSON 输入数据,构建出配送问题的完整数字孪生模型
数据处理流程
通过Input解析json数据,生成可处理的结构体
结语
任务与运输工具的定义构成车辆路径问题的基石。
精确描述任务需求(地点、耗时、货量)与运输能力(载量、时段、技能),是生成高效路径方案的前提。
下一章将深入解析位置关系的数学表达:第三章:位置与矩阵。