当前位置: 首页 > news >正文

[Vroom] 位置与矩阵 | 路由集成 | 抽象,解耦与通信

第三章:位置与矩阵

欢迎回到 VROOM !

在第一章:输入与问题定义中我们学习了如何描述整体问题框架,在第二章:任务与运输工具中我们聚焦于核心实体——任务(Jobs)与运输工具(Vehicles)。

现在我们将解析路径规划中不可或缺的关键要素:如何在任务执行位置与运输工具起止点之间建立移动关系,这正是位置(Locations)与矩阵(Matrices)的协同作用。

设想我们有一辆从仓库出发的配送卡车需要访问两个客户点。要规划最优路线,必须明确以下移动参数:

  1. 仓库至第一个客户点的耗时/距离
  2. 客户点之间的移动参数
  3. 返回仓库的移动参数

缺少这些位置间移动数据的支撑,任何路径优化算法都将失去计算基础。

位置(Locations)定义

在 VROOM 中,位置代表地图上对路径规划有重要意义的地理节点,包括:

  • 运输工具的起始/终止位置
  • 任务执行位置

通过 JSON 输入的坐标定义示例:

{"vehicles": [{"id": 1,"start": [2.3522, 48.8566], // 车辆1起始位置(巴黎仓库)"end": [2.3522, 48.8566],   // 车辆1终止位置"capacity": [100],"profile": "car"}],"jobs": [{"id": 10,"location": [2.2945, 48.8584], // 任务10位置(埃菲尔铁塔)"service": 300,"delivery": [10]},{"id": 20,"location": [2.3490, 48.8641], // 任务20位置(卢浮宫)"service": 180,"delivery": [20]}]
}

该配置包含三个物理位置:

  1. 仓库坐标(2.3522, 48.8566)
  2. 任务10坐标(2.2945, 48.8584)
  3. 任务20坐标(2.3490, 48.8641)

VROOM 通过内部索引机制管理位置唯一性,相同坐标自动归并为同一位置。若使用预计算矩阵,可直接指定位置索引:

{"vehicles": [{ "id": 1, "start": 0, "end": 0, "profile": "car" } // 索引0表示仓库],"jobs": [{ "id": 10, "location": 1, "service": 300 },  // 索引1对应任务10{ "id": 20, "location": 2, "service": 180 }   // 索引2对应任务20],"matrices": {// 矩阵数据需与索引0/1/2对应}
}

内部 vroom::Location 结构体实现:

// 简化版位置结构体(src/structures/vroom/location.h)
class Location {
private:Index _index;            // 内部自动分配的索引OptionalCoordinates _coords; // 可选地理坐标bool _user_index;        // 是否为用户定义索引public:explicit Location(Index index);  // 用户索引构造器Location(const Coordinates& coords); // 坐标构造器// 获取索引/坐标等方法...
};

该结构支持坐标预定义索引两种定位方式的无缝切换。

矩阵(Matrices)

矩阵是存储位置间移动成本的方阵数据结构,主要类型包括:

  1. 耗时矩阵(Duration):存储位置间移动秒数
  2. 距离矩阵(Distance):存储位置间移动米数
  3. 成本矩阵(Cost):自定义成本指标

对于 N 个唯一位置,矩阵为 N×N 结构。矩阵元素 [i][j] 表示从索引 i 位置到索引 j 位置的移动成本。

矩阵数据在 JSON 中的配置示例:

{"matrices": {"car": {"durations": [[0, 600, 900],    // 仓库(0)到各点耗时[580, 0, 300],    // 任务10(1)到各点耗时[880, 320, 0]     // 任务20(2)到各点耗时],"distances": [[0, 5000, 7000],  // 仓库(0)到各点距离[4800, 0, 2500],  // 任务10(1)到各点距离[6800, 2700, 0]   // 任务20(2)到各点距离]}}
}

矩阵特性说明:

  • 非对称性:A→B 与 B→A 的耗时/距离可能不同(受单行道等因素影响)
  • 索引强关联:用户定义索引必须与矩阵行列顺序严格对应

内部矩阵存储采用一维向量优化访问效率:

template <class T> class Matrix {std::size_t n;          // 矩阵维度std::vector<T> data;    // 矩阵元素线性存储public:T* operator[](std::size_t i) { return data.data() + (i * n); // 模拟二维访问}// 其他方法...
};

数据处理全流程

VROOM 通过 vroom::io::parse 解析输入数据时执行以下关键步骤:

在这里插入图片描述

成本封装器(CostWrapper)是核心访问接口:

// 简化版成本访问逻辑
const auto& cost_wrapper = input.get_cost_wrapper(vehicle.profile);
Duration 耗时 = cost_wrapper.duration(起点索引, 终点索引);
Distance 距离 = cost_wrapper.distance(起点索引, 终点索引); 

应用场景推演

以仓库(0)→任务10(1)→任务20(2)→仓库(0)的路线为例:

移动段       耗时(s)   距离(m)
0→1        600      5000
1→2        300      2500  
2→0        880      6800
----------------------------
总计       1780     14300

VROOM 在优化过程中通过矩阵查询累计各路径成本,结合服务时间、时间窗等约束寻找全局最优解。

总结

位置与矩阵构成了移动成本计算的基础层。

通过精确配置位置关系与移动成本矩阵,或依赖路由引擎动态生成(详见第四章:路由集成),VROOM 得以构建完整的成本评估体系。

理解此章内容将为后续学习路由集成机制奠定重要基础。


第四章:路由集成

在前几章中,我们学习了如何定义路径规划问题的核心要素:

需要执行的任务(第二章:任务与运输工具)以及任务执行位置运输工具的起止点(第三章:位置与矩阵)。

我们了解到,获取位置间的移动耗时/距离数据对路径优化至关重要,这些信息存储在矩阵中。

但当用户仅拥有坐标数据而缺乏预计算矩阵时,VROOM 如何获取真实道路网络的移动参数?

这正是路由集成机制的核心价值。

连接现实世界的桥梁

路由集成是 VROOM 与专业地图服务交互的智能通道。不同于简单的直线距离计算,VROOM 通过集成以下主流路由引擎获取真实道路数据:

  • OSRM(开源路由引擎)
  • Openrouteservice (ORS)
  • Valhalla

当用户在 JSON 输入中指定车辆配置(如"car")并提供地理坐标时,VROOM 将自动通过路由集成模块完成以下流程:

  1. 数据收集汇总特定配置(如汽车)关联的所有坐标点
  2. 请求构建生成路由引擎可识别的矩阵查询请求
  3. 服务交互:通过 HTTP 协议发送请求至路由服务
  4. 结果解析提取响应中的矩阵数据并转换为 VROOM 标准格式
  5. 路径可视化:在求解完成后获取道路级路径坐标串(用于地图展示)

路由服务配置机制

用户通过命令行参数指定路由引擎类型与服务地址,而非 JSON 输入。典型启动命令示例:

vroom --router osrm -m http://localhost:5000 < 输入文件.json

参数解读:

  • --router osrm:选择 OSRM 引擎
  • -m http://localhost:5000:路由服务地址
  • 输入文件.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]}]
}

内部实现架构

VROOM 通过抽象化的路由封装器(Wrapper)实现多引擎支持,其核心类结构如下:

基础封装器接口

class Wrapper {
public:std::string profile;  // 支持的配置方案// 矩阵数据获取接口virtual Matrices get_matrices(const vector<Location>& locs) = 0;// 路径几何数据获取接口virtual void add_geometry(Route& route) = 0;
};

前文传送:[xiaozhi-esp32] 构建智能AI设备 | 开发板抽象层 | 通信协议层
(这个助手兼容多种硬件的架构设计,不同的硬件抽象为了统一的驱动,参考VFS的思想

HTTP 通信基类

class HttpWrapper : public Wrapper {
protected:Server _server;  // 服务端配置// 构建服务特定查询virtual string build_query(...) = 0;// 执行HTTP请求string run_query(const string& query) {// 实现HTTPS请求发送与接收}
};

具体引擎封装器(如OsrmRoutedWrapper)继承自HttpWrapper,实现服务特定的查询构建与结果解析逻辑。

数据处理全流程


相当于是借助第三方库的力量

应用场景

以包含仓库与两个配送点的汽车路径问题为例:

  1. 矩阵获取阶段

    • 封装器发送三个坐标点的矩阵查询至 OSRM
    • 接收包含 3x3 耗时/距离矩阵的 JSON 响应
    • 转换为vroom::Matrices对象供优化器使用
  2. 路径优化阶段

    • 求解器通过CostWrapper获取移动成本
    • 生成最优路径序列(如仓库→任务A→任务B→仓库)
  3. 几何数据获取

    • 对最终路径发送路线查询请求
    • 解析响应中的 GeoJSON 路径坐标串
    • 写入解决方案供地图可视化使用

总结

路由集成机制使 VROOM 具备以下核心能力:

  1. 现实道路建模:考虑单行道、限速等实际路况
  2. 多运输模式支持:通过不同配置方案实现汽车/卡车/自行车等差异计算
  3. 动态数据更新:实时获取最新路况信息(需路由引擎支持)
  4. 可视化增强:提供导航级路径细节展示

通过解耦路由服务优化引擎,VROOM 保持了架构的扩展性,可快速接入新型路由引擎。这种设计模式为处理复杂的物流路径问题提供了坚实基础。

在掌握路由集成机制后,我们将进入更具挑战性的约束条件处理环节:第五章:时间窗约束将解析如何在路径优化中纳入时效性要求

http://www.dtcms.com/a/270918.html

相关文章:

  • VScode SSH远程连接Ubuntu(通过SSH密钥对的方式)
  • LLM的表征做减法的是什么,自然语言是一个矩阵,怎么进行减法的
  • 爬虫-正则表达式
  • 【HarmonyOS6】获取华为用户信息
  • 出圈or出局?AI汽车“急速驶来”,市场淘汰赛一触即发
  • leetcode 每日一题 3439. 重新安排会议得到最多空余时间 I
  • 二刷 黑马点评 部署
  • 大模型MoE模型技术详解
  • 专题一_双指针_查找总价格为目标值的两个商品
  • 小程序主体变更全攻略:流程、资料与异常处理方案
  • WPF学习笔记(27)科学计算器
  • 李宏毅NLP-9-语音转换
  • 无人机报警器频段模块设计与运行要点
  • 小米路由器3C刷OpenWrt,更换系统/变砖恢复 指南
  • 在 Spring Boot 中如何使用 Assert 进行断言校验
  • 安卓设备信息查看器 - 功能介绍
  • 【bug修复积累】关于包装类型和基本数据类型的使用
  • 在Ubuntu上安装配置 LLaMA-Factory
  • Go 延迟调用 defer 用法详解
  • vscode 防止linux索引爆红
  • SQL Server通过存储过程实现HTML页面生成
  • Python爬取闲鱼价格趋势并可视化分析
  • Using Spring for Apache Pulsar:Message Production
  • 基于svga+uniapp的微信小程序动画组件开发指南
  • pytorch的详细安装教程
  • 百度文心一言开源ERNIE-4.5深度测评报告:技术架构解读与性能对比
  • “AI 曼哈顿计划”:科技竞赛还是人类挑战?
  • AI识别 + 食品质量安全预警系统
  • 18-C#改变形参内容
  • 工程改Mvvm