使用ortools库导致Jupyter Notebook内核崩溃问题求助
排查ortools代码导致Jupyter内核崩溃的建议
先直接点明代码中的致命错误,这些是引发内核崩溃的核心原因:
代码中的关键错误
- 参数顺序完全颠倒:
create_routing_model函数定义的参数顺序是(distance_matrix, depot, num_vehicles),但调用时写成了create_routing_model(distance_matrix, num_vehicles, depot),导致起点(depot)和车辆数的赋值完全混乱,直接破坏模型初始化逻辑。 - 返回值与接收变量不匹配:
create_routing_model返回routing, manager,但调用时用routing, search_parameters接收,把manager错误当成了搜索参数。搜索参数需要单独创建,这种错误会导致SolveWithParameters传入非法参数,触发底层崩溃。 - 未定义变量引用:
time_dimension.SetSpanUpperBoundForVehicle(LOCATION_TIME_LIMIT)中,LOCATION_TIME_LIMIT未定义,实际定义的变量是VEHICLE_LOCATION_TIME_LIMIT,会抛出NameError,在Jupyter环境中极易引发内核异常。 - 维度方法调用错误:
SetSpanUpperBoundForVehicle需要指定车辆ID,正确调用应为time_dimension.SetSpanUpperBoundForVehicle(VEHICLE_LOCATION_TIME_LIMIT, vehicle_id),缺少车辆ID参数会导致方法调用失败。
修复后的核心代码片段
# 创建路径规划模型 def create_routing_model(distance_matrix, num_vehicles, depot): tsp_size = len(distance_matrix) manager = pywrapcp.RoutingIndexManager(tsp_size, num_vehicles, depot) routing = pywrapcp.RoutingModel(manager) # 设置成本函数(距离矩阵) 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] transit_callback_index = routing.RegisterTransitCallback(distance_callback) routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index) # 设置路径时间维度 dimension_name="Time" routing.AddDimension( transit_callback_index, SLACK_AMOUNT, MAX_ROUTING_TIME_LIMIT, IS_CUMUL_ZERO, dimension_name ) # 设置每个地点的停留时间上限 time_dimension = routing.GetDimensionOrDie(dimension_name) # 修复变量名和参数 for vehicle_id in range(num_vehicles): time_dimension.SetSpanUpperBoundForVehicle(VEHICLE_LOCATION_TIME_LIMIT, vehicle_id) return routing, manager # 求解路径规划问题 def solve_routing_problem(): num_vehicles = 1 depot = 0 routing, manager = create_routing_model(distance_matrix, num_vehicles, depot) # 正确创建搜索参数 search_parameters = pywrapcp.DefaultRoutingSearchParameters() search_parameters.time_limit.seconds = SOLVER_TIME_LIMIT solution = routing.SolveWithParameters(search_parameters) if solution: print_solution(routing, manager, solution) # 传入manager用于节点转换 # 打印求解结果 def print_solution(routing, manager, solution): print("Objective: {} km".format(solution.ObjectiveValue())) index = routing.Start(0) plan_output = "Route:\n" route_distance = 0 while not routing.IsEnd(index): node = manager.IndexToNode(index) # 用manager转换index到node route_name = list(locations.keys())[node] plan_output += f" -> {route_name}\n" previous_index = index index = solution.Value(routing.NextVar(index)) # 正确获取弧的距离成本 route_distance += routing.GetArcCostForVehicle(previous_index, index, 0) print(plan_output) print("Total Distance: {} km".format(route_distance))
通用排查步骤
- 分步测试模块:单独运行距离矩阵生成代码,验证矩阵值是否合理;单独测试模型初始化逻辑,确认无参数错误。
- 添加异常捕获:在
solve_routing_problem中加入try-except块,捕获并打印异常信息,避免内核直接崩溃:def solve_routing_problem(): try: # 原有代码 except Exception as e: print(f"Error occurred: {str(e)}") - 检查环境兼容性:确认ortools版本与Python版本匹配(建议使用ortools 9.x以上版本,Python 3.8-3.11),通过
pip install --upgrade ortools更新库。 - 限制求解规模:先使用3-4个节点测试代码,确认逻辑正常后再扩展到更多节点,避免因问题规模过大导致内存溢出。
内容的提问来源于stack exchange,提问作者Bruno Peixoto
相关产品推荐
相关产品推荐

