微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Google或工具:当在ApplyLocksToAllVehicles中未传递任何部分路由时,没有解决方案,但是如果您指定了部分路由,则存在解决方案

如何解决Google或工具:当在ApplyLocksToAllVehicles中未传递任何部分路由时,没有解决方案,但是如果您指定了部分路由,则存在解决方案

这没有意义,因为不应用部分路由约束至少应导致尽可能多的解决方案。完整的代码在下面,但是相关的部分在这里

routing.CloseModel()
partial_route_list = data['partial_routes']
routing.ApplyLocksToAllVehicles(partial_route_list,False)

data['partial_routes']中的所有列表仅包含user manual中的传输节点。当data['partial_routes'] = [[],[0,1],[],[]]我有5辆车)或其他变型时,OR-Tools可以找到解决方案。但是当data['partial_routes'] = [[],[]]时,它找不到解决方案。

完整代码

# Create the routing index manager.
manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']),data['num_vehicles'],data['start'],data['end'])

# Create Routing Model.
routing = pywrapcp.RoutingModel(manager)

# Add resource constraints (which vehicles are allowed to visit which nodes)
for index in range(len(data['node_name'])):
    allowed_vehicles = [-1]
    if data['num_ramp'][index] > 0 or np.isnan(data['num_ramp'][index]):
        allowed_vehicles.extend(
            [key for key,val in enumerate(data['vehicle_type']) if val == 'van' and key in data['allowed_vehicles'][index]])
    if data['num_dock_high'][index] > 0 or data['num_dock_high'][index]:
        allowed_vehicles.extend(
            [key for key,val in enumerate(data['vehicle_type']) if val == 'truck' and key in data['allowed_vehicles'][index]])
    routing.VehicleVar(index).SetValues(allowed_vehicles)

# Create and register a transit distance callback.
def distance_callback(from_index,to_index):
    """Returns the distance between the two nodes."""
    # Convert from routing variable Index to distance matrix NodeIndex.
    from_node = manager.IndexToNode(from_index)
    to_node = manager.IndexToNode(to_index)
    return data['distance_matrix'][from_node][to_node]

transit_distance_callback_index = routing.RegisterTransitCallback(distance_callback)

# Add distance constraint.
routing.AddDimension(
    transit_distance_callback_index,# no slack
    sum([sum(x) for x in data['distance_matrix']]),# vehicle maximum travel distance
    True,# start cumul to zero
    'distance')
distance_dimension = routing.GetDimensionorDie('distance')

# Add capacity constraints.
def demand_weight_callback(from_index):
    """Returns the weight demand of the node."""
    # Convert from routing variable Index to demands NodeIndex.
    from_node = manager.IndexToNode(from_index)
    return data['demand_weight'][from_node]

demand_weight_callback_index = routing.RegisterUnaryTransitCallback(demand_weight_callback)
routing.AddDimensionWithVehicleCapacity(
    demand_weight_callback_index,# null capacity slack
    data['vehicle_capacity_weight'],# vehicle maximum capacities
    True,# start cumul to zero
    'Weight Capacity')

def demand_volume_callback(from_index):
    """Returns the volume demand of the node."""
    # Convert from routing variable Index to demands NodeIndex.
    from_node = manager.IndexToNode(from_index)
    return data['demand_volume'][from_node]

demand_volume_callback_index = routing.RegisterUnaryTransitCallback(demand_volume_callback)
routing.AddDimensionWithVehicleCapacity(
    demand_volume_callback_index,# null capacity slack
    data['vehicle_capacity_volume'],# start cumul to zero
    'Volume Capacity')

def demand_pallet_callback(from_index):
    """Returns the pallet demand of the node."""
    # Convert from routing variable Index to demands NodeIndex.
    from_node = manager.IndexToNode(from_index)
    return data['demand_pallet'][from_node]

demand_pallet_callback_index = routing.RegisterUnaryTransitCallback(demand_pallet_callback)
routing.AddDimensionWithVehicleCapacity(
    demand_pallet_callback_index,# null capacity slack
    data['vehicle_capacity_pallet'],# start cumul to zero
    'Pallet Capacity')

# Define pickup and delivery constraints
for request in data['pickups_deliveries']:
    pickup_index = manager.NodetoIndex(request[0])
    delivery_index = manager.NodetoIndex(request[1])
    routing.AddPickupAndDelivery(pickup_index,delivery_index)
    routing.solver().Add(
        routing.VehicleVar(pickup_index) == routing.VehicleVar(
            delivery_index))
    routing.solver().Add(
        distance_dimension.CumulVar(pickup_index) <=
        distance_dimension.CumulVar(delivery_index))

# Create and register a transit time callback.
def transit_time_callback(from_index,to_index):
    """Returns the travel time only between the two nodes."""
    # Convert from routing variable Index to time matrix NodeIndex.
    from_node = manager.IndexToNode(from_index)
    to_node = manager.IndexToNode(to_index)
    return data['time_matrix'][from_node][to_node]

transit_time_callback_index = routing.RegisterTransitCallback(transit_time_callback)

# Create and register a time callback.
def time_callback(from_index,to_index):
    """Returns the travel and dock time between the two nodes."""
    # Convert from routing variable Index to time matrix NodeIndex.
    transit_time = transit_time_callback(from_index,to_index)
    to_node = manager.IndexToNode(to_index)
    if to_node in data['pickups']:
        dock_time = data['load_time'][to_node]
    else:
        dock_time = data['unload_time'][to_node]
    return transit_time + dock_time

time_callback_index = routing.RegisterTransitCallback(time_callback)

# Add time windows constraint.
routing.AddDimension(
    time_callback_index,3 * MIN_PER_HR * SEC_PER_MIN,# allow waiting time
    24 * MIN_PER_HR * SEC_PER_MIN,# maximum time per vehicle
    False,# Don't force start cumul to zero.
    'Time')
time_dimension = routing.GetDimensionorDie('Time')

# Add time window constraints for each location.
for location_idx,time_window in enumerate(data['time_windows']):
    index = manager.NodetoIndex(location_idx)
    time_dimension.CumulVar(index).SetRange(time_window[0],time_window[1])

# Add driving duration constraint.
routing.AddDimension(
    transit_time_callback_index,# Don't force start cumul to zero.
    'Driving Duration')
driving_duration_dimension = routing.GetDimensionorDie('Driving Duration')

for v in range(data['num_vehicles']):
    # Limit max on-duty time for each vehicle
    routing.solver().Add(
        time_dimension.CumulVar(routing.End(v)) - time_dimension.CumulVar(routing.Start(v)) <= MAX_TIME_ON_DUTY)
    # Limit max driving time for each vehicle
    routing.solver().Add(driving_duration_dimension.CumulVar(routing.End(v)) <= MAX_TIME_DRIVING)

# Minimize on-duty duration.
for i in range(data['num_vehicles']):
    routing.AddVariableMaximizedByFinalizer(
        time_dimension.CumulVar(routing.Start(i)))
    routing.AddVariableMinimizedByFinalizer(
        time_dimension.CumulVar(routing.End(i)))

# Define cost of each arc for each vehicle
for v in range(data['num_vehicles']):
    def cost_callback(from_index,to_index):
        """Returns the cost between the two nodes."""
        # Convert from routing variable Index to distance matrix NodeIndex.
        from_node = manager.IndexToNode(from_index)
        to_node = manager.IndexToNode(to_index)
        cost_per_mi = data['cost_per_mi'][v]
        if data['node_name'][from_node] != data['node_name'][to_node]:
            if data['is_hub'][to_node] is True:
                stop_cost = data['cost_per_hub_to_hub'][v]
            else:
                stop_cost = data['cost_per_stop'][v]
        else:
            stop_cost = 0
        return data['distance_matrix'][from_node][to_node] / METERS_PER_MI * cost_per_mi + stop_cost
    
    cost_callback_index = routing.RegisterTransitCallback(cost_callback)
    routing.SetArcCostEvaluatorOfVehicle(cost_callback_index,v)

search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.local_search_Metaheuristic = (
    routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
search_parameters.time_limit.seconds = 30
search_parameters.solution_limit = 5
search_parameters.first_solution_strategy = (
    routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC)

# Collect multiple solutions.
solution_collector = routing.solver().AllSolutionCollector()

for location_idx in range(len(data['time_windows'])):
    index = manager.NodetoIndex(location_idx)
    time_var = time_dimension.CumulVar(index)
    duration_var = driving_duration_dimension.CumulVar(index)
    next_var = routing.Nextvar(index)
    solution_collector.Add(time_var)
    solution_collector.Add(duration_var)
    solution_collector.Add(next_var)
for v in range(data['num_vehicles']):
    index = routing.Start(v)
    time_var = time_dimension.CumulVar(index)
    duration_var = driving_duration_dimension.CumulVar(index)
    next_var = routing.Nextvar(index)
    solution_collector.Add(time_var)
    solution_collector.Add(duration_var)
    solution_collector.Add(next_var)

    index = routing.End(v)
    time_var = time_dimension.CumulVar(index)
    duration_var = driving_duration_dimension.CumulVar(index)
    solution_collector.Add(time_var)
    solution_collector.Add(duration_var)

routing.AddSearchMonitor(solution_collector)

# Lock partial routes
# Reference: https://github.com/google/or-tools/blob/master/examples/python/cvrptw_plot.py
routing.CloseModel()
partial_route_list = data['partial_routes']
routing.ApplyLocksToAllVehicles(partial_route_list,False)

# Solve
solution = routing.solveWithParameters(search_parameters)

这可能是矫kill过正,但是下面定义了data

{
    "node_name": [
        "Cleveland Food Hub","Cleveland Food Hub","Dummy Food Hub","East","MLK","MCHS","Choffin","Refugee Response","Refugee Response"
    ],"delivery_notes": [
        NaN,NaN,NaN
    ],"is_hub": [
        true,true,false,"num_dock_high": [
        2.0,2.0,1.0,0.0,"num_ramp": [
        1.0,"distance_matrix": [
        [
            0,126018,127656,129435,129815,125621,40935,24559,40939,24517
        ],[
            0,[
            123102,123102,7510,9289,9669,4207,90590,90599,90594,90642
        ],[
            122953,122953,7958,3332,3712,2818,87035,87044,87038,87086
        ],[
            124709,124709,9713,502,5168,88790,88800,88794,88842
        ],[
            125089,125089,10093,5548,89170,89180,89174,89222
        ],[
            121938,121938,4204,2866,5216,5596,84376,84385,84380,84428
        ],[
            24281,24281,91665,93303,89558,89332,85598,9,4,51
        ],[
            24272,24272,91674,93312,89568,89341,85608,6,42
        ],[
            24278,24278,91668,93306,89562,89336,85602,48
        ],[
            24230,24230,91716,93354,89610,89383,85650,51,42,48,0
        ]
    ],"time_matrix": [
        [
            0,4723,4836,4985,5022,4685,1980,2111,1981,2099
        ],[
            4607,4607,618,767,804,421,3879,3881,3880,3892
        ],[
            4649,4649,602,363,399,329,3855,3857,3856,3868
        ],[
            4783,4783,736,352,83,456,3989,3991,3990,4002
        ],[
            4827,4827,779,396,85,500,4032,4034,4033,4045
        ],[
            4525,4525,423,341,478,514,3754,3756,3755,3767
        ],[
            2070,2070,3962,4075,4223,4241,3925,2,1,13
        ],[
            2068,2068,3965,4078,4225,4244,3928,3,10
        ],[
            2069,2069,3963,4076,4224,4242,3927,12
        ],[
            2057,2057,3976,4090,4237,4256,3940,15,11,14,"time_windows": [
        [
            21600,36000
        ],[
            21600,[
            28800,43200
        ],[
            50400,57600
        ],72000
        ],72000
        ]
    ],"demand_weight": [
        0.0,50.0,100.0,80.0,75.0,0.0
    ],"demand_volume": [
        0.0,25.0,"demand_pallet": [
        0.0,3.0,"load_description": [
        NaN,"interesting","why not?","testing","echo\nbye!","test\nhello\ngoodbye","fascinating","load_time": [
        1800,1800,1200,900,0
    ],"unload_time": [
        1200,600,"allowed_vehicles": [
        [
            0,4
        ],4
        ]
    ],"vehicle_type": [
        "van","van","truck","truck"
    ],"vehicle_capacity_weight": [
        3500,4650,4300,7200,17000
    ],"vehicle_capacity_volume": [
        260,480,800,950,1700
    ],"vehicle_capacity_pallet": [
        2,8,12
    ],"cost_per_mi": [
        1.0,1.25,2.25,2.5
    ],"cost_per_stop": [
        5,5,5
    ],"cost_per_hub_to_hub": [
        50,50,50
    ],"num_vehicles": 5,"pickups_deliveries": [
        [
            0,6
        ],[
            1,7
        ],[
            2,8
        ],[
            3,9
        ],[
            4,[
            5,11
        ]
    ],"pickups": [
        0,"start": [
        12,13,16
    ],"end": [
        12,"partial_routes": [
        [],1
        ],[]
    ]
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。