You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OR-Tools路由问题:含晚时间窗节点时路径混乱的优化需求

OR-Tools路径规划时间窗问题及解决建议

问题背景

现有11个节点:10个时间窗为[0, horizon]的节点,1个时间窗从下午2点(需转换为对应数值单位,如假设12点对应600、下午2点对应800)开始至horizon的节点。不含该晚时间窗节点时,路径可在12点完成;加入后,Solver生成大量循环路径拖延时间以满足该节点时间窗,而非使用已启用的Slack等待至下午2点后访问该节点。

时间窗通过Time维度CumulVar的SetMin()/SetMax()建模,节点SlackVar的Max值设为horizon,Time维度slack_max设为horizon,force_start_cumul_to_zero为false。期望Solver生成将晚时间窗节点置于路径末尾并使用Slack等待的优化路径。

核心问题分析

  • 目标函数导向偏差:当前仅用SetSpanCostCoefficientForAllVehicles(1)最小化路径时间跨度,但循环路径的时间跨度和「先完成所有节点+Slack等待」的跨度可能相同,Solver会随机选择可行解,而循环路径在初始解生成阶段更容易被构造。
  • 初始解策略不合理:BEST_INSERTION策略优先插入节点,易忽略时间窗的时序合理性,生成包含循环的初始路径,后续局部搜索难以跳出局部最优。
  • Slack无使用激励:未对Slack设置成本优势,Solver没有动力选择「等待」而非「循环」,两者在当前目标下成本一致。
  • 时间窗建模存在错误:示例代码中对非depot节点的时间窗End设置为SetMin(kHorizon)(应为SetMax(kHorizon)),需确保晚时间窗节点的Start约束正确。

解决建议

1. 调整目标函数,惩罚循环行为

增加总行驶时间的权重,让循环路径的成本远高于「完成节点+等待」的成本:

// 新增:将行驶时间计入弧成本,最小化总行驶时长
routing_model.SetArcCostEvaluatorOfVehicle(time_transit_callback_2_indices[0], 0);
// 保留原有的时间跨度惩罚
routing_model.GetMutableDimension("Time")->SetSpanCostCoefficientForAllVehicles(1);

2. 更换初始解策略

改用更倾向于生成无循环路径的初始策略,为后续局部搜索提供合理起点:

parameters.set_first_solution_strategy(
    operations_research::FirstSolutionStrategy::PATH_CHEAPEST_ARC
);

3. 强制晚时间窗节点为路径末尾(业务允许时)

通过约束确保晚节点之后只能前往终点,直接避免循环:

// 假设晚时间窗节点索引为11(根据实际节点数调整)
int64_t late_node_index = 11;
solver->AddConstraint(
    solver->MakeEquality(routing_model.NextVar(late_node_index), routing_model.End(0))
);

4. 修正时间窗建模

确保晚时间窗节点的CumulVar约束正确:

// 下午2点对应的数值(根据实际时间单位调整)
int64_t late_node_start_time = 800;
time_dimension.CumulVar(late_node_index)->SetMin(late_node_start_time);
time_dimension.CumulVar(late_node_index)->SetMax(kHorizon);

5. 优化局部搜索参数

启用路径邻域搜索并延长求解时间,帮助Solver跳出循环路径的局部最优:

parameters.mutable_local_search_operators()->set_use_path_lns(
    operations_research::OptionalBoolean::BOOL_TRUE
);
parameters.mutable_time_limit()->set_seconds(60); // 延长求解时间

6. 移除冲突的Finalizer设置

当前对起点CumulVar设置AddVariableMaximizedByFinalizer与「起点时间固定为0」的约束冲突,建议移除:

// 删除该行代码
// routing_model.AddVariableMaximizedByFinalizer(time_dimension.CumulVar(routing_model.Start(vehicle_idx)));

内容的提问来源于stack exchange,提问作者Maria Mat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 14:35:55