如何配置Google OR-Tools以调用更多车辆而非生成长路径规划?
解决方案
针对Google OR-Tools车辆路径规划的问题,可通过以下配置调整实现调用更多车辆、避免跨区路径的目标:
1. 确保正确配置可用车辆总数
首先检查RoutingModel初始化时是否将车辆数量设为8,这是算法调用更多车辆的基础前提:
# 假设depot为仓库节点索引 routing = pywrapcp.RoutingModel(num_locations, 8, depot)
若之前车辆数设置小于8,算法自然只会调用对应数量的车辆。
2. 添加区域约束限制跨区服务
给每个任务节点标记所属区域(如左侧为0、右侧为1),通过两种方式限制车辆跨区:
方式一:硬约束——指定车辆服务固定区域
提前给车辆分配专属区域,比如前4辆车仅服务左侧,后4辆仅服务右侧:
# 假设每个节点的区域信息存在node_region列表中,索引对应节点id def region_constraint_callback(from_index, to_index): from_node = routing.IndexToNode(from_index) to_node = routing.IndexToNode(to_index) # 仓库节点允许所有车辆访问,跳过约束 if from_node == depot or to_node == depot: return 0 # 给车辆分配区域:vehicle_id <4 服务左侧,否则服务右侧 vehicle_region = 0 if routing.VehicleIndex() <4 else 1 # 目标节点区域不符则返回极大值(禁止通行) if node_region[to_node] != vehicle_region: return 1000000 return 0 # 添加约束维度 region_constraint_dimension = routing.AddDimension( region_constraint_callback, 0, # 松弛量 1000000, # 最大累积值 True, # 从仓库开始累积 "RegionConstraint" )
方式二:软约束——给跨区路径加高额惩罚
若不需要严格禁止跨区,仅通过成本引导算法规避:
def modified_cost_callback(from_index, to_index): from_node = routing.IndexToNode(from_index) to_node = routing.IndexToNode(to_index) # 原有的行驶时间+载重成本计算 original_cost = calculate_original_cost(from_node, to_node) # 跨区则追加惩罚成本 if from_node != depot and to_node != depot: if node_region[from_node] != node_region[to_node]: original_cost += 5000 # 可根据实际成本量级调整惩罚值 return original_cost # 替换原成本回调 routing.SetArcCostEvaluatorOfAllVehicles(modified_cost_callback)
3. 调整搜索参数优化结果
当前3秒的搜索时间较短,算法可能来不及探索多车辆方案,可调整策略并延长时间:
search_parameters = pywrapcp.DefaultRoutingSearchParameters() # 改用更倾向于多车辆的初始解策略 search_parameters.first_solution_strategy = ( routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION) search_parameters.local_search_metaheuristic = ( routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH) # 延长搜索时间,给算法足够空间探索最优解 search_parameters.time_limit.FromSeconds(10) # 启用路径拆分启发式,鼓励将长路径拆分到更多车辆 search_parameters.local_search_operators.use_path_splitting = True
4. 平衡成本参数权重
若载重成本权重过高,算法可能优先合并路径满足载重要求,而非规避长距离。可提高行驶时间的权重:
def cost_callback(from_index, to_index): from_node = routing.IndexToNode(from_index) to_node = routing.IndexToNode(to_index) # 提高行驶时间成本的权重,让长距离路径成本更高 time_cost = calculate_time_cost(from_node, to_node) * 2 load_cost = calculate_load_cost(from_node, to_node) return time_cost + load_cost
内容的提问来源于stack exchange,提问作者Ahsan Mukhtar
相关产品推荐
相关产品推荐

