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

如何使用Or-Tools(Java)为路径优化弧段添加特定容量约束

可以基于OR-Tools Routing模块实现弧段级的载重约束,Java版本有完整API支持,不需要魔改源码,具体实现方案如下:

实现前提

你已经完成基础CVRP逻辑搭建,且通过addDimension方法注册了载重维度(常规命名为Capacity),维度中每个节点的累计变量(CumulVar)对应该节点位置的货车实时载重。

核心逻辑

你需要的约束本质是:当路径选择弧(i,j)通行时,货车在i点的实时载重(即驶入弧段时的载重)必须小于等于该弧段的最大允许载重。
你提到的规则capacity(i) - capacity(j) <= allowed capacity between the two steps和上述逻辑完全等价:弧段(i,j)之间无装卸货操作,j点的载重等于i点载重减去j点的卸货量/加上j点的装货量,差值为节点j的固定需求值,天然为非负且远小于常规限重,真正触发限制的是弧段上的实时载重值。

Java版本具体实现步骤
  • 第一步:预处理弧段限重矩阵
    构建二维数组long[][] arcMaxLoad存储所有节点对之间的载重上限:无特殊限制的普通路段直接填车辆最大额定载重,存在桥梁、限高杆等限重要求的弧段填入对应限制值,完全禁止货车通行的弧段可直接在距离/成本矩阵中赋值为极大值(大于所有可行路径的总成本即可),提前剪枝提升求解效率。
  • 第二步:获取模型核心实例
    拿到已经初始化完成的三个核心对象:路由索引管理器RoutingIndexManager、路由模型RoutingModel、载重维度实例RoutingDimension capacityDim。
  • 第三步:逐弧段绑定约束
    遍历所有可通行的节点对,针对有限重要求的弧段,通过onlyEnforceIf方法绑定约束生效条件:仅当路径实际选中该弧段时,才校验载重是否符合限重要求。核心代码如下:
    // 全局车辆最大载重,用于跳过无特殊限制的弧段减少冗余约束
    final long VEHICLE_MAX_CAP = 6;
    for (int i = 0; i < manager.getNumberOfNodes(); i++) {
        for (int j = 0; j < manager.getNumberOfNodes(); j++) {
            if (i == j) continue;
            long currentArcLimit = arcMaxLoad[i][j];
            // 限重等于车辆最大载重的弧段无需额外加约束,减少求解器计算量
            if (currentArcLimit >= VEHICLE_MAX_CAP) continue;
            // 转换节点索引为模型内部索引
            long indexI = manager.nodeToIndex(i);
            long indexJ = manager.nodeToIndex(j);
            // 获取i点的实时载重变量
            IntVar loadAtINode = capacityDim.getCumulVar(indexI);
            // 添加约束:i点载重 <= 弧段限重,仅当弧(i,j)被选中通行时生效
            model.addLessOrEqual(loadAtINode, currentArcLimit)
                 .onlyEnforceIf(routing.arcVarAsBool(indexI, indexJ));
        }
    }
    
验证说明

针对你提到的测试场景:节点i处货车载重为3单位,弧(i,j)对应桥梁限重2单位,求解器会自动识别该弧段违反约束,不会将其纳入最终规划路径,完全符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:36:20