首页 > 解决方案 > 如何在车辆路线问题中将超过 75 的容量设置为未分配

问题描述

我正在研究一个车辆路线问题,其中我对容量破坏感兴趣。我想将超过 75 的容量/负载设置为未分配。我正在分享代码和输出的一瞥

    def create_data_model_cap_con(df_user,no_fos):
        """Stores the data for the problem."""
        data = {}
        data['distance_matrix'] = dist.pairwise(df_user[['lat','lon']].to_numpy())*6373)
        data['depot'] = 0
        data['num_vehicles'] = no_fos
        data['demands'] = df_user["no_cases"].to_list()
        data['vehicle_capacities'] = [75] *no_fos
        return data

def print_solution_cap_con(data, manager, routing, assignment):
    """Prints assignment on console."""
    # Display dropped nodes.
    dropped_nodes = 'Dropped nodes:'
    for node in range(routing.Size()):
        if routing.IsStart(node) or routing.IsEnd(node):
            continue
        if assignment.Value(routing.NextVar(node)) == node:
            dropped_nodes += ' {}'.format(manager.IndexToNode(node))
    print(dropped_nodes)
    # Display routes
    total_distance = 0
    total_load = 0
    for vehicle_id in range(data['num_vehicles']):
        index = routing.Start(vehicle_id)
        plan_output = 'Route for vehicle {}:\n'.format(vehicle_id)
        route_distance = 0
        route_load = 0
        while not routing.IsEnd(index):
            node_index = manager.IndexToNode(index)
            route_load += data['demands'][node_index]
            plan_output += ' {0} Load({1}) -> '.format(node_index, route_load)
            previous_index = index
            index = assignment.Value(routing.NextVar(index))
            route_distance += routing.GetArcCostForVehicle(
                previous_index, index, vehicle_id)
        plan_output += ' {0} Load({1})\n'.format(manager.IndexToNode(index),
                                                 route_load)
        plan_output += 'Distance of the route: {}m\n'.format(route_distance)
        plan_output += 'Load of the route: {}\n'.format(route_load)
        print(plan_output)
        total_distance += route_distance
        total_load += route_load
    print('Total Distance of all routes: {}m'.format(total_distance))
    print('Total Load of all routes: {}'.format(total_load))


def distance_cap_con(x,y,data):
    dis = data['distance_matrix'][x][y]
    return dis


def get_routes_cap_con(solution, routing, manager,df_user,data):
  """Get vehicle routes from a solution and store them in an array."""
  # Get vehicle routes and store them in a two dimensional array whose
  # i,j entry is the jth location visited by vehicle i along its route.
  routes = []
  #routes_dist = []  
  for route_nbr in range(routing.vehicles()):
    index = routing.Start(route_nbr)
    route = [manager.IndexToNode(index)]
    
    while not routing.IsEnd(index):
      index = solution.Value(routing.NextVar(index))
      route.append(manager.IndexToNode(index))
    routes.append(route)
    #routes = get_routes(solution, routing, manager)
    routes_t = pd.DataFrame(routes).T
    col_to_iter = routes_t.columns
    routes_t['route_info'] = routes_t.index
    routes_t = pd.melt(routes_t, id_vars=['route_info'], value_vars=col_to_iter)
    routes_t = routes_t.drop_duplicates(subset='value', keep="first")

    df_user['value'] = df_user.index
    df_user_out = pd.merge(df_user, routes_t, on="value")
    
    df_user_out = df_user_out.sort_values(by=['variable','route_info'])
    df_user_out['route_lag'] = df_user_out.groupby('variable')['value'].shift(-1).fillna(0)
    df_user_out['route_lag'] = df_user_out['route_lag'].astype(np.int64)
    df_user_out['route_info'] = df_user_out['route_info'].astype(np.int64)
    df_user_out['dist'] = df_user_out.apply(lambda row: distance_cap_con(row['route_lag'], row['value'],data), axis=1)
    
  return df_user_out

def get_sol_cap_con(sub_dist_fil,fos_cnt,state_fil):
    df_user_org_sub = df_user_org[(df_user_org.District == sub_dist_fil) & (df_user_org.State == state_fil) ]
    df_user_org_sub.reset_index( inplace=True,drop=True)
    print(sub_dist_fil," no fos",fos_cnt)

    fos_cnt=fos_cnt

    
    
    data = create_data_model_cap_con(df_user_org_sub,fos_cnt)

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

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


    # Create and register a transit 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_callback_index = routing.RegisterTransitCallback(distance_callback)

    # Define cost of each arc.
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)


    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.time_limit.seconds = 200
    search_parameters.solution_limit = 100
    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.FromSeconds(30)


    # Solve the problem.
    solution = routing.SolveWithParameters(search_parameters)

    out_df = get_routes_cap_con(solution, routing, manager,df_user_org_sub,data)

    # Print solution on console.
    if solution:
        try:
            print_solution_cap_con(data, manager, routing, solution)
        except:
            print('Exception')
    return   out_df

我想添加一些功能,我可以将大于 75 的负载设置为未分配。

输出->

kachchh  no fos 1
Dropped nodes:
Route for vehicle 0:
 0 Load(1) ->  1 Load(2) ->  2 Load(3) ->  4 Load(4) ->  3 Load(5) ->  6 Load(6) ->  5 Load(7) ->  9 Load(8) ->  7 Load(9) ->  8 Load(10) ->  10 Load(11) ->  186 Load(12) ->  185 Load(13) ->  184 Load(14) ->  182 Load(15) ->  152 Load(16) ->  151 Load(17) ->  179 Load(18) ->  180 Load(19) ->  177 Load(20) ->  175 Load(21) ->  176 Load(22) ->  178 Load(23) ->  181 Load(24) ->  183 Load(25) ->  188 Load(26) ->  187 Load(27) ->  161 Load(28) ->  158 Load(29) ->  153 Load(30) ->  154 Load(31) ->  155 Load(32) ->  156 Load(33) ->  157 Load(34) ->  160 Load(35) ->  11 Load(36) ->  159 Load(37) ->  172 Load(38) ->  165 Load(39) ->  162 Load(40) ->  163 Load(41) ->  164 Load(42) ->  166 Load(43) ->  167 Load(44) ->  168 Load(45) ->  169 Load(46) ->  170 Load(47) ->  171 Load(48) ->  173 Load(49) ->  174 Load(50) ->  111 Load(51) ->  110 Load(52) ->  109 Load(53) ->  108 Load(54) ->  107 Load(55) ->  106 Load(56) ->  105 Load(57) ->  104 Load(58) ->  103 Load(59) ->  102 Load(60) ->  101 Load(61) ->  100 Load(62) ->  99 Load(63) ->  98 Load(64) ->  97 Load(65) ->  96 Load(66) ->  95 Load(67) ->  94 Load(68) ->  42 Load(69) ->  41 Load(70) ->  40 Load(71) ->  39 Load(72) ->  38 Load(73) ->  37 Load(74) ->  36 Load(75) ->  28 Load(76) ->  21 Load(77) ->  93 Load(78) ->  12 Load(79) ->  13 Load(80) ->  14 Load(81) ->  15 Load(82) ->  16 Load(83) ->  26 Load(84) ->  19 Load(85) ->  17 Load(86) ->  20 Load(87) ->  18 Load(88) ->  22 Load(89) ->  23 Load(90) ->  27 Load(91) ->  25 Load(92) ->  29 Load(93) ->  24 Load(94) ->  32 Load(95) ->  31 Load(96) ->  30 Load(97) ->  33 Load(98) ->  34 Load(99) ->  43 Load(100) ->  46 Load(101) ->  47 Load(102) ->  49 Load(103) ->  145 Load(104) ->  144 Load(105) ->  143 Load(106) ->  142 Load(107) ->  138 Load(108) ->  137 Load(109) ->  120 Load(110) ->  135 Load(111) ->  134 Load(112) ->  125 Load(113) ->  55 Load(114) ->  133 Load(115) ->  136 Load(116) ->  141 Load(117) ->  140 Load(118) ->  139 Load(119) ->  132 Load(120) ->  131 Load(121) ->  130 Load(122) ->  129 Load(123) ->  128 Load(124) ->  127 Load(125) ->  124 Load(126) ->  121 Load(127) ->  126 Load(128) ->  123 Load(129) ->  122 Load(130) ->  119 Load(131) ->  118 Load(132) ->  117 Load(133) ->  116 Load(134) ->  115 Load(135) ->  114 Load(136) ->  113 Load(137) ->  58 Load(138) ->  57 Load(139) ->  56 Load(140) ->  54 Load(141) ->  53 Load(142) ->  52 Load(143) ->  51 Load(144) ->  35 Load(145) ->  44 Load(146) ->  45 Load(147) ->  48 Load(148) ->  50 Load(149) ->  59 Load(150) ->  79 Load(151) ->  78 Load(152) ->  74 Load(153) ->  73 Load(154) ->  76 Load(155) ->  77 Load(156) ->  75 Load(157) ->  71 Load(158) ->  72 Load(159) ->  70 Load(160) ->  69 Load(161) ->  68 Load(162) ->  67 Load(163) ->  66 Load(164) ->  65 Load(165) ->  64 Load(166) ->  63 Load(167) ->  62 Load(168) ->  61 Load(169) ->  60 Load(170) ->  80 Load(171) ->  87 Load(172) ->  86 Load(173) ->  92 Load(174) ->  91 Load(175) ->  90 Load(176) ->  89 Load(177) ->  88 Load(178) ->  85 Load(179) ->  84 Load(180) ->  83 Load(181) ->  82 Load(182) ->  81 Load(183) ->  196 Load(184) ->  193 Load(185) ->  194 Load(186) ->  195 Load(187) ->  197 Load(188) ->  198 Load(189) ->  205 Load(190) ->  204 Load(191) ->  203 Load(192) ->  202 Load(193) ->  201 Load(194) ->  200 Load(195) ->  199 Load(196) ->  112 Load(197) ->  189 Load(198) ->  148 Load(199) ->  146 Load(200) ->  147 Load(201) ->  150 Load(202) ->  149 Load(203) ->  192 Load(204) ->  191 Load(205) ->  190 Load(206) ->  0 Load(206)
Distance of the route: 894m
Load of the route: 206

Total Distance of all routes: 894m
Total Load of all routes: 206

对于超过 75 的所有负载,我希望结果显示为“未分配”。帮助

标签: python-3.xfunctionvehicle-routing

解决方案


推荐阅读