manager = pywrapcp.RoutingIndexManager(
len(data["time_matrix"]), data["num_vehicles"], data["depot"]
)
print(f"number of nodes: {manager.GetNumberOfNodes()}")
print(f"number of vehicles: {manager.GetNumberOfVehicles()}")
print(f"depot: {data['depot']}")
routing = pywrapcp.RoutingModel(manager)
# demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback)
# routing.AddDimensionWithVehicleCapacity(
# demand_callback_index,
# 0, # null capacity slack
# data["vehicle_capacities"], # vehicle maximum capacities
# True, # start cumul to zero
# "Capacity"
# )
# 注册回调函数并添加约束
transit_callback_index = routing.RegisterTransitCallback(time_and_cost_callback)
routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
# Add Time Window constraint
time1 = "Time"
routing.AddDimension(
transit_callback_index,
10000000, # allow waiting time
# so 3-20 400 3-50 250 5-20 200 5-50 300
# hom 3-20 1150 3-50 1500 5-20 850 5-50 1150
# ran 3-20 700 3-50 350 5-20 5-50 700
100000000, # maximum time per vehicle
False, # Don't force start cumul to zero.
time1
)
time_dimension = routing.GetDimensionOrDie(time1)
# 只添加软时间窗惩罚,不使用 SetRange
for location_idx, time_window in enumerate(data["time_windows"]):
index = manager.NodeToIndex(location_idx)
# 设置软下界:如果早到,则产生惩罚
time_dimension.SetCumulVarSoftLowerBound(index, time_window[0], 1)
# 设置软上界:如果晚到,则产生惩罚
time_dimension.SetCumulVarSoftUpperBound(index, time_window[1], 4)
# 确保每个客户只能被一辆车服务一次
for node in range(1, manager.GetNumberOfNodes()):
index = manager.NodeToIndex(node)
time_dimension.CumulVar(index).SetMin(1)
for vehicle_id in range(data["num_vehicles"]):
start_index = routing.Start(vehicle_id)
routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(start_index))
end_index = routing.End(vehicle_id)
routing.AddVariableMinimizedByFinalizer(time_dimension.CumulVar(end_index))
# Ensure each vehicle visits at least one node
routing.AddVariableMinimizedByFinalizer(routing.ActiveVar(start_index))
# Solve the problem with search parameters
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC
# search_parameters.local_search_metaheuristic = routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
# search_parameters.time_limit.seconds = 1200 # 增加求解时间限制
# Solve the problem.
print("Start solving...")
solution = routing.SolveWithParameters(search_parameters)