本页介绍了使用 Route Optimization API 的路线规划生命周期,从确定路线需求开始,到在系统中获得集成路线规划结束。
按照路线规划的各个阶段操作,您可以实现以下目标:
- 将车队运营情况映射到代码中:将实体车队、复杂限制条件和业务目标转化为 API 代码。
- 优化业务路线规划:了解如何优化路线规划,使其能够满足您的目标并改进日常运营。
- 部署到生产环境:将路线规划纳入日常运营,以实现路线规划。
下图显示了路线方案的生命周期。
路线规划的实施阶段是指您首次集成 API 或业务需求发生重大变化时。它涵盖了第 1 阶段到第 5 阶段。
日常运营阶段的负担较轻,细化程度也最低。 它涵盖了第 2 阶段到第 4 阶段。
路线的生命周期阶段如下:
- 确定问题的范围:确定并整理目标、资源、任务和限制条件,以便在开始使用 API 之前全面了解您的运营情况。
- 映射数据:将您的业务实际情况转换为 API 参数,以便路线规划反映您希望车队如何运营。
- 创建请求并获取路线方案:将数据输入到 API 中,然后获取优化后的路线方案。
- 优化路线规划:测试路线规划,并通过调整限制条件和目标进行迭代,确保其满足您的所有需求。
- 集成路线规划:将路线规划与现有系统相关联,以提供可据以行动的导航。
确定问题范围
在使用该 API 之前,您需要将日常运营的详细信息整理成清晰的数据类别。这样一来,您就可以清楚地了解当前有哪些资源和任务、这些资源和任务受到哪些限制,以及您希望通过车队实现哪些目标,从而开始实施流程。
确定资源和任务
规划路线方案时,一个重要步骤是确定资源和任务,即车辆和货件。
| 车辆 | 装运 |
|---|---|
|
|
确定限制条件
限制条件是指您在车辆使用和货物处理方面受到的限制。它们决定了您的大部分运营,对于创建优化的路线规划至关重要。
限制通常分为两类:
| 硬性限制 | 软性限制 |
|---|---|
| 这些是无法突破的限制。例如,卡车无法承载超过其最大载重量的货物,并且司机无法在商店关门后取货。 | 这些是必要时可以违反的偏好设置,但通常会产生罚款。例如,您可能希望仅将卡车装载到 80% 的容量,或在目标时间之前送达,但您也愿意为了获得更好的路线而超出这些限制。 |
常见限制包括:
- 载货量限制:车辆可载的最大重量、体积或物品数量。
- 时间范围:某个地点可供到访的具体时间段,或司机的具体轮班时间。
- 费用:车辆运行或跳过配送的费用。该 API 的主要目标之一是生成经济实惠的路线方案。
- 驾驶员休息时间:驾驶员在工作一定时间后,根据劳动法通常需要休息一段时间。
确定您的业务目标
确定资源、任务及其限制后,接下来就要确定对您的业务最重要的指标。这些目标与限制条件相辅相成,可帮助您在规划路线时确定最重要的因素。
以下是一些业务目标示例:
| 车队规模 | 距离 | 时间 | 费用 |
|---|---|---|---|
| 您是想尽可能减少使用的车辆数量,还是想充分利用整个车队来提前结束工作日? | 您是想选择最短的路线以节省燃料,还是想选择可能更长但速度更快的路线(因为会使用高速公路)? | 您是想尽量减少总工作时间,还是优先考虑在特定时间到达目的地,这可能会延长路线上的时间? | 您是想尽可能减少工资和燃料等运营费用,还是愿意接受更高的费用来满足严格的截止期限? |
映射您的数据
收集完数据后,请将数据映射为与 API 的属性相匹配。这样,优化器就可以获得所有信息,从而返回符合您业务实际情况的路线方案。
使用下表中的参数来映射您在确定问题范围部分中映射的资源、任务、限制条件和目标。
变量映射
| 实际概念 | API 参数 | 说明 |
|---|---|---|
| 司机或车辆 | model.vehicles[] |
表示车队中的单辆车。 |
| 配送中心位置 |
vehicles[].startWaypointvehicles[].endWaypoint
|
车辆开始和结束路线的位置。 |
| 您的营业时间 |
model.globalStartTimemodel.globalEndTime
|
整个车队运营的最早开始时间和最晚结束时间。 |
| 任务或软件包 | model.shipments[] |
表示作业。可以是 pickup、delivery 或两者兼而有之。 |
| 任务位置 |
pickups[].arrivalWaypointdeliveries[].arrivalWaypoint
|
工作地点所在的地理位置。 |
| 服务时间 |
pickups[].durationdeliveries[].duration
|
在位置完成任务(例如卸货)所花费的时间,不包括行程时间。 |
限制条件映射
| 实际应用限制 | API 参数 | 说明 |
|---|---|---|
| 车辆容量 | vehicles[].loadLimits |
设置车辆容量的硬性或软性限制。如果某批货件的 loadDemand 超过剩余限额,则不会分配该批货件。 |
| 软件包大小 | shipments[].loadDemands |
相应货件占用的车辆容量。 |
| 车辆限制 | shipments[].allowedVehicleIndices |
限制货件,使其只能由特定车辆或司机取件或送达。 |
| 营业时间 | shipments[].pickups[].timeWindows 或 shipments[].deliveries[].timeWindows |
设置可前往某个地点的时段。如果车辆无法在此时间范围内到达,则跳过相应配送。 |
| 轮班时长限制 | vehicles[].routeDurationLimit |
设置特定司机可以工作的时间上限(例如,最长 8 小时),无论全局结束时间如何。 |
| 驾驶员休息时间 | vehicles[].breakRule |
强制执行特定的休息规则,例如在工作一定时间后强制休息。 |
| 道路限制 | vehicles[].travelMode |
指定出行方式(例如,DRIVE 或 BICYCLE)。此参数会将路线限制为合法道路,并确定用于计算出行时间的行驶速度。 |
目标映射
| 实际目标 | API 参数 | 说明 |
|---|---|---|
| 尽量减少车队规模 | vehicles[].fixedCost |
针对使用车辆收取一次性费用。较高的固定费用会迫使路线优先使用较少的车辆,而不是增加总距离或工作时间。 |
| 尽量缩短距离 | vehicles[].costPerKilometer |
按每公里行驶距离收取费用。优先选择较短的路线,以节省燃油和减少磨损。 |
| 尽量缩短总时间 | vehicles[].costPerHour |
按车辆的每小时使用时间(包括行驶时间和等待时间)收取费用。优先考虑更快地完成任务。 |
| 尽量缩短驾车时间 | vehicles[].costPerTraveledHour |
专门针对移动时间应用费用。这样可以区分堵车(费用高)和在停车点等待(费用可能较低)。 |
| 优先处理某些任务 | shipments[].penaltyCost |
如果跳过特定配送,则应用相应费用。将此值设为高可确保关键任务的优先级高于可选任务。 |
创建请求并获取响应
使用 Route Optimization API 生成路线方案涉及以下步骤:
- 配置环境:设置 Google Cloud 云项目、启用 API 并配置身份验证。如需查看相关说明,请参阅使用入门。 您只需执行此步骤一次。
- 发送请求:使用上一部分中定义的数据映射构建请求正文。如需了解端点、标头和请求格式,请参阅发出 API 请求。
- 了解响应:从 API 获得响应后,请了解路线规划以及每个参数的含义。请参阅解读响应。
优化路线规划
将现实世界的物流转化为 API 成本和限制是一项复杂的任务。您的初始路线规划可能不符合您的业务目标或司机的预期。优化路线规划是一个迭代过程,即测试返回的路线并调整参数,直到找到可实现目标的设置。
调整目标和限制条件
如果生成的路线方案不符合您的需求,您可以修改某些参数以获得不同的结果。收紧或放宽参数会改变路线方案中冲突目标的解决方式,而放宽参数是发现导致路线方案出错的参数的有效方法。
下表列出了常见的路由问题以及您可以调整的参数来解决这些问题。
| 场景 | 参数 | 调整 | 说明 |
|---|---|---|---|
| 跳过了一项重要配送 | shipments[].penaltyCost |
提高其价值,或向其他货件添加违约金 | 如果配送方式是可选的,请提高其惩罚成本,以便优先考虑该配送方式。如果发货是强制性的(没有违约金),请将违约金添加到其他不太重要的货件中。这样一来,这些配送就成了可选配送,从而为重要货件腾出车辆时间和运力。 |
| 因时间安排而跳过递送 | softStartTime/softEndTime |
添加软时间窗口 | 硬时间窗口会舍弃即使只晚了一分钟的任务。软窗口期允许司机在略微偏离预定时间的情况下到达,只需付出“代价”,而不会导致任务失败。 |
| 因重量而跳过递送 | loadLimits[].softMaxLoad和costPerUnitAbove |
添加软负载需求 | 允许车辆略微超出其理想容量(但会受到处罚),而不是遗漏包裹。 |
| 因车队过载而跳过递送 | model.vehicles[] 或 shipments[].timeWindows |
添加车辆或放松时间窗口 | 如果当前车队运送的货物太多,尤其是在高峰时段,请增加车辆或延长配送时间,以分散工作负载。 |
| 路线过长或效率低下 | vehicles[].costPerKilometer/costPerHour |
添加费用或提高费用价值 | 告知 API 旅行费用较高,促使 API 舍弃遥远且孤立的停靠点,从而为车队创建更紧凑的路线。 |
| 司机轮班时间过长 | vehicles[].routeDurationLimit 或 model.vehicles[] |
添加时长限制,或添加车辆和限制 | 对司机在路上的总时间强制执行硬性上限(例如 8 小时)。仅添加车辆并不会缩短路线,除非您还应用了时长限制,以强制求解器在更大的车队中分配工作负载。 |
更新路线方案
您经常需要更新路线方案,同时保持基础路线不变,例如向正在工作的司机的行程中添加接单。为此,请使用注入参数,这些参数可为 API 提供基于您之前解决方案的起点,从而使 API 能够修改现有方案,而不是从头开始计算新方案。
以下是使用注入参数更新路线方案的不同方式:
- 将上一个响应中的路线传递到新请求的
injectedFirstSolutionRoutes字段中。这有助于加快优化搜索速度,并且在日常运营开始之前(例如整合临时安排的货件)重新规划时非常有用。 - 使用
injectedSolutionConstraint字段控制变化程度。 当操作已在进行中时,此功能非常有用,可让您保留驱动程序的当前序列或修复已执行的部分计划。 - 通过将
interpretInjectedSolutionsUsingLabels设置为true,确保更新后的路线仍分配给正确的车辆。在实验中添加或移除货件和车辆时,此功能非常有用,因为它可以根据标签(而非索引)匹配路线。这要求所有车辆和货件标签都具有唯一性。
整合路线规划
最终确定的路线方案是一个数据对象,表示在遵循您的限制条件和目标的前提下,对资源和任务进行优化管理。通过将此路线规划集成到您的系统中,在日常运营中使用它。 这通常包括为车队经理直观呈现路线规划,以及向司机调度逐向导航指令。
可视化
为了让车队经理能够验证和监控您的路线规划,您可以通过以下方式直观呈现路线规划:
为了让车队经理能够验证和监控您的路线规划,您可以在信息中心地图上显示路线规划。根据您当前的开发阶段,您可以通过以下方式直观呈现路线规划:
- 无需代码即可探索:您可以使用开源的路线优化应用,了解该 API 如何将您的数据转换为地图上的实际路径。此 Web 应用是一个探索性工具,可让您构建方案、调整限制参数,并在编写任何代码之前直观地呈现生成的路线规划。
- 显示拜访顺序:您可以在地图上以带编号的点显示拜访顺序,以便在自己的系统中评估优化和调度方案。为此,请在 API 响应的每个路线中找到
visits数组。此数组中的项的顺序与驱动程序应执行这些项的顺序完全一致。您可以遍历此列表,使用shipmentIndex检索每个停靠点的地理位置坐标,并使用地图库根据这些停靠点在列表中的顺序在地图上渲染带编号的标记。 - 绘制实际路线:您可以在地图上直观呈现确切的规划路线,了解优化工具为何选择特定顺序。此多段线表示用于规划和评估的预期路径,而不是驾驶员行驶的实时路线。在请求中设置
populatePolylines: true,以获取每条路线的encodedPolyline字段,并使用 Maps JavaScript API 中的google.maps.geometry.encoding.decodePath()方法对其进行解码。
向司机派单
您可以使用 Navigation SDK 将精细导航功能集成到您的司机应用中,也可以提供指向 Google 地图消费者应用的深层链接。
- Navigation SDK:如果您有自定义的司机应用,可以集成 Navigation SDK for Android 或 iOS,以便在应用内提供逐向导航。
您可以将 API 响应中的任务信息集成到您的系统中,并使用 SDK 进行导航。如需将 API 响应中的路线传递给 SDK,请在请求中设置
populateTransitionPolylines: true。这会为响应中的每个过渡生成一个routeToken。 - Fleet Engine:对于高级车队管理,您可以将 API 生成的路线规划导入 Fleet Engine,以实时监控路线执行情况。虽然该 API 提供用于评估的预期路径的多段线,但 Fleet Engine 会将您计划的访问顺序与实时车辆跟踪信息配对。