OR-Tools VRP中是否可针对不同维度使用多个RegisterTransitCallback?
OR-Tools VRP多TransitCallback注册问题解答
首先明确结论:完全支持针对不同维度多次调用RegisterTransitCallback注册独立回调,你遇到的所有维度仅生效最后一次回调的问题,属于代码实现层面的疏漏,并非OR-Tools本身不支持该用法。
问题成因
RegisterTransitCallback调用后会返回一个唯一的整型回调ID,你遇到的异常是因为注册多个回调时没有分别存储每个回调对应的ID,添加维度时统一传入了最后一次注册返回的ID,导致所有维度都复用了同一个回调逻辑。
正确实现步骤
- 为每个独立维度单独实现对应的transit回调逻辑,比如距离维度做路径长度计算、载重维度做货物重量累加、时间维度做行程时间计算,各回调逻辑互相独立
- 依次调用
RegisterTransitCallback注册每个回调,用不同的变量存储每次返回的回调ID,严禁用同一个变量重复接收ID导致值被覆盖 - 调用
AddDimension添加对应维度时,传入和该维度匹配的回调ID,不要所有维度统一传入同一个ID
代码示例(Python)
# 1. 实现不同维度的独立回调 # 距离回调:计算两点间行驶距离 def distance_callback(from_index, to_index): from_node = manager.IndexToNode(from_index) to_node = manager.IndexToNode(to_index) return distance_matrix[from_node][to_node] # 载重回调:累加下一个节点的货物重量 def load_callback(from_index, to_index): to_node = manager.IndexToNode(to_index) return demand[to_node] # 2. 分别注册回调,存储各自的ID distance_callback_id = routing.RegisterTransitCallback(distance_callback) load_callback_id = routing.RegisterTransitCallback(load_callback) # 3. 添加维度时传入对应回调ID # 添加距离维度 routing.AddDimension( distance_callback_id, 0, # 无松弛量 15000, # 单辆车最大行驶距离上限 True, # 累计值从起点0开始计算 "Distance" ) # 添加载重维度 routing.AddDimension( load_callback_id, 0, # 无松弛量 50, # 单辆车最大载重上限 True, # 累计值从起点0开始计算 "Load" )
注意事项
- OR-Tools VRP的transit回调仅支持返回整数,如果你需要计算浮点型的距离、时间等数值,需要提前做固定比例缩放后转成整数传入,比如将公里数乘以1000转成米为单位的整数
- 回调内部尽量不要做复杂的IO操作或者大量计算,会大幅降低求解效率,依赖的静态数据(如距离矩阵、需求数组)建议提前预处理好存在内存中直接读取
内容的提问来源于stack exchange,提问作者ChrisP
相关产品推荐
相关产品推荐

