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

OR-Tools求解VRP时如何为特定车辆排除指定路径组合

OR-Tools VRP 指定车辆专属路径排斥约束实现方案

你需要实现的约束核心是对指定车辆,禁止其配送的节点集合恰好等于预设的排斥节点子集,不限制节点的访问顺序,也不禁止节点在搭配其他非排斥集合节点时被访问,原有节点级的访问权限控制接口粒度过粗,无法满足该需求,可以通过基于节点归属判断的自定义硬约束实现,完全匹配你给出的判定规则。

实现逻辑

约束的判定规则可以拆解为:对任意车辆k和它对应的排斥节点集合S,以下两个条件不能同时成立:

  • S内的所有配送节点全部分配给车辆k
  • 所有不在S内的配送节点都没有分配给车辆k
    只要两个条件不同时满足,路径就合法,不管S内节点的访问顺序如何,也不管S内节点是否和其他节点搭配出现。

具体实现步骤

  • 第一步:预处理排斥规则
    提前将所有车辆的排斥路径转为无序集合存储(忽略节点访问顺序),建议用frozenset类型方便后续匹配,结构为{车辆id: [排斥节点集合1, 排斥节点集合2, ...]}。注意所有节点要提前通过manager.NodeToIndex()转为路由模型内部索引,不要直接使用原始节点编号避免索引不匹配。
  • 第二步:添加自定义硬约束
    借助OR-Tools CP求解器原生支持的布尔表达式能力,直接对上述判定规则加硬约束即可,参考代码如下:
    from ortools.constraint_solver import pywrapcp
    
    # 以下代码在routing模型、index manager、depot索引初始化完成后添加
    depot_index = manager.NodeToIndex(0)  # 替换为你实际的depot节点索引
    # 提取所有配送节点(排除仓库depot)
    delivery_nodes = [
        idx for idx in range(manager.GetNumberOfIndices())
        if idx != depot_index
    ]
    # 配置每台车的排斥集合,示例对应题目中车辆A(id=0)的规则
    vehicle_forbidden_sets = {
        0: [
            frozenset([manager.NodeToIndex(X)]),  # 禁止仅访问X的单节点路径
            frozenset([manager.NodeToIndex(X), manager.NodeToIndex(Y)])  # 禁止仅访问X、Y的双节点路径(任意顺序)
        ]
        # 其他车辆的排斥规则按相同格式追加即可
    }
    
    solver = routing.solver()
    for vehicle_id, forbidden_set_list in vehicle_forbidden_sets.items():
        for forbidden_set in forbidden_set_list:
            # 表达式:禁止集合内的所有节点都分配给了当前车辆
            all_forbidden_served = sum(
                routing.VehicleVar(node_idx) == vehicle_id
                for node_idx in forbidden_set
            ) == len(forbidden_set)
            # 表达式:禁止集合外的所有配送节点都没分配给当前车辆
            no_other_node_served = sum(
                routing.VehicleVar(node_idx) == vehicle_id
                for node_idx in delivery_nodes
                if node_idx not in forbidden_set
            ) == 0
            # 加硬约束:两个表达式不能同时为真,否则为非法路径
            solver.AddConstraint(
                ~(all_forbidden_served & no_other_node_served)
            )
    

适配说明

  • 该实现完全匹配你给出的可行/不可行判定规则:
    • 会自动禁止排斥集合节点任意顺序的全组合路径、仅包含排斥集合节点的路径
    • 不会禁止排斥集合节点搭配其他节点的路径、排斥集合的真子集路径
    • 不会限制单个节点的访问权限,节点只要不凑成完整的排斥集合就可以被对应车辆访问
  • 如果需要禁止某台车不执行任何配送任务(空驶),只需要给对应车辆的排斥集合列表追加空集合frozenset()即可,无需额外编写约束。
  • 常规场景下(节点数<200、车辆数<50、单车辆排斥集合数<100)该实现的性能损耗可以忽略,大规模场景下提前对重复的排斥集合做去重即可。
  • 多台车辆的排斥规则完全独立,不会出现跨车辆的规则干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:45:38