在OR-Tools的VRPTW中,如何添加仅允许特定车辆子集访问站点的约束?
在OR-Tools的VRPTW中添加车辆-节点服务许可约束
针对你给出的车辆-节点服务许可矩阵,核心思路是禁止不被允许的车辆访问对应节点,用OR-Tools可以通过直接约束路径变量实现,以下是具体实现方案(以Python为例):
1. 定义服务许可映射
先把你的矩阵转换成代码中的映射关系(注意OR-Tools中车辆ID默认从0开始,对应你矩阵里的vehicle1→ID0、vehicle2→ID1,以此类推):
# 节点ID → 允许服务的车辆ID列表 allowed_vehicles = { 1: [0, 1], # node1仅允许vehicle1、vehicle2服务 2: [1, 2], # node2仅允许vehicle2、vehicle3服务 3: [2, 3] # node3仅允许vehicle3、vehicle4服务 }
2. 添加约束到VRPTW模型
在初始化完manager、routing对象(以及时间窗、容量等基础约束)后,遍历每个节点和车辆,为不允许的组合添加约束:
from ortools.constraint_solver import routing_enums_pb2 from ortools.constraint_solver import pywrapcp # 省略模型初始化、基础约束设置的代码(如时间窗、容量限制等) # ... # 遍历所有节点,添加服务许可约束 for node_id, allowed_ids in allowed_vehicles.items(): # 将节点ID转换为OR-Tools内部的节点索引 node_index = manager.NodeToIndex(node_id) # 遍历所有车辆 for vehicle_id in range(routing.vehicles()): if vehicle_id not in allowed_ids: # 约束:该车辆不得访问此节点(路径变量取值为0) routing.solver().Add( routing.VehicleVar(node_index, vehicle_id) == 0 ) # 执行求解、结果输出逻辑 # ...
关键说明
routing.VehicleVar(node_idx, vehicle_id)是OR-Tools内置的布尔变量,取值1表示车辆访问该节点,0表示不访问。直接约束其等于0,就能彻底禁止对应车辆服务该节点。- 如果你的节点索引和业务ID不对应(比如起点是索引0,客户节点从索引1开始),要确保
manager.NodeToIndex()的转换正确,避免索引错误。
内容的提问来源于stack exchange,提问作者heman33
相关产品推荐
相关产品推荐

