OR Tools如何限制两个指定节点之间的可访问节点数量
OR-Tools 多起点终点场景下的节点区间访问数量约束实现
你可以通过自定义计数维度+区间差值约束的方式实现需求,无需绑定车辆全局配置,适配同车辆多起止对的场景:
实现步骤
- 添加专属节点计数维度
先注册一个单节点回调,每经过一个普通访问点就返回计数步长1,你指定的start、end节点返回步长0,再基于这个回调添加路由维度:
// 此处以C#为例,其他语言逻辑一致 int countCallback(int fromIndex) { int node = routing.IndexToNode(fromIndex); if (node == start || node == end) return 0; return 1; } int countCallbackIndex = routing.RegisterUnaryTransitCallback(countCallback); routing.AddDimension( countCallbackIndex, 0, // 无松弛量,不需要额外缓存 9999, // 全局最大计数设为远大于场景上限的数值即可 false, // 不需要强制所有车辆起始维度值为0,仅做区间约束 "node_count" ); var countDimension = routing.GetDimensionOrDie("node_count");
- 添加起止节点区间差值约束
仅约束你指定的start到end区间内的计数值差值不超过上限,和你已有的激活变量约束联动:
// 你原有激活约束保留 solver().Add(this.solver.ActiveVar(start) == this.solver.ActiveVar(end)); // 新增区间计数约束,示例上限为2 solver().Add( countDimension.CumulVar(end) - countDimension.CumulVar(start) <= 2 ).OnlyEnforceIf(solver.ActiveVar(start));
补充说明
- 该约束完全独立于车辆全局配置,同一辆车有多对
start-end节点时,给每对节点单独加对应差值约束即可,互不干扰 - 若需要设置中间节点数下限,可额外加
countDimension.CumulVar(end) - countDimension.CumulVar(start) >= 下限值的约束即可 - 约束仅在当前
start节点被激活时生效,不会影响其他无关路径的计算
内容的提问来源于stack exchange,提问作者ZantAgg
相关产品推荐
相关产品推荐

