コード例 #1
0
def main():
# Enter filename of a manifest. Will be automated in production version.
  fname = '243884'
# Run Java code GraphHopper on manifest to create distance matrix as csv.
  os.system('java -jar dmatrix.jar ./manifests/'+fname +'.csv')
# Load manifest data and split.
  df = pd.read_csv('./manifests/'+fname+'.csv')
  city_names = df['Address'][:]
  lats = df['Latitude'][:]
  lons = df['Longitude'][:]


  tsp_size = len(df)

  # Create routing model
  if tsp_size > 0:
    # TSP of size tsp_size
    # Second argument = 1 to build a single tour (used for TSP with single delivery truck rather than full
    # vehicle routing problem with fleet).
    # Nodes are indexed from 0 to tsp_size - 1. By default the start of
    # the route is node 0.
    routing = pywrapcp.RoutingModel(tsp_size, 1, 0) #had to add depot index
    search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()

    # Setting first solution heuristic: the
    # method for finding a first solution to the problem.
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

    # Create the distance callback, which takes two arguments (the from and to node indices)
    # and returns the distance between these nodes.

    dist_between_nodes = CreateDistanceCallback(fname)
    dist_callback = dist_between_nodes.Distance
    routing.SetArcCostEvaluatorOfAllVehicles(dist_callback)
    # Solve, returns a solution if any.
    assignment = routing.SolveWithParameters(search_parameters)
    if assignment:
      # Solution cost.
      print "Total distance: " + str(assignment.ObjectiveValue()) + " meters\n"
      # Inspect solution.
      # Only one route here; otherwise iterate from 0 to routing.vehicles() - 1


      leadingurl = 'http://localhost:8989/?point='
      trailingurl = '&locale=en-US&vehicle=car&weighting=fastest&elevation=false&use_miles=false&layer=Omniscale'
      urlspace = '%2C'
      urlnext = '&point='
      theurl = leadingurl

      route_number = 0
      index = routing.Start(route_number)  # Index of the variable for the starting node.
      route = ''

      while not routing.IsEnd(index):
        # Convert variable indices to node indices in the displayed route.
        route += str(city_names[routing.IndexToNode(index)]) + ' -> '
        theurl += str(lats[routing.IndexToNode(index)]) + urlspace + str(lons[routing.IndexToNode(index)]) + urlnext
        index = assignment.Value(routing.NextVar(index))
      route += str(city_names[routing.IndexToNode(index)])
      theurl += str(lats[routing.IndexToNode(index)]) + urlspace + str(lons[routing.IndexToNode(index)])
      print "Route:\n\n" + route
      print theurl + trailingurl



    else:
      print 'No solution found.'
  else:
    print 'Specify an instance greater than 0.'
コード例 #2
0
ファイル: solver.py プロジェクト: OWLxx/DiscreteOptimization
def main(data, num_vehicles,vehicle_capacity ):
  # Create the data.
  #data = create_data_array()
  locations = data[0]
  demands = data[1]
  num_locations = len(locations)
  depot = 0    # The depot is the start and end point of each route.


  # Create routing model.
  if num_locations > 0:
    routing = pywrapcp.RoutingModel(num_locations, num_vehicles, depot)
    search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()

    # Setting first solution heuristic: the
    # method for finding a first solution to the problem.
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

    # The 'PATH_CHEAPEST_ARC' method does the following:
    # Starting from a route "start" node, connect it to the node which produces the
    # cheapest route segment, then extend the route by iterating on the last
    # node added to the route.

    # Put a callback to the distance function here. The callback takes two
    # arguments (the from and to node indices) and returns the distance between
    # these nodes.

    dist_between_locations = CreateDistanceCallback(locations)
    dist_callback = dist_between_locations.Distance
    routing.SetArcCostEvaluatorOfAllVehicles(dist_callback)

    # Put a callback to the demands.
    demands_at_locations = CreateDemandCallback(demands)
    demands_callback = demands_at_locations.Demand

    # Add a dimension for demand.
    slack_max = 0
    fix_start_cumul_to_zero = True
    demand = "Demand"
    routing.AddDimension(demands_callback, slack_max, vehicle_capacity,
                         fix_start_cumul_to_zero, demand)

    # Solve, displays a solution if any.
    assignment = routing.SolveWithParameters(search_parameters)
    if assignment:
          # Display solution.
          # Solution cost.
          print( "Total distance of all routes: " + str(assignment.ObjectiveValue()) + "\n")
          total_tour = []
          for vehicle_nbr in range(num_vehicles):
                index = routing.Start(vehicle_nbr)
                index_next = assignment.Value(routing.NextVar(index))
                route = ''
                route_dist = 0
                route_demand = 0
                while not routing.IsEnd(index_next):
                    node_index = routing.IndexToNode(index)
                    node_index_next = routing.IndexToNode(index_next)
                    route += str(node_index) + " -> "
                    # Add the distance to the next node.
                    route_dist += dist_callback(node_index, node_index_next)
                    # Add demand.
                    route_demand += demands[node_index_next]
                    index = index_next
                    index_next = assignment.Value(routing.NextVar(index))
                node_index = routing.IndexToNode(index)
                node_index_next = routing.IndexToNode(index_next)
                route += str(node_index) + " -> " + str(node_index_next)


                route_dist += dist_callback(node_index, node_index_next)
                temp = route.split('->')
                temp = [int(i) for i in temp if i != 0]
                total_tour.append(temp)
                print ("Route for vehicle " + str(vehicle_nbr) + ":\n\n" + route + "\n")
                print ("Distance of route " + str(vehicle_nbr) + ": " + str(route_dist))
                print ("Demand met by vehicle " + str(vehicle_nbr) + ": " + str(route_demand) + "\n")
          return total_tour
    else:
        print ('No solution found.')
  else:
    print ('Specify an instance greater than 0.')
コード例 #3
0
def main():
    """Entry point of the program."""
    # Instantiate the data problem.
    # [START data]
    data = create_data_model()
    # [END data]

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

    # Create Routing Model.
    # [START routing_model]
    routing = pywrapcp.RoutingModel(manager)

    # [END routing_model]

    # Define cost of each arc.
    # [START arc_cost]
    def distance_callback(from_index, to_index):
        """Returns the manhattan 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)
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
    # [END arc_cost]

    # Add Distance constraint.
    # [START distance_constraint]
    dimension_name = 'Distance'
    routing.AddDimension(
        transit_callback_index,
        0,  # no slack
        3000,  # vehicle maximum travel distance
        True,  # start cumul to zero
        dimension_name)
    distance_dimension = routing.GetDimensionOrDie(dimension_name)
    distance_dimension.SetGlobalSpanCostCoefficient(100)
    # [END distance_constraint]

    # Define Transportation Requests.
    # [START pickup_delivery_constraint]
    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))
    routing.SetPickupAndDeliveryPolicyOfAllVehicles(
        pywrapcp.RoutingModel.PICKUP_AND_DELIVERY_LIFO)
    # [END pickup_delivery_constraint]

    # Setting first solution heuristic.
    # [START parameters]
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION)
    # [END parameters]

    # Solve the problem.
    # [START solve]
    assignment = routing.SolveWithParameters(search_parameters)
    # [END solve]

    # Print solution on console.
    # [START print_solution]
    if assignment:
        print_solution(data, manager, routing, assignment)
def run_vrptur(pois, measurement, num_days):

    depot = 0  # The depot is the start and end point of each route.
    num_pois = len(pois)

    tour = Tour(num_days)

    # Create routing model.
    if num_pois > 0:
        routing = pywrapcp.RoutingModel(num_pois, num_days, depot)
        search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()

        # Setting first solution heuristic: the
        # method for finding a first solution to the problem.
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

        # search_parameters.first_solution_strategy = (
        #     routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)

        # The 'PATH_CHEAPEST_ARC' method does the following:
        # Starting from a route "start" node, connect it to the node which produces the
        # cheapest route segment, then extend the route by iterating on the last
        # node added to the route.

        # Put a callback to the measurement function here. The callback takes two
        # arguments (the from and to node indices) and returns the duration between
        # these nodes.

        measurement_between_pois = CreateMeasurementCallback(pois, measurement)
        duration_callback = measurement_between_pois.duration
        distance_callback = measurement_between_pois.distance
        routing.SetArcCostEvaluatorOfAllVehicles(duration_callback)

        # Add a dimension for duration.
        max_day_duration = 480  # in minutes
        fix_start_cumul_to_zero = True
        duration = "Duration"
        routing.AddDimension(duration_callback, max_day_duration,
                             max_day_duration, fix_start_cumul_to_zero,
                             duration)

        # Solve, displays a solution if any.
        assignment = routing.SolveWithParameters(search_parameters)
        if assignment:

            # Solution cost.
            tour.duration = assignment.ObjectiveValue()

            for day_nbr in range(num_days):

                trip = Trip(day_nbr)

                # Start: nodes 0 and 1
                index = routing.Start(day_nbr)
                index_next = assignment.Value(routing.NextVar(index))

                while not routing.IsEnd(index_next):

                    # Get indexes of nodes
                    node_index = routing.IndexToNode(index)
                    node_index_next = routing.IndexToNode(index_next)

                    # Increment trip
                    trip.add_poi(pois[node_index])
                    trip.add_duration(
                        duration_callback(node_index, node_index_next))
                    trip.add_distance(
                        distance_callback(node_index, node_index_next))

                    # Get next nodes
                    index = index_next
                    index_next = assignment.Value(routing.NextVar(index))

                # Get indexes of last nodes: (n-2) and (n-1)
                node_index = routing.IndexToNode(index)
                node_index_next = routing.IndexToNode(index_next)

                # Increment trip with last indexes
                trip.add_poi(pois[node_index])
                trip.add_poi(pois[node_index_next])
                trip.add_duration(
                    duration_callback(node_index, node_index_next))
                trip.add_distance(
                    distance_callback(node_index, node_index_next))

                tour.trips.append(trip)

        else:
            print('No solution found for num_days = ' + str(num_days))
    else:
        print('Specify an instance (PoIs) greater than 0.')

    return tour
コード例 #5
0
ファイル: vrp_initial_routes.py プロジェクト: falble/or-tools
def main():
    """Solve the CVRP problem."""
    # Instantiate the data problem.
    # [START data]
    data = create_data_model()
    # [END data]

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

    # Create Routing Model.
    # [START routing_model]
    routing = pywrapcp.RoutingModel(manager)

    # [END routing_model]

    # Create and register a transit callback.
    # [START 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)
    # [END transit_callback]

    # Define cost of each arc.
    # [START arc_cost]
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
    # [END arc_cost]

    # Add Distance constraint.
    # [START distance_constraint]
    dimension_name = 'Distance'
    routing.AddDimension(
        transit_callback_index,
        0,  # no slack
        3000,  # vehicle maximum travel distance
        True,  # start cumul to zero
        dimension_name)
    distance_dimension = routing.GetDimensionOrDie(dimension_name)
    distance_dimension.SetGlobalSpanCostCoefficient(100)
    # [END distance_constraint]

    # [START print_initial_solution]
    initial_solution = routing.ReadAssignmentFromRoutes(
        data['initial_routes'], True)
    print('Initial solution:')
    print_solution(data, manager, routing, initial_solution)
    # [END print_initial_solution]

    # Set default search parameters.
    # [START parameters]
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    # [END parameters]

    # Solve the problem.
    # [START solve]
    solution = routing.SolveFromAssignmentWithParameters(
        initial_solution, search_parameters)
    # [END solve]

    # Print solution on console.
    # [START print_solution]
    if solution:
        print('Solution after search:')
        print_solution(data, manager, routing, solution)
コード例 #6
0
def solve_vrp(vehicle_count,
              vehicle_capacity,
              customers: Customer,
              big_number=100000,
              strategy=FSS.FIRST_UNBOUND_MIN_VALUE,
              ls_option=LSM.GUIDED_LOCAL_SEARCH):
    """Solve the CVRP problem."""
    # Instantiate the data problem.
    data = create_data_model(vehicle_count, vehicle_capacity, customers,
                             big_number)

    # 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)

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

    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')

    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    if 10 <= vehicle_count < 16:
        search_parameters.time_limit.seconds = 600
    else:
        search_parameters.time_limit.seconds = 90
    search_parameters.first_solution_strategy = strategy
    search_parameters.local_search_metaheuristic = ls_option

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

    # Print solution on console.
    objective = -1
    if solution:
        tours, objective = print_solution(data,
                                          manager,
                                          routing,
                                          solution,
                                          customers,
                                          big_number,
                                          do_print=False)
    else:
        tours = trivial_solution(vehicle_count, vehicle_capacity, customers)
    return tours, objective
コード例 #7
0
def solve_vrp(vrp_points, problem_id, depot_id, ffs, lsm, n_veh):
    """Solve the CVRP problem."""
    # Instantiate the data problem.
    data = create_data_model(vrp_points, depot_id, n_veh)

    # 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)

    # Add Distance constraint.
    dimension_name = 'Distance'
    routing.AddDimension(
        transit_callback_index,
        0,  # no slack
        3000000,  # vehicle maximum travel distance
        True,  # start cumul to zero
        dimension_name)
    distance_dimension = routing.GetDimensionOrDie(dimension_name)
    distance_dimension.SetGlobalSpanCostCoefficient(100)

    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()

    firstSolutions = {
        'PATH_CHEAPEST_ARC':
        (routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC),
        'AUTOMATIC': (routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC),
        'PATH_MOST_CONSTRAINED_ARC':
        (routing_enums_pb2.FirstSolutionStrategy.PATH_MOST_CONSTRAINED_ARC),
        'EVALUATOR_STRATEGY':
        (routing_enums_pb2.FirstSolutionStrategy.EVALUATOR_STRATEGY),
        'SAVINGS': (routing_enums_pb2.FirstSolutionStrategy.SAVINGS),
        'SWEEP': (routing_enums_pb2.FirstSolutionStrategy.SWEEP),
        'CHRISTOFIDES': (routing_enums_pb2.FirstSolutionStrategy.CHRISTOFIDES),
        'ALL_UNPERFORMED':
        (routing_enums_pb2.FirstSolutionStrategy.ALL_UNPERFORMED),
        'BEST_INSERTION':
        (routing_enums_pb2.FirstSolutionStrategy.BEST_INSERTION),
        'PARALLEL_CHEAPEST_INSERTION':
        (routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION),
        'LOCAL_CHEAPEST_INSERTION':
        (routing_enums_pb2.FirstSolutionStrategy.LOCAL_CHEAPEST_INSERTION),
        'GLOBAL_CHEAPEST_ARC':
        (routing_enums_pb2.FirstSolutionStrategy.GLOBAL_CHEAPEST_ARC),
        'LOCAL_CHEAPEST_ARC':
        (routing_enums_pb2.FirstSolutionStrategy.LOCAL_CHEAPEST_ARC),
        'FIRST_UNBOUND_MIN_VALUE':
        (routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE)
    }

    search_parameters.first_solution_strategy = firstSolutions[ffs]

    localSearchMetas = {
        'AUTOMATIC': (routing_enums_pb2.LocalSearchMetaheuristic.AUTOMATIC),
        'GREEDY_DESCENT':
        (routing_enums_pb2.LocalSearchMetaheuristic.GREEDY_DESCENT),
        'GUIDED_LOCAL_SEARCH':
        (routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH),
        'SIMULATED_ANNEALING':
        (routing_enums_pb2.LocalSearchMetaheuristic.SIMULATED_ANNEALING),
        'TABU_SEARCH': (routing_enums_pb2.LocalSearchMetaheuristic.TABU_SEARCH)
    }

    search_parameters.local_search_metaheuristic = localSearchMetas[lsm]

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

    # Print solution on console.
    if solution:
        total_string = print_solution(data, manager, routing, solution)
        rez = solution_dict(data, manager, routing, solution)
        # save_pickle_data('routing_rez.pkl', rez)
        exists = RoutingPlan.objects.filter(
            problem=VrpProblem.objects.get(id=problem_id),
            vehicle_num=n_veh).exists()

        if not exists:
            for r in rez:

                rp = ';'.join([str(i) for i in r['route']])

                routing_plan = RoutingPlan(
                    problem=VrpProblem.objects.get(id=problem_id),
                    routing_plan=rp,
                    vehicle_num=n_veh,
                    vehicle_id=r['veh_id'],
                    total_distance=r['distance'])
                routing_plan.save()

        return total_string, rez

    return None, None
コード例 #8
0
def main():

    # Create the data.
    data = create_data_array()
    locations = data[0]
    demands = data[1]
    start_times = data[2]
    num_locations = len(locations)
    depot = 0
    num_vehicles = 5
    search_time_limit = 400000

    # Create routing model.
    if num_locations > 0:

        # The number of nodes of the VRP is num_locations.
        # Nodes are indexed from 0 to num_locations - 1. By default the start of
        # a route is node 0.
        routing = pywrapcp.RoutingModel(num_locations, num_vehicles)
        search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()

        # Setting first solution heuristic: the
        # method for finding a first solution to the problem.
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

        # The 'PATH_CHEAPEST_ARC' method does the following:
        # Starting from a route "start" node, connect it to the node which produces the
        # cheapest route segment, then extend the route by iterating on the last
        # node added to the route.

        # Set the depot.
        routing.SetDepot(depot)

        # Put callbacks to the distance function and travel time functions here.

        dist_between_locations = CreateDistanceCallback(locations)
        dist_callback = dist_between_locations.Distance

        routing.SetArcCostEvaluatorOfAllVehicles(dist_callback)
        demands_at_locations = CreateDemandCallback(demands)
        demands_callback = demands_at_locations.Demand

        # Adding capacity dimension constraints.
        VehicleCapacity = 100
        NullCapacitySlack = 0
        fix_start_cumul_to_zero = True
        capacity = "Capacity"

        routing.AddDimension(demands_callback, NullCapacitySlack,
                             VehicleCapacity, fix_start_cumul_to_zero,
                             capacity)

        # Adding time dimension constraints.
        time_per_demand_unit = 300
        horizon = 24 * 3600
        time = "Time"
        tw_duration = 5 * 3600
        speed = 10

        service_times = CreateServiceTimeCallback(demands,
                                                  time_per_demand_unit)
        service_time_callback = service_times.ServiceTime

        total_times = CreateTotalTimeCallback(service_time_callback,
                                              dist_callback, speed)
        total_time_callback = total_times.TotalTime

        # Add a dimension for time-window constraints and limits on the start times and end times.

        routing.AddDimension(
            total_time_callback,  # total time function callback
            horizon,
            horizon,
            fix_start_cumul_to_zero,
            time)

        # Add limit on size of the time windows.
        time_dimension = routing.GetDimensionOrDie(time)

        for order in range(1, num_locations):
            start = start_times[order]
            time_dimension.CumulVar(order).SetRange(start, start + tw_duration)

        # Solve displays a solution if any.
        assignment = routing.SolveWithParameters(search_parameters)
        if assignment:
            data = create_data_array()
            locations = data[0]
            demands = data[1]
            start_times = data[2]
            size = len(locations)
            # Solution cost.
            print "Total distance of all routes: " + str(
                assignment.ObjectiveValue()) + "\n"
            # Inspect solution.
            capacity_dimension = routing.GetDimensionOrDie(capacity)
            time_dimension = routing.GetDimensionOrDie(time)

            for vehicle_nbr in range(num_vehicles):
                index = routing.Start(vehicle_nbr)
                plan_output = 'Route {0}:'.format(vehicle_nbr)

                while not routing.IsEnd(index):
                    node_index = routing.IndexToNode(index)
                    load_var = capacity_dimension.CumulVar(index)
                    time_var = time_dimension.CumulVar(index)
                    plan_output += \
                              " {node_index} Load({load}) Time({tmin}, {tmax}) -> ".format(
                                  node_index=node_index,
                                  load=assignment.Value(load_var),
                                  tmin=str(assignment.Min(time_var)),
                                  tmax=str(assignment.Max(time_var)))
                    index = assignment.Value(routing.NextVar(index))

                node_index = routing.IndexToNode(index)
                load_var = capacity_dimension.CumulVar(index)
                time_var = time_dimension.CumulVar(index)
                plan_output += \
                          " {node_index} Load({load}) Time({tmin}, {tmax})".format(
                              node_index=node_index,
                              load=assignment.Value(load_var),
                              tmin=str(assignment.Min(time_var)),
                              tmax=str(assignment.Max(time_var)))
                print plan_output
                print "\n"
        else:
            print 'No solution found.'
    else:
        print 'Specify an instance greater than 0.'
コード例 #9
0
def solve_it(input_data):
    # Create routing model
    # if args.tsp_size > 0:
    # TSP of size args.tsp_size
    # Second argument = 1 to build a single tour (it's a TSP).
    # Nodes are indexed from 0 to parser_tsp_size - 1, by default the start of
    # the route is node 0.
    matrix = RandomMatrix(input_data)
    tsp_size = len(matrix.points)
    routing = pywrapcp.RoutingModel(tsp_size, 1, 0)

    search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()
    # Setting first solution heuristic (cheapest addition).
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

    # Setting the cost function.
    # Put a callback to the distance accessor here. The callback takes two
    # arguments (the from and to node inidices) and returns the distance between
    # these nodes.

    matrix_callback = matrix.Distance
    tsp_use_random_matrix = True
    if tsp_use_random_matrix:
        routing.SetArcCostEvaluatorOfAllVehicles(matrix_callback)
    else:
        routing.SetArcCostEvaluatorOfAllVehicles(Distance)
    # Forbid node connections (randomly).
    rand = random.Random()
    rand.seed(1)  # rand.seed(args.tsp_random_seed)
    forbidden_connections = 0
    while forbidden_connections < 0:  # while forbidden_connections < args.tsp_random_forbidden_connections:
        from_node = rand.randrange(tsp_size - 1)
        to_node = rand.randrange(tsp_size - 1) + 1
        if routing.NextVar(from_node).Contains(to_node):
            print('Forbidding connection ' + str(from_node) + ' -> ' +
                  str(to_node))
            routing.NextVar(from_node).RemoveValue(to_node)
            forbidden_connections += 1

    # Solve, returns a solution if any.
#    assignment = routing.SolveWithParameters(search_parameters)
    assignment = routing.Solve()
    if assignment:
        # Solution cost.
        # print(assignment.ObjectiveValue())
        # Inspect solution.
        # Only one route here; otherwise iterate from 0 to routing.vehicles() - 1
        route_number = 0
        node = routing.Start(route_number)
        route = ''
        while not routing.IsEnd(node):
            route += ' ' + str(node)
            node = assignment.Value(routing.NextVar(node))
        # route += '0'
        nodeList = route.split()[1:]
        # totalDistance = assignment.ObjectiveValue() + matrix.points[int(nodeList[0])].distanceTo(matrix.points[int(nodeList[-1])])
        # print(totalDistance)
        output_data = '%.2f' % assignment.ObjectiveValue() + ' ' + str(
            0) + '\n'
        output_data += route
        # output_data += ' '.join(map(str, solution))
        csvOutput(matrix, route.split(' '))
        return output_data

    else:
        print('No solution found.')
コード例 #10
0
def main():
    vehicleList = None
    waypointsList = None
    depotList = None
    flightTime = 15
    maxSpeed = 5
    for arg in sys.argv[1:]:
        #print('{}'.format(arg))
        tokens = arg.split(":")
        if tokens[0] == "Vehicles":
            vehicleList = (tokens[1].split(","))
        elif tokens[0] == "Waypoints":
            waypointsList = parseWaypoints(tokens[1])
        elif tokens[0] == "Depot":
            depotList = parseDepots(tokens[1])
        elif tokens[0] == "Flight Time":
            flightTime = int(tokens[1])
        elif tokens[0] == "Speed":
            maxSpeed = int(tokens[1])

    print("Vehicles: {}".format(vehicleList))
    print("Waypoints: {}".format(waypointsList))
    print("Depot: {}".format(depotList))

    #Waypoints have no demaonds
    demands = None

    #Add the depot(s) to the begining of the waypoints list
    depotIndices = []
    for idx in range(len(depotList)):
        waypointsList.insert(idx, depotList[idx])
        depotIndices.append(idx)

    # Create a set of customer, (and depot) stops.
    customers = Customers(
        num_stops=len(waypointsList),
        lats=[loc[0] for loc in waypointsList],
        lons=[loc[1] for loc in waypointsList],
        dems=demands,
        maxFlightTime=flightTime,
        #min_demand=1,
        #max_demand=15,
        #box_size=40,
        min_tw=15,
        max_tw=15)

    # Create callback fns for distances, demands, service and transit-times.
    dist_fn = customers.return_dist_callback()
    dem_fn = customers.return_dem_callback()
    #serv_time_fn = customers.make_service_time_call_callback()

    #Turn the
    ## Create a list of inhomgenious vehicle capacities as integer units.
    #capacity = [50, 175, 200, 250]
    capacity = []
    for veh in vehicleList:
        capacity.append(100)

    transit_time_fn = customers.make_transit_time_callback(speed_kmph=maxSpeed)

    def tot_time_fn(a, b):
        """
        The time function we want is both transit time and service time.
        """
        #return serv_time_fn(a, b) + transit_time_fn(a, b)
        return transit_time_fn(a, b)

    # Create a list of inhomogenious fixed vehicle costs.
    cost = [int(100) for c in capacity]

    # Create a set of vehicles, the number set by the length of capacity.
    vehicles = Vehicles(capacity=capacity, cost=cost)

    ## check to see that the problem is feasible, if we don't have enough
    ## vehicles to cover the demand, there is no point in going further.
    #assert (customers.get_total_demand() < vehicles.get_total_capacity())

    # Set the starting nodes, and create a callback fn for the starting node.
    start_fn = vehicles.return_starting_callback(customers,
                                                 sameStartFinish=True)

    # Set model parameters
    model_parameters = pywrapcp.RoutingModel.DefaultModelParameters()

    # The solver parameters can be accessed from the model parameters. For example :
    #   model_parameters.solver_parameters.CopyFrom(
    #       pywrapcp.Solver.DefaultSolverParameters())
    #    model_parameters.solver_parameters.trace_propagation = True

    # Make the routing model instance.
    # if we have multiple depots, then each vehicle has a differnt start/end location, pass those in
    # instead of start/ends in the vehicle class
    routing = pywrapcp.RoutingModel(
        customers.number,  #in tnumber
        vehicles.number,  #int number
        depotIndices,  #list of start depot
        depotIndices,  #list of end depots
        model_parameters)

    #routing = pywrapcp.RoutingModel(
    #     customers.number,  # int number
    #     vehicles.number,  # int number
    #     vehicles.starts,  # List of int start depot
    #     vehicles.ends,  # List of int end depot
    #     model_parameters)

    parameters = routing.DefaultSearchParameters()
    # Setting first solution heuristic (cheapest addition).
    parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
    # Disabling Large Neighborhood Search, (this is the default behaviour)
    parameters.local_search_operators.use_path_lns = False
    parameters.local_search_operators.use_inactive_lns = False
    # Routing: forbids use of TSPOpt neighborhood,
    parameters.local_search_operators.use_tsp_opt = False

    parameters.time_limit_ms = 30 * 1000  # 30 seconds
    parameters.use_light_propagation = False
    # parameters.log_search = True

    # Set the cost function (distance callback) for each arc, homogenious for
    # all vehicles.
    routing.SetArcCostEvaluatorOfAllVehicles(dist_fn)

    # Set vehicle costs for each vehicle, not homogenious.
    for veh in vehicles.vehicles:
        routing.SetFixedCostOfVehicle(veh.cost, int(veh.index))

    # Add a dimension for vehicle capacities
    null_capacity_slack = 0
    routing.AddDimensionWithVehicleCapacity(
        dem_fn,  # demand callback
        null_capacity_slack,
        capacity,  # capacity array
        True,
        'Capacity')
    # Add a dimension for time and a limit on the total time_horizon
    routing.AddDimension(
        tot_time_fn,  # total time function callback
        customers.time_horizon,
        customers.time_horizon,
        True,
        'Time')

    time_dimension = routing.GetDimensionOrDie('Time')
    for cust in customers.customers:
        if cust.tw_open is not None:
            time_dimension.CumulVar(routing.NodeToIndex(cust.index)).SetRange(
                cust.tw_open.seconds, cust.tw_close.seconds)
    """
     To allow the dropping of orders, we add disjunctions to all the customer
    nodes. Each disjunction is a list of 1 index, which allows that customer to
    be active or not, with a penalty if not. The penalty should be larger
    than the cost of servicing that customer, or it will always be dropped!
    """
    # To add disjunctions just to the customers, make a list of non-depots.
    non_depot = set(range(customers.number))
    non_depot.difference_update(depotIndices)
    non_depot.difference_update(depotIndices)
    penalty = 400000  # The cost for dropping a node from the plan.
    nodes = [routing.AddDisjunction([int(c)], penalty) for c in non_depot]

    # This is how you would implement partial routes if you already knew part
    # of a feasible solution for example:
    # partial = np.random.choice(list(non_depot), size=(4,5), replace=False)

    # routing.CloseModel()
    # partial_list = [partial[0,:].tolist(),
    #                 partial[1,:].tolist(),
    #                 partial[2,:].tolist(),
    #                 partial[3,:].tolist(),
    #                 [],[],[],[]]
    # print(routing.ApplyLocksToAllVehicles(partial_list, False))

    # Solve the problem !
    assignment = routing.SolveWithParameters(parameters)

    # The rest is all optional for saving, printing or plotting the solution.
    if assignment:
        #print('The Objective Value is {0}'.format(assignment.ObjectiveValue()))

        buildQGCReturn(routing, assignment, waypointsList, vehicleList,
                       len(depotList))
        #plan_output, dropped = vehicle_output_string(routing, assignment)
        #print(plan_output)
        #print('dropped nodes: ' + ', '.join(dropped))

        # you could print debug information like this:
        # print(routing.DebugOutputAssignment(assignment, 'Capacity'))

        #vehicle_routes = {}
        #for veh in range(vehicles.number):
        #  vehicle_routes[veh] = build_vehicle_route(routing, assignment, customers,veh)

    else:
        print('No assignment')
コード例 #11
0
def cvrp(data, set, vehicles, strategy):
    """Solve the CVRP problem."""
    # Instantiate the data problem.
    data, name = modelData.create_data_model(data, set, vehicles)

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

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

    # initial plot
    plot.create_initial_plot(data['points'], name)

    # 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)

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

    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')

    # Setting solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()

    if strategy == 'first-solution':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC)
    elif strategy == 'local-search':
        search_parameters.local_search_metaheuristic = (
            routing_enums_pb2.LocalSearchMetaheuristic.AUTOMATIC)
        search_parameters.time_limit.seconds = 20
    else:
        search_parameters.local_search_metaheuristic = (
            routing_enums_pb2.LocalSearchMetaheuristic.AUTOMATIC)
        search_parameters.time_limit.seconds = 25
        # search_parameters.local_search_metaheuristic = (
        #     routing_enums_pb2.LocalSearchMetaheuristic.TABU_SEARCH)
        # search_parameters.time_limit.seconds = 20

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

    # Print solution.
    if assignment:
        vehicle_distance, vehicle_load, text = print.print_solution(
            data, manager, routing, assignment)
    routes = getRoutes.get_routes(manager, routing, assignment,
                                  data['num_vehicles'])
    # Display the routes.
    route_arr = print.print_routes(routes)
    plot.create_plot(data['points'], routes, vehicle_distance, name)
    return vehicle_distance, vehicle_load, text, name, route_arr
コード例 #12
0
def main(data, truck_options):
    # Create the data.

    #   data = create_data_array()

    locations = data[0]
    demands = data[1]
    start_times = data[2]
    end_times = data[3]
    volume = data[4]
    address = data[5]
    nodes = data[6]
    num_locations = len(locations)
    depot = 0

    try:

        num_vehicles = truck_options['number_of_trucks']
    except:
        num_vehicles = 100
    search_time_limit = 400000

    # Create routing model.
    if num_locations > 0:

        # The number of nodes of the VRP is num_locations.
        # Nodes are indexed from 0 to num_locations - 1. By default the start of
        # a route is node 0.
        routing = pywrapcp.RoutingModel(num_locations, num_vehicles, depot)
        search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()

        # Callbacks to the distance function and travel time functions here.
        if num_vehicles == 1:
            dist_between_locations = CreateDistanceCallbackNEW(locations)
        else:
            dist_between_locations = CreateDistanceCallback(locations)
#     dist_between_locations.matrix = matrix
        dist_callback = dist_between_locations.Distance

        routing.SetArcCostEvaluatorOfAllVehicles(dist_callback)
        demands_at_locations = CreateDemandCallback(demands)
        demands_callback = demands_at_locations.Demand

        maximum_dist = int(truck_options['MaxDistancePerVehicle'])
        NullDistanceStack = 0
        fix_start_cumul_to_zero = True
        distance_check = "Distances"
        routing.AddDimension(dist_callback, NullDistanceStack, maximum_dist,
                             fix_start_cumul_to_zero, distance_check)

        # Adding capacity dimension constraints.

        VehicleCapacity = 0
        VolumeCapacity = 0

        for i in truck_options['SelectedDeliveryVehicles']:
            if i['Code'] == 'V400':
                VehicleCapacity = int(i['WeightAllowed'])

                VolumeCapacity = int(i['VmWtAllowed'])
                selected_vehicle = i
        if VehicleCapacity == 0:
            for i in truck_options['SelectedDeliveryVehicles']:
                if i['Code'] == 'V500':
                    VehicleCapacity = int(i['WeightAllowed'])

                    VolumeCapacity = int(i['VmWtAllowed'])
                    selected_vehicle = i
        if VehicleCapacity == 0:
            for i in truck_options['SelectedDeliveryVehicles']:
                if i['Code'] == 'V200':
                    VehicleCapacity = int(i['WeightAllowed'])

                    VolumeCapacity = int(i['VmWtAllowed'])
                    selected_vehicle = i

        NullCapacitySlack = 0
        fix_start_cumul_to_zero = True
        capacity = "Capacity"
        routing.AddDimension(demands_callback, NullCapacitySlack,
                             VehicleCapacity, fix_start_cumul_to_zero,
                             capacity)

        ## Adding Volume constraint
        volume_at_locations = CreateVolumeCallback(volume)
        volume_callback = volume_at_locations.Volume

        NullVolumeSlack = 0
        fix_start_cumul_to_zero = True
        volumes = "Volume"

        routing.AddDimension(volume_callback, NullVolumeSlack, VolumeCapacity,
                             fix_start_cumul_to_zero, volumes)

        # Add time dimension.

        time_per_demand_unit = int(truck_options['MHaltTimeAtDropPoint']) * 60
        horizon = 24 * 3600
        time = "Time"
        speed = int(truck_options['AverageSpeedOfVehicle'])

        service_times = CreateServiceTimeCallback(demands,
                                                  time_per_demand_unit)
        service_time_callback = service_times.ServiceTime

        travel_times = CreateTravelTimeCallback(dist_callback, speed)
        travel_time_callback = travel_times.TravelTime

        total_times = CreateTotalTimeCallback(service_time_callback,
                                              travel_time_callback)
        total_time_callback = total_times.TotalTime
        duration = end_times[0] - start_times[0]
        routing.AddDimension(
            total_time_callback,  # total time function callback
            horizon,
            duration,
            False,
            time)
        # Add time window constraints.
        time_dimension = routing.GetDimensionOrDie(time)

        for location in range(1, num_locations):

            start = start_times[location] - start_times[0]
            end = start + end_times[location] - start_times[location]

            location_idx = routing.NodeToIndex(location)
            time_dimension.CumulVar(location_idx).SetRange(start, end)
            routing.AddToAssignment(time_dimension.SlackVar(location_idx))

        for vehicle_id in xrange(num_vehicles):
            index = routing.Start(vehicle_id)
            time_dimension.CumulVar(index).SetRange(0, duration)
            routing.AddToAssignment(time_dimension.SlackVar(index))

        # Solve displays a solution if any.

        #     search_parameters.time_limit_ms = 30000


#     search_parameters.solution_limit = 100
#

        assignment = routing.SolveWithParameters(search_parameters)
        if assignment:

            size = len(locations)
            # Solution cost.

            #       print "Total distance of all routes: " + str(assignment.ObjectiveValue()) + "\n"
            # Inspect solution.
            capacity_dimension = routing.GetDimensionOrDie(capacity)
            time_dimension = routing.GetDimensionOrDie(time)
            volume_dimension = routing.GetDimensionOrDie(volumes)
            distance_dimension = routing.GetDimensionOrDie(distance_check)
            plans = []

            distances = []
            cum_distance = []
            address1 = []
            truck = []

            volume1 = []
            cum_volume = []
            time_range = []
            weight = []
            cum_weight = []
            for vehicle_nbr in range(num_vehicles):
                index = routing.Start(vehicle_nbr)
                plan_output = 'Route {0}:'.format(vehicle_nbr)
                plan1 = []
                dist = 0
                number_del = 0

                while not routing.IsEnd(index):

                    node_index = routing.IndexToNode(index)

                    number_del += 1
                    if node_index == 0:
                        node_prev = 0
                        dist += 0
                        dist1 = 0
                    else:

                        dist1 = dist_between_locations.matrix[node_index][
                            node_prev]
                        dist += dist1
                        node_prev = node_index
                    distances.append(dist1)
                    cum_distance.append(dist)
                    address1.append(address[node_index])
                    truck.append("Truck" + str(vehicle_nbr + 1))
                    weight.append(demands[node_index])

                    volume1.append(volume[node_index])
                    dist_var = distance_dimension.CumulVar(index)
                    load_var = capacity_dimension.CumulVar(index)
                    vol_var = volume_dimension.CumulVar(index)
                    time_var = time_dimension.CumulVar(index)
                    cum_weight.append(assignment.Value(load_var))
                    cum_volume.append(assignment.Value(vol_var))
                    time_range.append(
                        str(assignment.Min(time_var)) + " - " +
                        str(assignment.Max(time_var)))
                    plan1.append(
                        (nodes[node_index], dist1, assignment.Value(load_var),
                         assignment.Value(vol_var),
                         str(assignment.Min(time_var) + start_times[0]),
                         str(assignment.Max(time_var) + start_times[0]),
                         locations[node_index], node_index))
                    plan_output += \
                              " {node_index} Load({load}) Vol({vol}) Dist({dist}) Time({tmin}, {tmax}) -> ".format(
                                  node_index=node_index,
                                  load=assignment.Value(load_var),
                                  vol = assignment.Value(vol_var),
                                  dist = dist,
                                  tmin=str(assignment.Min(time_var)),
                                  tmax=str(assignment.Max(time_var)))
                    index = assignment.Value(routing.NextVar(index))

                node_index = routing.IndexToNode(index)

                dist1 = dist_between_locations.matrix[node_index][node_prev]
                dist += dist1
                node_prev = node_index
                distances.append(dist1)
                cum_distance.append(dist)
                address1.append(address[node_index])
                truck.append("Truck" + str(vehicle_nbr + 1))
                weight.append(demands[node_index])
                volume1.append(volume[node_index])
                dist_var = distance_dimension.CumulVar(index)
                load_var = capacity_dimension.CumulVar(index)
                vol_var = volume_dimension.CumulVar(index)
                time_var = time_dimension.CumulVar(index)
                cum_weight.append(assignment.Value(load_var))
                cum_volume.append(assignment.Value(vol_var))
                time_range.append(
                    str(assignment.Min(time_var)) + " - " +
                    str(assignment.Max(time_var)))

                plan1.append(
                    (nodes[node_index], dist1, assignment.Value(load_var),
                     assignment.Value(vol_var),
                     str(assignment.Min(time_var) + start_times[0]),
                     str(assignment.Max(time_var) + start_times[0]),
                     locations[node_index], node_index))

                plan_output += \
                          " {node_index} Load({load}) Vol({vol}) Dist({dist}) Time({tmin}, {tmax})".format(
                              node_index=node_index,
                              load=assignment.Value(load_var),
                              vol = assignment.Value(vol_var),
                              dist = dist,
                              tmin=str(assignment.Min(time_var)),
                              tmax=str(assignment.Max(time_var)))
                #         print plan_output
                #
                #         print "\n"
                #         print dist, number_del
                #         print "\n"
                if len(plan1) == 2 and plan1[1][0] == 0:
                    pass
                else:
                    plans.append(plan1)

        else:
            print 'No solution found.'
    else:
        print 'Specify an instance greater than 0.'

    return (plans, selected_vehicle)
コード例 #13
0
def main():

    # Cities
    #city_names = ['Ghatkesar', 'B N Reddy Nagar', 'Nagole', 'LB Nagar', 'DSNR', 'Champapet', 'SC', 'Boduppal', 'Meerpet', 'Tarnaka', 'Malakpet', 'Hastinapuram', 'Kothapet', 'Ramanthapur', 'Banjara Hills', 'Pocharam', 'Nadergul']
    #city_names=stores
    city_names = city_dist
    # Distance matrix

    dist_matrix = dms
    #  dist_matrix=[[    0, 32358, 19813, 21847, 24806, 36389, 25079, 14146, 36418,
    #        20957, 25149, 34520, 20128, 21223, 34173,  5716, 39778],
    #       [30517,     0,  9023,  5808, 10374,  7659, 19841, 14838,  5551,
    #        15719, 13032,  2350,  8345, 12765, 22147, 31482,  6316],
    #       [24709,  9058,     0,  4785,  7722, 10566, 13500,  8497, 10596,
    #         9378, 10380,  9565,  3067,  8105, 22594, 25675, 14904],
    #       [29751,  4973,  4611,     0,  7114,  5781, 16251, 11247,  5811,
    #        12129,  9772,  4780,  5818,  9505, 18887, 30716, 10819],
    #       [22064,  8844,  6218,  4512,     0,  4138, 15342, 10339,  7646,
    #        11220,  4911,  8651,  2627,  4278, 14026, 19489, 14690],
    #       [34340,  7974,  9958,  5051,  4361,     0, 13574, 14130,  4206,
    #        15011,  5735,  7781,  6418,  6752, 14948, 35305, 10818],
    #       [23772, 20281, 13274, 15308, 13379, 15039,     0, 12282, 19047,
    #         5848, 10349, 20088, 13590, 13425,  9614, 21197, 26127],
    #       [13681, 16143,  9136, 11170, 12457, 16951, 12240,     0, 16980,
    #         6653, 12800, 15950,  9452,  8873, 21334, 11106, 21989],
    #       [35606,  5651, 11224,  7383,  8561,  4016, 17394, 16962,     0,
    #        17843,  9555,  3280,  9920, 10951, 27579, 36571,  8067],
    #       [19293, 15802,  8794, 10829, 10280, 16610,  6022,  6682, 16639,
    #            0,  9797, 15608,  9110,  8945, 15116, 16718, 21647],
    #       [24165, 13171, 10544,  8838,  4353,  6013,  8863, 12440, 10020,
    #        10691,     0, 12978,  6953,  6230, 10237, 21590, 16633],
    #       [32495,  2449,  8983,  5692, 10258,  6500, 19725, 14721,  3238,
    #        15603, 12916,     0,  8229, 12649, 22031, 33460,  8295],
    #       [19437,  8019,  3591,  3686,  4655,  6171, 12715,  7712,  8356,
    #         8593,  7313,  7826,     0,  7320, 16428, 16862, 13865],
    #       [20308, 12793,  8079,  8460,  3975,  6859, 11377,  8582, 10583,
    #         7255,  6187, 12600,  6576,     0, 12658, 17732, 18639],
    #       [32769, 33276, 22271, 18998, 14513, 16173, 10628, 21280, 29141,
    #        14845, 11482, 31892, 17113, 12939,     0, 30194, 33357],
    #       [ 5483, 32298, 17089, 19123, 22082, 24904, 22355, 11423, 24933,
    #        18233, 22426, 34461, 17405, 18499, 31449,     0, 39718],
    #       [38908,  6109, 14944, 11729, 16295, 11159, 25762, 20758,  8075,
    #        21640, 18953,  8271, 14266, 18686, 32675, 39873,     0]]
    #

    tsp_size = len(city_names)
    num_routes = 1
    depot = 0

    # Create routing model
    if tsp_size > 0:
        routing = pywrapcp.RoutingModel(tsp_size, num_routes, depot)
        search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()
        # Create the distance callback.
        dist_callback = create_distance_callback(dist_matrix)
        routing.SetArcCostEvaluatorOfAllVehicles(dist_callback)
        # Solve the problem.
        assignment = routing.SolveWithParameters(search_parameters)
        if assignment:
            # Solution distance.
            print("Total distance: " + str(assignment.ObjectiveValue()) +
                  " miles\n")
            # Display the solution.
            # Only one route here; otherwise iterate from 0 to routing.vehicles() - 1
            route_number = 0
            index = routing.Start(
                route_number)  # Index of the variable for the starting node.
            route = ''
            while not routing.IsEnd(index):
                # Convert variable indices to node indices in the displayed route.
                shortest_path.append(city_names[routing.IndexToNode(
                    index)])  ###list for solution

                route += str(city_names[routing.IndexToNode(index)]) + ' --> '
                index = assignment.Value(routing.NextVar(index))
            route += str(city_names[routing.IndexToNode(index)])
            print("Route:\n\n" + route)
        else:
            print('No solution found.')
    else:
        print('Specify an instance greater than 0.')
コード例 #14
0
def main():
    """Entry point of the program"""
    # Instantiate the data problem.
    data = create_data_model()

    # Create Routing Model
    routing = pywrapcp.RoutingModel(data["num_locations"],
                                    data["num_vehicles"], data["depot"])
    # Define weight of each edge
    distance_callback = create_distance_callback(data)
    routing.SetArcCostEvaluatorOfAllVehicles(distance_callback)
    # Add Capacity constraint
    demand_callback = create_demand_callback(data)
    add_capacity_constraints(routing, data, demand_callback)
    # Add Time Window constraint
    time_callback = distance_callback  #create_time_callback(data)
    add_time_window_constraints(routing, data, time_callback)

    # WEN TODO: What is it can deliver to SC_1 or SC_2 or SC_3
    #routing.AddPickupAndDelivery(LocationEnum.PICKUP_0.value, LocationEnum.SC_1_TAKEIN_0.value)

    v0_default_node_idx = routing.NodeToIndex(8)
    v0_end_node_idx = routing.NodeToIndex(11)
    routing.solver().Add(
        routing.VehicleVar(routing.Start(0)) == routing.VehicleVar(
            LocationEnum.V0_DEFAULT_START.value))
    routing.Start(0).SetRange(0, 110)

    #routing.solver().Add(routing.VehicleVar(routing.End(0)) == routing.VehicleVar(LocationEnum.V0_END.value))
    #routing.solver().Add(routing.VehicleVar(v0_end_node_idx) == routing.VehicleVar(routing.End(0)))

    v1_default_node_idx = routing.NodeToIndex(9)
    v1_end_node_idx = routing.NodeToIndex(12)
    routing.solver().Add(
        routing.VehicleVar(v1_default_node_idx) == routing.VehicleVar(
            routing.Start(1)))
    #routing.solver().Add(routing.VehicleVar(v1_end_node_idx) == routing.VehicleVar(routing.End(1)))

    v2_default_node_idx = routing.NodeToIndex(10)
    routing.solver().Add(
        routing.VehicleVar(v2_default_node_idx) == routing.VehicleVar(
            routing.Start(2)))

    # TODO: punish for miss one in the list? or punish for couldn't do any one in the list?
    routing.AddDisjunction(
        [LocationEnum.SC_1_TAKEIN_0.value, LocationEnum.SC_2_TAKEIN_0.value],
        100000)
    routing.AddDisjunction(
        [LocationEnum.SC_1_TAKEIN_1.value, LocationEnum.SC_2_TAKEIN_1.value],
        100000)
    routing.AddDisjunction([LocationEnum.RETURN_0.value], 100000)
    routing.AddDisjunction([LocationEnum.RETURN_1.value], 100000)
    routing.AddDisjunction([LocationEnum.PICKUP_0.value], 100000)
    routing.AddDisjunction([LocationEnum.PICKUP_1.value], 100000)
    # routing.AddDisjunction([LocationEnum.SC_1_TAKEIN_0.value], 10000)
    routing.AddDisjunction([LocationEnum.SC_2.value],
                           0)  # we actually don't need SC_2

    # ??? not working?
    routing.AddPickupAndDelivery(LocationEnum.SC_2_RETURN_0.value,
                                 LocationEnum.RETURN_0.value)
    routing.AddPickupAndDelivery(LocationEnum.SC_1_RETURN_1.value,
                                 LocationEnum.RETURN_1.value)
    #routing.AddPickupAndDelivery(LocationEnum.V0_DEFAULT_START.value, LocationEnum.V0_END.value)
    #routing.AddPickupAndDelivery(LocationEnum.V2_DEFAULT_START.value, LocationEnum.V2_END.value)
    #routing.AddPickupAndDelivery(LocationEnum.SC_1_TAKEIN_0.value, LocationEnum.SC_1_RETURN_1.value)

    # v0_end_node_idx = routing.NodeToIndex(11)
    # routing.solver().Add(routing.VehicleVar(v0_end_node_idx) == routing.VehicleVar(routing.End(0)))
    #
    # v1_end_node_idx = routing.NodeToIndex(12)
    # routing.solver().Add(routing.VehicleVar(v1_end_node_idx) == routing.VehicleVar(routing.End(1)))
    #
    # v2_end_node_idx = routing.NodeToIndex(13)
    # routing.solver().Add(routing.VehicleVar(v2_end_node_idx) == routing.VehicleVar(routing.End(2)))

    # Setting first solution heuristic (cheapest addition).
    search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_MOST_CONSTRAINED_ARC)
    #    routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
    #   routing_enums_pb2.FirstSolutionStrategy.ALL_UNPERFORMED)
    # Solve the problem.
    assignment = routing.SolveWithParameters(search_parameters)
    if assignment:
        printer = print_solution(data, routing, assignment)
コード例 #15
0
ファイル: process.py プロジェクト: vmgabriel/or-tools-base
def run():
    """Solve the problem"""
    # Create a set of customer, (and depot) stops.
    customers = Customers(
        num_stops=50,
        min_demand=1,
        max_demand=15,
        box_size=40,
        min_tw=3,
        max_tw=6
    )

    # Create a list of inhomgenious vehicle capacities as integer units.
    capacity = [50, 75, 100, 125, 150, 175, 200, 250]

    # Create a list of inhomogeneous fixed vehicle costs.
    cost = [int(100 + 2 * np.sqrt(c)) for c in capacity]

    # Create a set of vehicles, the number set by the length of capacity.
    vehicles = Vehicles(capacity=capacity, cost=cost)

    # check to see that the problem is feasible, if we don't have enough
    # vehicles to cover the demand, there is no point in going further.
    assert (customers.get_total_demand() < vehicles.get_total_capacity())

    # Set the starting nodes, and create a callback fn for the starting node.
    start_fn = vehicles.return_starting_callback(
        customers,
        same_start_finish=False
    )

    # Create the routing index manager.
    manager = pywrapcp.RoutingIndexManager(
        customers.number,  # int number
        vehicles.number,  # int number
        vehicles.starts,  # List of int start depot
        vehicles.ends)  # List of int end depot

    customers.set_manager(manager)

    # Set model parameters
    model_parameters = pywrapcp.DefaultRoutingModelParameters()

    # The solver parameters can be accessed from the model parameters. For example :
    #   model_parameters.solver_parameters.CopyFrom(
    #       pywrapcp.Solver.DefaultSolverParameters())
    #    model_parameters.solver_parameters.trace_propagation = True

    # Make the routing model instance.
    routing = pywrapcp.RoutingModel(manager, model_parameters)

    parameters = pywrapcp.DefaultRoutingSearchParameters()
    # Setting first solution heuristic (cheapest addition).
    parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
    # Routing: forbids use of TSPOpt neighborhood, (this is the default behaviour)
    parameters.local_search_operators.use_tsp_opt = pywrapcp.BOOL_FALSE
    # Disabling Large Neighborhood Search, (this is the default behaviour)
    parameters.local_search_operators.use_path_lns = pywrapcp.BOOL_FALSE
    parameters.local_search_operators.use_inactive_lns = pywrapcp.BOOL_FALSE

    parameters.time_limit.seconds = 10
    parameters.use_full_propagation = True
    # parameters.log_search = True

    # Create callback fns for distances, demands, service and transit-times.
    dist_fn = customers.return_dist_callback()
    dist_fn_index = routing.RegisterTransitCallback(dist_fn)

    dem_fn = customers.return_dem_callback()
    dem_fn_index = routing.RegisterUnaryTransitCallback(dem_fn)

    # Create and register a transit callback.
    serv_time_fn = customers.make_service_time_call_callback()
    transit_time_fn = customers.make_transit_time_callback()

    def tot_time_fn(from_index, to_index):
        """
        The time function we want is both transit time and service time.
        """
        # Convert from routing variable Index to distance matrix NodeIndex.
        from_node = manager.IndexToNode(from_index)
        to_node = manager.IndexToNode(to_index)
        return serv_time_fn(
            from_node,
            to_node
        ) + transit_time_fn(
            from_node,
            to_node
        )

    tot_time_fn_index = routing.RegisterTransitCallback(tot_time_fn)

    # Set the cost function (distance callback) for each arc, homogeneous for
    # all vehicles.
    routing.SetArcCostEvaluatorOfAllVehicles(dist_fn_index)

    # Set vehicle costs for each vehicle, not homogeneous.
    for veh in vehicles.vehicles:
        routing.SetFixedCostOfVehicle(veh.cost, int(veh.index))

    # Add a dimension for vehicle capacities
    null_capacity_slack = 0
    routing.AddDimensionWithVehicleCapacity(
        dem_fn_index,  # demand callback
        null_capacity_slack,
        capacity,  # capacity array
        True,
        'Capacity')
    # Add a dimension for time and a limit on the total time_horizon
    routing.AddDimension(
        tot_time_fn_index,  # total time function callback
        customers.time_horizon,
        customers.time_horizon,
        True,
        'Time')

    time_dimension = routing.GetDimensionOrDie('Time')
    for cust in customers.customers:
        if cust.tw_open is not None:
            time_dimension.CumulVar(manager.NodeToIndex(cust.index)).SetRange(
                cust.tw_open.seconds, cust.tw_close.seconds)
    """
     To allow the dropping of orders, we add disjunctions to all the customer
    nodes. Each disjunction is a list of 1 index, which allows that customer to
    be active or not, with a penalty if not. The penalty should be larger
    than the cost of servicing that customer, or it will always be dropped!
    """
    # To add disjunctions just to the customers, make a list of non-depots.
    non_depot = set(range(customers.number))
    non_depot.difference_update(vehicles.starts)
    non_depot.difference_update(vehicles.ends)
    penalty = 400000  # The cost for dropping a node from the plan.
    nodes = [
        routing.AddDisjunction([
            manager.NodeToIndex(c)
        ], penalty) for c in non_depot
    ]

    # This is how you would implement partial routes if you already knew part
    # of a feasible solution for example:
    # partial = np.random.choice(list(non_depot), size=(4,5), replace=False)

    # routing.CloseModel()
    # partial_list = [partial[0,:].tolist(),
    #                 partial[1,:].tolist(),
    #                 partial[2,:].tolist(),
    #                 partial[3,:].tolist(),
    #                 [],[],[],[]]
    # print(routing.ApplyLocksToAllVehicles(partial_list, False))

    # Solve the problem !
    assignment = routing.SolveWithParameters(parameters)

    # The rest is all optional for saving, printing or plotting the solution.
    if assignment:
        # # save the assignment, (Google Protobuf format)
        # save_file_base = os.path.realpath(__file__).split('.')[0]
        # if routing.WriteAssignment(save_file_base + '_assignment.ass'):
        #    print('succesfully wrote assignment to file ' + save_file_base +
        #          '_assignment.ass')

        print('The Objective Value is {0}'.format(assignment.ObjectiveValue()))

        plan_output, dropped = vehicle_output_string(
            manager,
            routing,
            assignment
        )
        print(plan_output)
        print('dropped nodes: ' + ', '.join(dropped))

        # you could print debug information like this:
        # print(routing.DebugOutputAssignment(assignment, 'Capacity'))

        vehicle_routes = {}
        for veh in range(vehicles.number):
            vehicle_routes[veh] = build_vehicle_route(
                manager,
                routing,
                assignment,
                customers,
                veh
            )

        # Plotting of the routes in matplotlib.
        fig = plt.figure()
        ax = fig.add_subplot(111)
        # Plot all the nodes as black dots.
        clon, clat = zip(*[(c.lon, c.lat) for c in customers.customers])
        ax.plot(clon, clat, 'k.')
        # plot the routes as arrows
        plot_vehicle_routes(vehicle_routes, ax, customers, vehicles)
        plt.show()

    else:
        print('No assignment')
コード例 #16
0
def mySolver():
    """Solve the CVRP problem."""
    # Instantiate the data problem.
    # [START data]
    data = create_data_model()
    # [END data]

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

    # Create Routing Model.
    # [START routing_model]
    routing = pywrapcp.RoutingModel(manager)

    # [END routing_model]

    # Create and register a transit callback.
    # [START 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)
    # [END transit_callback]

    # Define cost of each arc.
    # [START arc_cost]
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)

    # [END arc_cost]

 # Add Distance constraint.
    # dimension_name = 'Distance'
    # routing.AddDimension(
    #     transit_callback_index,
    #     0,  # no slack
    #     3000,  # vehicle maximum travel distance
    #     True,  # start cumul to zero
    #     dimension_name)
    # distance_dimension = routing.GetDimensionOrDie(dimension_name)
    # distance_dimension.SetGlobalSpanCostCoefficient(100)


    # Add Capacity constraint.
    # [START capacity_constraint]
    def demand_callback(from_index):
        """Returns the demand of the node."""
        # Convert from routing variable Index to demands NodeIndex.
        from_node = manager.IndexToNode(from_index)
        return data['demands'][from_node]

    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')
    # [END capacity_constraint]

    # Add Time Window constraint
    time_evaluator_index = routing.RegisterTransitCallback(
        partial(create_time_evaluator(data), manager))
    add_time_window_constraints(routing, manager, data, time_evaluator_index)

    penalty = 20000
    for node in range(0, len(data['distance_matrix'])):
        if manager.NodeToIndex(node) == -1:
            continue
        routing.AddDisjunction([manager.NodeToIndex(node)], penalty)



    # Setting first solution heuristic.
    # [START parameters]
    # Setting first solution heuristic (cheapest addition).
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)  # pylint: disable=no-membe
    # [END parameters]

    # Solve the problem.
    # [START solve]
    assignment = routing.SolveWithParameters(search_parameters)
    # [END solve]
    data['previous_solution'] = assignment
    # Print solution on console.
    # [START print_solution]
    if assignment:
        print_solution(data, manager, routing, assignment)
    # [END print_solution]

    print('\n\n\n')
    ### Running new instance ####
    data['demands'][14] = 0
    
    new_solution = routing.SolveFromAssignmentWithParameters(data['previous_solution'] , search_parameters)
    
    if new_solution:
        print('New solution from previous one : ')
        print_solution(data, manager , routing, new_solution)
コード例 #17
0
ファイル: solver.py プロジェクト: gertgoeman/vrps
    def solve(self):
        logger.info("Calculating solution.")

        depot = 0
        num_locations = len(self.locations)

        routing = pywrapcp.RoutingModel(num_locations, self.num_vehicles, depot)
        search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()

        # Set heuristics and time limit
        search_parameters.local_search_metaheuristic = routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
        search_parameters.time_limit_ms = self.time_limit_ms

        # Try to minimize the amount of vehicles
        node_indices = []
        for i in range(len(self.locations)):
            node_indices.append(routing.IndexToNode(i))

        # Add additional cost for each vehicle.
        routing.AddSoftSameVehicleConstraint(node_indices, 100000)

        #  Set cost function. We use total distance.
        cost_function = self.__cost_function
        routing.SetArcCostEvaluatorOfAllVehicles(cost_function)
        
        # Add time dimension.
        total_time_callback = self.__total_time_callback # I honestly have no idea why this is necessary, but if I don't do it, a segmentation fault is thrown.

        time_horizon = 24 * 3600 # Used as both the upper bound for the slack variable (maximum amount of time between 2 nodes) and the upper bound for the cummulative variable (total maximum amount of time).
        time = "Time"
        time_fix_start_cumul_to_zero_time = True

        routing.AddDimension(total_time_callback,
                             time_horizon,
                             time_horizon,
                             time_fix_start_cumul_to_zero_time,
                             time)

        # Add time window constraints.
        time_dimension = routing.GetDimensionOrDie(time)

        for location in range(1, num_locations):
            start = self.time_windows[location][0]
            end = self.time_windows[location][1]
            time_dimension.CumulVar(location).SetRange(start, end)

        # Set a cost coefficient on time. This should minimize "idle" time of vehicles.
        time_dimension.SetSpanCostCoefficientForAllVehicles(2)

        # Solve the problem.
        assignment = routing.SolveWithParameters(search_parameters)
        
        # No solution, nothing to return.
        if not assignment: return None

        # Create the solution
        time_dimension = routing.GetDimensionOrDie(time);

        vehicles = []

        for vehicle_nbr in range(self.num_vehicles):
            index = routing.Start(vehicle_nbr)

            nodes = []

            while not routing.IsEnd(index):
                node_index = routing.IndexToNode(index)
                time_var = time_dimension.CumulVar(index)
                nodes.append(Node(self.locations[node_index], assignment.Value(time_var)))
                index = assignment.Value(routing.NextVar(index))

            node_index = routing.IndexToNode(index)
            time_var = time_dimension.CumulVar(index)
            nodes.append(Node(self.locations[node_index], assignment.Value(time_var)))

            if len(nodes) > 2: # 2 is from start to finish directly
                vehicles.append(Vehicle(nodes))

        return Solution(vehicles)
コード例 #18
0
ファイル: tsp.py プロジェクト: caelan/pb-construction
def solve_tsp(all_elements,
              ground_nodes,
              node_points,
              printed,
              initial_point,
              final_point,
              bidirectional=False,
              layers=True,
              max_time=30,
              visualize=True,
              verbose=False):
    # https://developers.google.com/optimization/routing/tsp
    # https://developers.google.com/optimization/reference/constraint_solver/routing/RoutingModel
    # http://www.math.uwaterloo.ca/tsp/concorde.html
    # https://developers.google.com/optimization/reference/python/constraint_solver/pywrapcp
    # AddDisjunction
    # TODO: pick up and delivery
    # TODO: time window for skipping elements
    # TODO: Minimum Spanning Tree (MST) bias
    # TODO: time window constraint to ensure connected
    # TODO: reuse by simply swapping out the first vertex
    # arc-routing
    from ortools.constraint_solver import routing_enums_pb2, pywrapcp
    from extrusion.visualization import draw_ordered, draw_model
    start_time = time.time()
    assert initial_point is not None
    remaining = all_elements - printed
    #printed_nodes = compute_printed_nodes(ground_nodes, printed)
    if not remaining:
        cost = get_distance(initial_point, final_point)
        return [], cost
    # TODO: use as a lower bound
    total_distance = compute_element_distance(node_points, remaining)

    # TODO: some of these are invalid still
    level_from_node, cost_from_edge, sequence = greedily_plan(
        all_elements, node_points, ground_nodes, remaining, initial_point)
    if sequence is None:
        return None, INF
    extrusion_edges = set()
    point_from_vertex = {INITIAL_NODE: initial_point, FINAL_NODE: final_point}
    frame_nodes = nodes_from_elements(remaining)
    min_level = min(level_from_node[n] for n in frame_nodes)
    max_level = max(level_from_node[n] for n in frame_nodes)

    frame_keys = set()
    keys_from_node = defaultdict(set)
    for element in remaining:
        mid = (element, element)
        point_from_vertex[mid] = get_midpoint(node_points, element)
        for node in element:
            key = (element, node)
            point_from_vertex[key] = node_points[node]
            frame_keys.add(key)
            keys_from_node[node].add(key)

        for reverse in [True, False]:
            directed = reverse_element(element) if reverse else element
            node1, node2 = directed
            #delta = node_points[node2] - node_points[node1]
            #pitch = get_pitch(delta)
            #upward = -SUPPORT_THETA <= pitch
            # theta = angle_between(delta, [0, 0, -1])
            # upward = theta < (np.pi / 2 - SUPPORT_THETA)
            #if (directed in tree_elements): # or upward:
            if bidirectional or (directed in cost_from_edge):
                # Add edges from anything that is roughly the correct cost
                start = (element, node1)
                end = (element, node2)
                extrusion_edges.update({(start, mid), (mid, end)})

    for node in keys_from_node:
        for edge in product(keys_from_node[node], repeat=2):
            extrusion_edges.add(edge)
    # Key thing is partial order on buckets of elements to adhere to height

    # Connect v2 to v1 if v2 is the same level
    # Traversing an edge might move to a prior level (but at most one)
    transit_edges = set()
    for directed in product(frame_keys, repeat=2):
        key1, key2 = directed
        element1, node1 = key1
        #level1 = min(level_from_node[n] for n in element1)
        level1 = level_from_node[get_other_node(node1, element1)]
        _, node2 = key2
        level2 = level_from_node[node2]
        if level2 in [level1, level1 + 1]:  # TODO: could bucket more coarsely
            transit_edges.add(directed)
    for key in frame_keys:
        _, node = key
        if level_from_node[node] == min_level:
            transit_edges.add((INITIAL_NODE, key))
        if level_from_node[node] in [max_level, max_level - 1]:
            transit_edges.add((key, FINAL_NODE))
    # TODO: can also remove restriction that elements are printed in a single direction
    if not layers:
        transit_edges.update(
            product(frame_keys | {INITIAL_NODE, FINAL_NODE},
                    repeat=2))  # TODO: apply to greedy as well

    key_from_index = list(
        {k
         for pair in extrusion_edges | transit_edges for k in pair})
    edge_weights = {
        pair: INVALID
        for pair in product(key_from_index, repeat=2)
    }
    for k1, k2 in transit_edges | extrusion_edges:
        p1, p2 = point_from_vertex[k1], point_from_vertex[k2]
        edge_weights[k1, k2] = get_distance(p1, p2)
    #edge_weights.update({e: 0. for e in extrusion_edges}) # frame edges are free
    edge_weights[FINAL_NODE, INITIAL_NODE] = 0.
    edge_weights[INITIAL_NODE,
                 FINAL_NODE] = INVALID  # Otherwise might be backward

    print(
        'Elements: {} | Vertices: {} | Edges: {} | Structure: {:.3f} | Min Level {} | Max Level: {}'
        .format(len(remaining), len(key_from_index), len(edge_weights),
                total_distance, min_level, max_level))
    index_from_key = dict(map(reversed, enumerate(key_from_index)))
    num_vehicles, depot = 1, index_from_key[INITIAL_NODE]
    manager = pywrapcp.RoutingIndexManager(len(key_from_index), num_vehicles,
                                           depot)
    #[depot], [depot])
    solver = pywrapcp.RoutingModel(manager)

    cost_from_index = {}
    for (k1, k2), weight in edge_weights.items():
        i1, i2 = index_from_key[k1], index_from_key[k2]
        cost_from_index[i1, i2] = int(math.ceil(SCALE * weight))
    solver.SetArcCostEvaluatorOfAllVehicles(
        solver.RegisterTransitCallback(
            lambda i1, i2: cost_from_index[manager.IndexToNode(
                i1), manager.IndexToNode(i2)]))  # from -> to

    # sequence = plan_stiffness(None, None, node_points, ground_nodes, elements,
    #                           initial_position=initial_point, stiffness=False, max_backtrack=INF)

    initial_order = []
    #initial_order = [INITIAL_NODE] # Start and end automatically included
    for directed in sequence:
        node1, node2 = directed
        element = get_undirected(remaining, directed)
        initial_order.extend([
            (element, node1),
            (element, element),
            (element, node2),
        ])
    initial_order.append(FINAL_NODE)
    #initial_order.append(INITIAL_NODE)
    initial_route = [index_from_key[key] for key in initial_order]
    #index = initial_route.index(0)
    #initial_route = initial_route[index:] + initial_route[:index] + [0]

    initial_solution = solver.ReadAssignmentFromRoutes(
        [initial_route], ignore_inactive_indices=True)
    assert initial_solution is not None
    #print_solution(manager, solver, initial_solution)
    #print(solver.GetAllDimensionNames())
    #print(solver.ComputeLowerBound())

    objective = initial_solution.ObjectiveValue() / SCALE
    invalid = int(objective / INVALID)
    order = parse_solution(solver, manager, key_from_index,
                           initial_solution)[:-1]
    ordered_pairs = get_pairs(order)
    cost = sum(edge_weights[pair] for pair in ordered_pairs)
    #print('Initial solution | Invalid: {} | Objective: {:.3f} | Cost: {:.3f} | Duration: {:.3f}s'.format(
    #    invalid, objective, cost, elapsed_time(start_time)))
    if False and visualize:  # and invalid
        remove_all_debug()
        draw_model(printed, node_points, None, color=BLACK)
        draw_point(initial_point, color=BLACK)
        draw_point(final_point, color=GREEN)
        for pair in ordered_pairs:
            if edge_weights[pair] == INVALID:
                for key in pair:
                    draw_point(point_from_vertex[key], color=RED)
        draw_ordered(ordered_pairs, point_from_vertex)
        wait_for_user()  # TODO: pause only if viewer
    #sequence = extract_sequence(level_from_node, remaining, ordered_pairs)
    #print(compute_sequence_distance(node_points, sequence, start=initial_point, end=final_point), total_distance+cost)
    #print([cost_from_edge[edge] for edge in sequence])
    #return sequence, cost

    start_time = time.time()
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    #search_parameters.solution_limit = 1
    search_parameters.time_limit.seconds = int(max_time)
    search_parameters.log_search = verbose
    # AUTOMATIC | PATH_CHEAPEST_ARC | LOCAL_CHEAPEST_ARC | GLOBAL_CHEAPEST_ARC | LOCAL_CHEAPEST_INSERTION
    #search_parameters.first_solution_strategy = (
    #    routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC)
    # AUTOMATIC | GREEDY_DESCENT | GUIDED_LOCAL_SEARCH | SIMULATED_ANNEALING | TABU_SEARCH | OBJECTIVE_TABU_SEARCH
    #search_parameters.local_search_metaheuristic = (
    #    routing_enums_pb2.LocalSearchMetaheuristic.GREEDY_DESCENT)
    #solution = solver.SolveWithParameters(search_parameters)
    solution = solver.SolveFromAssignmentWithParameters(
        initial_solution, search_parameters)
    #print_solution(manager, solver, solution)

    print('Status: {} | Text: {}'.format(solver.status(),
                                         STATUS[solver.status()]))
    if not solution:
        print('Failure! Duration: {:.3f}s'.format(elapsed_time(start_time)))
        return None, INF

    objective = solution.ObjectiveValue() / SCALE
    invalid = int(objective / INVALID)
    order = parse_solution(solver, manager, key_from_index, solution)[:-1]
    ordered_pairs = get_pairs(order)  # + [(order[-1], order[0])]
    #cost = compute_element_distance(point_from_vertex, ordered_pairs)
    cost = sum(edge_weights[pair] for pair in ordered_pairs)
    print(
        'Final solution | Invalid: {} | Objective: {:.3f} | Cost: {:.3f} | Duration: {:.3f}s'
        .format(invalid, objective, cost, elapsed_time(start_time)))

    sequence = extract_sequence(level_from_node, remaining, ordered_pairs)
    #print(compute_sequence_distance(node_points, sequence, start=initial_point, end=final_point)) #, total_distance+cost)

    #print(sequence)
    violations = 0
    printed_nodes = compute_printed_nodes(ground_nodes, printed)
    for directed in sequence:
        if directed[0] not in printed_nodes:
            #print(directed)
            violations += 1
        printed_nodes.update(directed)
    print('Violations:', violations)

    if visualize:
        # TODO: visualize by weight
        remove_all_debug()
        draw_model(printed, node_points, None, color=BLACK)
        draw_point(initial_point, color=BLACK)
        draw_point(final_point, color=GREEN)
        #tour_pairs = ordered_pairs + get_pairs(list(reversed(order)))
        #draw_model(extrusion_edges - set(tour_pairs), point_from_vertex, ground_nodes, color=BLACK)
        draw_ordered(ordered_pairs, point_from_vertex)
        wait_for_user()

    if sequence is None:
        return None, INF
    #print([cost_from_edge[edge] for edge in sequence])
    return sequence, cost
コード例 #19
0
def main():
    """Solve the CVRP problem."""
    # Instantiate the data problem.
    data = create_data_model()

    # 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)

    # Add Distance constraint.
    dimension_name = 'Distance'
    routing.AddDimension(
        transit_callback_index,
        0,  # no slack
        3000,  # vehicle maximum travel distance
        True,  # start cumul to zero
        dimension_name)
    distance_dimension = routing.GetDimensionOrDie(dimension_name)
    distance_dimension.SetGlobalSpanCostCoefficient(100)

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

    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')

    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

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

    # Print solution on console.
    if solution:
        print_solution(data, manager, routing, solution)
コード例 #20
0
def main():
    """Solve the VRP with time windows."""
    # Instantiate the data problem.
    data = create_data_model()

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

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

    # Create and register a transit callback.
    def time_callback(from_index, to_index):
        """Returns the travel time 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_callback_index = routing.RegisterTransitCallback(time_callback)

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

    # Add Time Windows constraint.
    time = 'Time'
    routing.AddDimension(
        transit_callback_index,
        15,  # allow waiting time
        600,  # maximum time per vehicle
        True,  # Don't force start cumul to zero.
        time)
    time_dimension = routing.GetDimensionOrDie(time)
    # Add time window constraints for each location except depot.
    for location_idx, time_window in enumerate(data['time_windows']):
        if location_idx == 0:
            continue
        index = manager.NodeToIndex(location_idx)
        time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1])
    # Add time window constraints for each vehicle start node.
    for vehicle_id in range(data['num_vehicles']):
        index = routing.Start(vehicle_id)
        time_dimension.CumulVar(index).SetRange(data['time_windows'][0][0],
                                                data['time_windows'][0][1])

    # Instantiate route start and end times to produce feasible times.
    for i in range(data['num_vehicles']):
        routing.AddVariableMinimizedByFinalizer(
            time_dimension.CumulVar(routing.Start(i)))
        routing.AddVariableMinimizedByFinalizer(
            time_dimension.CumulVar(routing.End(i)))

    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

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

    # Print solution on console.
    if solution:
        print_solution(data, manager, routing, solution)
コード例 #21
0
def main():
    """Solve the CVRP problem."""
    # Instantiate the data problem.
    data = create_data_model()

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

    # Create Routing Model.
    routing = pywrapcp.RoutingModel(manager)
    '''Create and register a transit callback. The distance matrix records the direct distances between the nodes. The distance callback can do some extra manipulations on top of what's recorded
    in the distance matrix'''
    def distance_callback(from_index, to_index):
        """Returns the distance between the two nodes. And also sets the cost of traveling between nodes (by routing.SetArcCostEvaluatorOfAllVehicles). and passes the cost to the solver"""
        # 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(edge) in the graph using the distance callback
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)

    dimension_name2 = 'Stops'
    car_capacity_callback_index = routing.RegisterUnaryTransitCallback(
        lambda index: 1)
    '''AddDimension applies dimension to all vehicles,
        AddDimensionWithVehicleCapacity can take a vector of capacities and apply them to corresponding vehicles)'''
    routing.AddDimension(
        car_capacity_callback_index,
        0,  # null capacity slack
        3,  # vehicle maximum number of stops
        True,  # start cumul to zero
        'Stops')

    # allow to drop nodes
    penalty = 15000
    for node in range(1, len(data['distance_matrix'])):
        routing.AddDisjunction([manager.NodeToIndex(node)], penalty)

    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters(
    )  # search strategy
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

    # Solve the problem.
    solution = routing.SolveWithParameters(search_parameters)
    if not solution:
        print("No solution")
    # Print solution on console.
    if solution:
        route_dict = print_solution(data, manager, routing, solution)
        driver_map = firebase.route(route_dict)
        driver_map1 = firebase.stringify(driver_map)
        firebase.add_to_db(driver_map1)
        rider_map = firebase.create_rider_map(driver_map)
        firebase.add_to_db_rider(rider_map)
コード例 #22
0
ファイル: vrp_tokens.py プロジェクト: weexp/or-tools
def main():
    """Solve the CVRP problem."""
    # Instantiate the data problem.
    data = create_data_model()

    # Create the routing index manager.
    manager = pywrapcp.RoutingIndexManager(len(data['tokens']),
                                           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 10

    transit_callback_index = routing.RegisterTransitCallback(distance_callback)

    routing.AddDimension(
        transit_callback_index,
        0,  # null slack
        3000,  # maximum distance per vehicle
        True,  # start cumul to zero
        "distance")
    distance_dimension = routing.GetDimensionOrDie("distance")
    distance_dimension.SetGlobalSpanCostCoefficient(100)

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

    # Add Token constraint.
    def token_callback(from_index):
        """Returns the number of token consumed by the node."""
        # Convert from routing variable Index to tokens NodeIndex.
        from_node = manager.IndexToNode(from_index)
        return data['tokens'][from_node]

    token_callback_index = routing.RegisterUnaryTransitCallback(token_callback)
    routing.AddDimensionWithVehicleCapacity(
        token_callback_index,
        0,  # null capacity slack
        data['vehicle_tokens'],  # vehicle maximum tokens
        False,  # start cumul to zero
        'Token')
    # Add constraint: special node can only be visited if token remaining is zero
    token_dimension = routing.GetDimensionOrDie('Token')
    for node in range(1, 6):
        index = manager.NodeToIndex(node)
        routing.solver().Add(token_dimension.CumulVar(index) == 0)

    # Setting first solution heuristic.
    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.FromSeconds(1)

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

    # Print solution on console.
    if solution:
        print_solution(manager, routing, solution)
    else:
        print("No solution found !")
コード例 #23
0
def main():
    """Solve the CVRP problem."""
    # Instantiate the data problem.
    data = create_data_model()

    time_matrix = compute_euclidean_distance_matrix(data['locations'])

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

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

    # Create and register a transit callback.
    def time_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 time_matrix[from_node][to_node]

    transit_callback_index = routing.RegisterTransitCallback(time_callback)

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

    # Add Time Windows constraint.
    time = 'Time'
    routing.AddDimension(
        transit_callback_index,
        10,  # allow waiting time
        100,  # 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 except depot.
    for location_idx, time_window in enumerate(data['time_windows']):
        if location_idx == 0:
            continue
        index = manager.NodeToIndex(location_idx)
        time_dimension.CumulVar(index).SetRange(data['time_windows'][0][0],
                                                data['time_windows'][1][1])
    # Add time window constraints for each vehicle start node.
    for vehicle_id in range(data['num_vehicles']):
        index = routing.Start(vehicle_id)
        time_dimension.CumulVar(index).SetRange(data['time_windows'][0][0],
                                                data['time_windows'][0][1])

    # Instantiate route start and end times to produce feasible times.
    for i in range(data['num_vehicles']):
        routing.AddVariableMinimizedByFinalizer(
            time_dimension.CumulVar(routing.Start(i)))
        routing.AddVariableMinimizedByFinalizer(
            time_dimension.CumulVar(routing.End(i)))

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

    demand_callback_index = routing.RegisterUnaryTransitCallback(
        demand_callback)
    routing.AddDimensionWithVehicleCapacity(
        demand_callback_index,
        0,  # null capacity slack
        data['vehicle_capacities'],  # vehicle maximum capacities
        False,  # start cumul to zero
        'Capacity')

    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.BEST_INSERTION)
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.local_search_metaheuristic = (
        routing_enums_pb2.LocalSearchMetaheuristic.GREEDY_DESCENT)
    search_parameters.time_limit.FromSeconds(1)

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

    # Print solution on console.
    if solution:
        solution_dict = print_solution(data, manager, routing, solution)

    coordinates = [
        (35, 35),
        (41, 49),
        (35, 17),
        (55, 45),
        (55, 20),
        (15, 30),
        (25, 30),
        (20, 50),
        (10, 43),
        (55, 60),
        (30, 60),
        (20, 65),
        (50, 35),
        (30, 25),
        (15, 10),
        (30, 5),
        (10, 20),
        (5, 30),
        (20, 40),
        (15, 60),
        (45, 65),
        (45, 20),
        (45, 10),
        (55, 5),  #23
        (65, 35),
        (65, 20),
        (45, 30),
        (35, 40),
        (41, 37),
        (64, 42),
        (40, 60),
        (31, 52),
        (35, 69),
        (53, 52),
        (65, 55),
        (63, 65),
        (2, 60),
        (20, 20),
        (5, 5),
        (60, 12),
        (40, 25),
        (42, 7),
        (24, 12),
        (23, 3),  #43
        (11, 14),
        (6, 38),
        (2, 48),
        (8, 56),
        (13, 52),
        (6, 68),
        (47, 47),
        (49, 58),
        (27, 43),
        (37, 31),
        (57, 29),
        (63, 23),
        (53, 12),
        (32, 12),
        (36, 26),
        (21, 24),
        (17, 34),
        (12, 24),
        (24, 58),
        (27, 69),
        (15, 77),
        (62, 77),
        (49, 73),
        (67, 5),
        (56, 39),
        (37, 47),
        (37, 56),
        (57, 68),  #71
        (47, 16),
        (44, 17),
        (46, 13),
        (49, 11),
        (49, 42),
        (53, 43),
        (61, 52),
        (57, 48),
        (56, 37),
        (55, 54),
        (15, 47),
        (14, 37),
        (11, 31),
        (16, 22),
        (4, 18),
        (28, 18),
        (26, 52),
        (26, 35),
        (31, 67),
        (15, 19),
        (22, 22),
        (18, 24),
        (26, 27),
        (25, 24),
        (22, 27),
        (25, 21),
        (19, 21),
        (20, 26),
        (18, 18),  #100
    ]
    X = np.array([x[0] for x in coordinates])
    Y = np.array([x[1] for x in coordinates])

    f, ax = plt.subplots(figsize=[8, 6])

    ax.plot(X, Y, 'ko', markersize=8)
    ax.plot(X[0], Y[0], 'gX', markersize=30)

    for i, txt in enumerate(coordinates):
        ax.text(X[i], Y[i], f"{i}")

    vehicle_colors = [
        "g", "k", "r", "m", "c", "b", "y", "g", "k", "r", "m", "c", "b", "y",
        "g", "k", "r", "m", "c", "b", "y", "g", "k", "r", "m"
    ]  #warna garis
    for vehicle in solution_dict:
        ax.plot(X[solution_dict[vehicle] + [0]],
                Y[solution_dict[vehicle] + [0]],
                f'{vehicle_colors[vehicle]}--')

    ax.set_title("Greedy descent - Best insertion")

    plt.show()
コード例 #24
0
def main():

  data = create_data_array()
  locations = data[0]
  demands = data[1]
  num_locations = len(locations)
  num_vehicles = 2 #Number of vehicles specified here.
  #Nodes are indexed from 0 to tsp_size - 1. The depot is the starting node of the route.
  depot = 0

  #Create routing model
  if num_locations > 0:
    routing = pywrapcp.RoutingModel(num_locations, num_vehicles, depot)
    #Define search parameters for how the route will be found.
    search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters() #Can modify search strategy here.

    #Create the distance callback, which takes two arguments (the from and to node indices)
    #and returns the distance between these nodes.
    dist_between_nodes = CreateDistanceCallback(locations)
    salary_dist_callback = dist_between_nodes.salary_distance
    special_dist_callback = dist_between_nodes.special_distance
    routing.SetArcCostEvaluatorOfVehicle(salary_dist_callback, 0) #Distance callback for vehicle 0 passed to solver.
    routing.SetArcCostEvaluatorOfVehicle(special_dist_callback, 1) #Distance callback for vehicle 1 passed to solver.

    #Create the demand callback
    demands_at_nodes = CreateDemandCallback(demands)
    demands_callback = demands_at_nodes.demand

    #Add Dimension for demand to routing model.
    slack_max = 0
    vehicle_capacity = 100
    fix_start_cumul_to_zero = True
    demand = "Demand"
    routing.AddDimension(demands_callback, slack_max, vehicle_capacity, fix_start_cumul_to_zero, demand)

    #Solve, returns a solution if any.
    assignment = routing.SolveWithParameters(search_parameters)

    if assignment: #If a solution was found.
      #Solution cost.
      print("Total distance: ", str(assignment.ObjectiveValue()), " units\n")
      
      for vehicle_nbr in range(num_vehicles):
        index = routing.Start(vehicle_nbr) #Sets index to be the index of the starting node of the route of the vehicle given by vehicle_nbr.
        index_next = assignment.Value(routing.NextVar(index))
        route = ''
        route_length = 0
        route_demand = 0
        while not routing.IsEnd(index_next): #While there are still nodes left on this path.
          #Convert variable indices to node indices in the displayed route.
          node_index = routing.IndexToNode(index)
          node_index_next = routing.IndexToNode(index_next)
          route += str(node_index) + " -> "
          #Add route distance.
          route_length += locations[node_index][node_index_next][vehicle_nbr]
          #Add route demand.
          route_demand += demands[node_index_next]
          #Advance to the next node.
          index = index_next 
          index_next = assignment.Value(routing.NextVar(index))

        node_index = routing.IndexToNode(index)
        node_index_next = routing.IndexToNode(index_next)
        route += str(node_index) + " -> " + str(node_index_next)

        route_length += locations[node_index][node_index_next][vehicle_nbr]
        print("Vehicle number: ", vehicle_nbr)
        print("Vehicle demand: ", route_demand)
        print("Distance travelled: ", route_length)
        print("Route:\n\n", route)
        

    else:
      print("No solution found.")

  else:
    print("Specify an instance greater than 0.")
コード例 #25
0
ファイル: main.py プロジェクト: AlexLisong/route-smart
def CVRP(addresses, API_key, vehicle_capacities, demands, starts, ends, depot, distance_type='Manhattan', use_1st_solu_strategy = False, scale=1): 
    '''return optimal solution for a Capacity Vehicle Routing Problem (CVRP) that 
    - each vehicle has limited capacity
    - allow dropped visits (but penalize_dropped visits)
    - allow setting different start and end locations for each vehicle
    
    Para
    ----
    - addresses: a list of real addresses (str) or (x, y)-locations
    #no longer need...num_vehicles: how many vehicles are used to cover those addresses
    - vehicle_capacities: a list of capacity of each vehicle
    - starts: a list of start-location-indices, each element for a vehicle/route
    - ends: a list of end-location-indices, each element for a vehicle/route
    - depot: the index of start & end address/location
      in the case that starts, ends, depot are all None, meaning we allow arbitary start and end location, we need to pre-process distance matrix by adding 1st row & 1st col all 0.
    - distance_type: 'Euclidean' or 'Manhattan'
    - use_1st_solu_strategy (bool)
    - scale (int): since the solver requires the distance_matrix has integer entries, we up-scale distance (says by 100) and take its integer part in order to keep the internal computation accurate.
    
    '''
    ###--------------------------------------------------------------------------<internal functions start>
    
    def create_data_model(distance_matrix, demands, vehicle_capacities, starts, ends, depot):
        '''create data model, a dictionary with following keys
        Para
        ----
        distance_matrix(a list of lists of numbers):entry (i,j) represents the distance bw ith row address and jth col address
        num_vehicles (int): number of vehicles in the fleet
        depot (int): start & end point for the trip represented by the index of addresses
        '''
        data = {}
        '''TBD
        if (starts is None) and (ends is None) and (depot == 0): # the case that allowing arbitary start and end location for each vehicle
            distance_matrix = [[0]*(len(distance_matrix)+1)] + [[0]+x for x in distance_matrix]
            demands = [0] + demands'''
        
        data['distance_matrix'] = distance_matrix
        data['demands'] = demands
        data['vehicle_capacities'] = vehicle_capacities
        data['num_vehicles'] = len(vehicle_capacities)
        data['starts'] = starts
        data['ends'] = ends
        data['depot'] = depot
        return data

    
    def print_solution(data, manager, routing, solution, scale):
        """Prints solution 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 solution.Value(routing.NextVar(node)) == node:
                dropped_nodes += ' {}'.format(manager.IndexToNode(node))
        print(dropped_nodes)
        # Display routes
        max_route_distance = 0
        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 = solution.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/scale)
            plan_output += 'Load of the route: {}\n'.format(route_load)
            print(plan_output)
            max_route_distance = max(route_distance, max_route_distance)
            total_distance += route_distance
            total_load += route_load
        print('Total Distance of all routes: {}m'.format(total_distance/scale))
        print('Total Load of all routes: {}'.format(total_load))
        print('Maximum of the route distances: {}m'.format(max_route_distance/scale))



    def get_routes(manager, routing, solution):
        """Get vehicle routes from a solution and store them in an array (a list of lists)."""
        # 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 = []
        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)
        return routes
    
    def send_request(origin_addresses, dest_addresses, API_key):
        """ Build and send request for the given origin and destination addresses."""
        def build_address_str(addresses):
            # Build a pipe-separated string of addresses
            address_str = ''
            for i in range(len(addresses) - 1):
                address_str += addresses[i] + '|'
            address_str += addresses[-1]
            return address_str

        request = 'https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial'
        origin_address_str = build_address_str(origin_addresses)
        dest_address_str = build_address_str(dest_addresses)
        request = request + '&origins=' + origin_address_str + '&destinations=' + \
                           dest_address_str + '&key=' + API_key
        #replace this one that only works in python 2: jsonResult = urllib.urlopen(request).read()
        import urllib.request

        with urllib.request.urlopen(request) as url:
            jsonResult = url.read()
        response = json.loads(jsonResult)
        return response

    def build_distance_matrix(response):
        distance_matrix = []
        for row in response['rows']:
            row_list = [row['elements'][j]['distance']['value'] for j in range(len(row['elements']))]
            distance_matrix.append(row_list)
        return distance_matrix



    def addresses_to_distance_matrix(API_key, addresses):
        """turn addresses to distance matrix
        API_key: get one here https://developers.google.com/maps/documentation/distance-matrix/start#get-a-key
        addresses: a list of addresses
        """
        # Distance Matrix API only accepts 100 elements per request, so get rows in multiple requests.
        max_elements = 100
        num_addresses = len(addresses) # 16 in this example.
        # Maximum number of rows that can be computed per request (6 in this example).
        max_rows = max_elements // num_addresses
        # num_addresses = q * max_rows + r (q = 2 and r = 4 in this example).
        q, r = divmod(num_addresses, max_rows)
        dest_addresses = addresses
        distance_matrix = []
        # Send q requests, returning max_rows rows per request.
        for i in range(q):
            origin_addresses = addresses[i * max_rows: (i + 1) * max_rows]
            response = send_request(origin_addresses, dest_addresses, API_key)
            distance_matrix += build_distance_matrix(response)

        # Get the remaining remaining r rows, if necessary.
        if r > 0:
            origin_addresses = addresses[q * max_rows: q * max_rows + r]
            response = send_request(origin_addresses, dest_addresses, API_key)
            distance_matrix += build_distance_matrix(response)
        return distance_matrix


    def locations_to_distance_matrix(locations, scale, distance_type='Euclidean'):
        '''return the distance matrix between locations'''

        #scale each element in locations
        locations = [(p[0]*scale, p[1]*scale) for p in locations]

        if distance_type == 'Euclidean':
            dist_mat = [[int(((p1[0]-p2[0])**2 + (p1[1]-p2[1])**2)**.5) for p2 in locations] for p1 in locations]

        if distance_type == 'Manhattan':
            dist_mat = [[abs(p1[0]-p2[0]) + abs(p1[1]-p2[1]) for p1 in locations] for p2 in locations]

        return dist_mat
    
    def preprocess_addresses(addresses):
        '''turn a string of separated words into a string of words connected by +'''
        return ['+'.join(re.sub("[^\w\s]", "", address).split()) for address in addresses]
    
    ###--------------------------------------------------------------------------<internal functions end>
    # create distance matrix
    if len(addresses[0])<3: # the case of (x, y) location
        distance_matrix = locations_to_distance_matrix(locations=addresses, scale=scale, distance_type=distance_type)
    else: # the case of address string
        addresses = preprocess_addresses(addresses)
        distance_matrix = addresses_to_distance_matrix(API_key, addresses)
    
    # create data
    data = create_data_model(distance_matrix, demands, vehicle_capacities, starts, ends, depot)
    
    # Create the routing index manager.
    #if (starts is not None) and (ends is not None):
    manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']),
                                               data['num_vehicles'], 
                                               data['starts'],
                                               data['ends'])
    """TBD
    
    else:
        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)

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

    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')
    
    # Allow to drop nodes.
    penalty = int(sum(sum(np.array(data['distance_matrix']))))
    for node in range(1, len(data['distance_matrix'])):
        routing.AddDisjunction([manager.NodeToIndex(node)], penalty)

    
    # Add Distance constraint.
    dimension_name = 'Distance'
    routing.AddDimension(
        transit_callback_index,
        0,  # no slack
        30000000,  # vehicle maximum travel distance
        True,  # start cumul to zero
        dimension_name)
    distance_dimension = routing.GetDimensionOrDie(dimension_name)
    distance_dimension.SetGlobalSpanCostCoefficient(100)

    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    if use_1st_solu_strategy:
        search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
    else:
        search_parameters.local_search_metaheuristic = (routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
        search_parameters.time_limit.seconds = 30
        search_parameters.log_search = True
        
    # Solve the problem.
    solution = routing.SolveWithParameters(search_parameters)

    # Print solution on console.
    if solution:
        print_solution(data, manager, routing, solution, scale)
        routs = get_routes(manager, routing, solution)
        return routs
コード例 #26
0
def resolverdorSat():
    gmaps = False
    f = open("solucaoSAT.txt", "a+")
    # FUNCOES PARA MONTAGEM DA MATRIZ DE DISTANCIAS
    for x in range(0, 6):
        f.write("#################### Dia " + str(x) +
                " ####################\n")

        if gmaps:
            # Cria os dados.
            dados = getEnderecos(x)
            enderecos = dados['enderecos']
            chave_API = dados['chave_API']
            matrizDeDistancias = criaMatrizDeDistancias(dados)
            f.write("Matriz de distancias: \n" + str(matrizDeDistancias))
        else:
            matrizDeDistancias = getMatrizDeDistancias(x)

        # FUNCOES PARA RESOLUCAO DO PROBLEMA DO CAIXEIRO VIAJANTE
        """Resolucao do problema de roteamento."""
        # Instancia os dados do problema.
        dados = criaModeloDeDados(matrizDeDistancias)
        # Cria o gerenciador de indice do roteamento.
        gerenciador = pywrapcp.RoutingIndexManager(
            len(dados['matrizDeDistancias']), dados['numVeiculos'],
            dados['pontoDePartida'])
        # Cria o modelo do roteamento.
        roteamento = pywrapcp.RoutingModel(gerenciador)

        # Cria e registra callback de transito.
        def distance_callback(indiceOrigem, indiceDestino):
            """Retorna a distancia entre dois nos."""
            # Converte de um indice da variavel roteamento para um indice da matriz de distancias.
            noOrigem = gerenciador.IndexToNode(indiceOrigem)
            noDestino = gerenciador.IndexToNode(indiceDestino)
            return dados['matrizDeDistancias'][noOrigem][noDestino]

        transit_callback_index = roteamento.RegisterTransitCallback(
            distance_callback)

        # Define o custo para cada arco.
        roteamento.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)

        # Adiciona restricao de distancia.
        nomeDimensao = 'Distance'
        roteamento.AddDimension(
            transit_callback_index,
            0,  # sem folga
            400000000,  # maior distancia percorrida por um veiculo
            True,  # inicia acumulando do 0
            nomeDimensao)
        dimensaoDistancia = roteamento.GetDimensionOrDie(nomeDimensao)
        dimensaoDistancia.SetGlobalSpanCostCoefficient(100)

        # Configura a heuristica para "primeira solucao".
        parametrosDeBusca = pywrapcp.DefaultRoutingSearchParameters()
        parametrosDeBusca.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

        # Resolve com os parametros.
        solucao = roteamento.SolveWithParameters(parametrosDeBusca)

        if solucao:
            f.flush()
            imprimeSolucao(dados, gerenciador, roteamento, solucao)
            f.write("\n")
        else:
            f.flush()
            f.write("\nSolucao nao encontrada\n")
    f.close()
コード例 #27
0
def main():
    """Entry point of the program."""
    # Instantiate the data problem.
    # [START data]
    data = create_data_model()
    # [END data]

    # Create the routing index manager.
    # [START index_manager]
    manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']),
                                           data['num_vehicles'],
                                           data['starts'], data['ends'])
    # [END index_manager]

    # Create Routing Model.
    # [START routing_model]
    routing = pywrapcp.RoutingModel(manager)

    # [END routing_model]

    # Create and register a transit callback.
    # [START 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)
    # [END transit_callback]

    # Define cost of each arc.
    # [START arc_cost]
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
    # [END arc_cost]

    # Add Distance constraint.
    # [START distance_constraint]
    dimension_name = 'Distance'
    routing.AddDimension(
        transit_callback_index,
        0,  # no slack
        2000,  # vehicle maximum travel distance
        True,  # start cumul to zero
        dimension_name)
    distance_dimension = routing.GetDimensionOrDie(dimension_name)
    distance_dimension.SetGlobalSpanCostCoefficient(100)
    # [END distance_constraint]

    # Setting first solution heuristic.
    # [START parameters]
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
    # [END parameters]

    # Solve the problem.
    # [START solve]
    solution = routing.SolveWithParameters(search_parameters)
    # [END solve]

    # Print solution on console.
    # [START print_solution]
    if solution:
        print_solution(data, manager, routing, solution)
コード例 #28
0
    lats=df.latitude.values, lons=df.longitude.values, unit='mi')
vehicles = [26]*len(distances)
demand = np.insert(df.pallets.values, 0, 0)

# scripting ortools model construction & method.
manager = pywrapcp.RoutingIndexManager(len(distances), len(vehicles), 0)

def distance_callback(i:int, j:int):
    """index of from (i) and to (j)"""
    node_i = manager.IndexToNode(i)
    node_j = manager.Inde-xToNode(j)
    
    return distances[node_i][node_j]

# model construction
model = pywrapcp.RoutingModel(manager)
model.SetArcCostEvaluatorOfAllVehicles(
    model.RegisterTransitCallback(distance_callback)
)

def demand_callback(i:int):
    """capacity constraint"""
    node = manager.IndexToNode(i)
    
    return demand[node]

model.AddDimensionWithVehicleCapacity(
    # function which return the load at each location (cf. cvrp.py example)
    model.RegisterUnaryTransitCallback(demand_callback),
    
    0, # null capacity slack
コード例 #29
0
def VRP(rides, no_vehicles, finish_time):

    rides.insert(0, Ride(-1, 0, 0, 0, 0, 0, 5))

    time_matrix = [[0 for i in range(len(rides))] for i in range(len(rides))]

    for i in range(len(rides)):
        for j in range(len(rides)):
            time_matrix[i][j] = get_length(i, j, rides)

    times = []
    for ride in rides:
        times.append((ride.s, ride.f))

    depot = 0

    manager = pywrapcp.RoutingIndexManager(len(time_matrix), no_vehicles,
                                           depot)
    routing = pywrapcp.RoutingModel(manager)

    def time_callback(from_index, to_index):
        from_node = manager.IndexToNode(from_index)
        to_node = manager.IndexToNode(to_index)
        return time_matrix[from_node][to_node]

    transit_callback_index = routing.RegisterTransitCallback(time_callback)
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)

    routing.AddDimension(transit_callback_index, int(finish_time / 4),
                         2 * finish_time, False, "Time")  # What do these mean?
    time_dimension = routing.GetDimensionOrDie("Time")

    for location_idx, time_window in enumerate(times):
        if location_idx == 0:
            continue
        index = manager.NodeToIndex(location_idx)
        time_dimension.CumulVar(index).SetRange(time_window[0], time_window[1])

    for vehicle_id in range(no_vehicles):
        index = routing.Start(vehicle_id)
        time_dimension.CumulVar(index).SetRange(times[0][0], times[0][1])

    for i in range(no_vehicles):
        routing.AddVariableMinimizedByFinalizer(
            time_dimension.CumulVar(routing.Start(i)))
        routing.AddVariableMinimizedByFinalizer(
            time_dimension.CumulVar(routing.End(i)))

    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

    print("SOLVING")

    solution = routing.SolveWithParameters(search_parameters)

    if not solution:
        return False, [], 0

    vehicles_routes = [[] for i in range(no_vehicles)]

    time_dimension = routing.GetDimensionOrDie('Time')
    max_time = 0
    for vehicle_id, stops in enumerate(vehicles_routes):
        index = routing.Start(vehicle_id)
        while not routing.IsEnd(index):
            stops.append(manager.IndexToNode(index))
            index = solution.Value(routing.NextVar(index))
        max_time = max(max_time, solution.Min(time_dimension.CumulVar(index)))

    for i in range(len(vehicles_routes)):
        vehicles_routes[i] = vehicles_routes[i][1:]
        for j in range(len(vehicles_routes[i])):
            vehicles_routes[i][j] -= 1

    print(vehicles_routes, max_time)

    return True, vehicles_routes, max_time  # vehicles routes is shape (no. vehicles, no. stops for vehicle)
コード例 #30
0
ファイル: vrp.py プロジェクト: liuyonggg/csp
def main():
    # Create the data.
    data = create_data_array()
    locations = data[0]
    demands = data[1]
    num_locations = len(locations)
    depot = 0
    num_vehicles = 1

    # Create routing model.
    if num_locations > 0:

        # The number of nodes of the TSP is num_locations.
        # Nodes are indexed from 0 to num_locations - 1. By default the start of
        # a route is node 0.
        routing = pywrapcp.RoutingModel(num_locations, num_vehicles)
        search_parameters = pywrapcp.RoutingModel.DefaultSearchParameters()

        # Setting first solution heuristic: the
        # method for finding a first solution to the problem.
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

        # The 'PATH_CHEAPEST_ARC' method does the following:
        # Starting from a route "start" node, connect it to the node which produces the
        # cheapest route segment, then extend the route by iterating on the last
        # node added to the route.

        # Put a callback to the distance function here. The callback takes two
        # arguments (the from and to node indices) and returns the distance between
        # these nodes.

        dist_between_locations = CreateDistanceCallback(locations)
        dist_callback = dist_between_locations.Distance
        routing.SetArcCostEvaluatorOfAllVehicles(dist_callback)

        # Put a callback to the demands.
        demands_at_locations = CreateDemandCallback(demands)
        demands_callback = demands_at_locations.Demand

        # Adding capacity dimension constraints.
        vehicle_capacity = 10000
        null_capacity_slack = 0
        fix_start_cumul_to_zero = True
        capacity = "Capacity"
        routing.AddDimension(demands_callback, null_capacity_slack,
                             vehicle_capacity, fix_start_cumul_to_zero,
                             capacity)

        routing.SetDepot(depot)

        # Solve, displays a solution if any.
        assignment = routing.SolveWithParameters(search_parameters)
        if assignment:
            # Display solution.

            for vehicle_nbr in range(num_vehicles):
                index = routing.Start(vehicle_nbr)
                index_next = assignment.Value(routing.NextVar(index))
                route = ''
                route_dist = 0
                route_demand = 0

                while not routing.IsEnd(index_next):
                    node_index = routing.IndexToNode(index)
                    node_index_next = routing.IndexToNode(index_next)
                    route += str(node_index) + " -> "
                    # Add the distance to the next node.
                    route_dist += dist_callback(node_index, node_index_next)
                    # Add demand.
                    route_demand += demands[node_index]
                    index = index_next
                    index_next = assignment.Value(routing.NextVar(index))

                node_index = routing.IndexToNode(index)
                node_index_next = routing.IndexToNode(index_next)
                route += str(node_index) + " -> " + str(node_index_next)
                route_dist += dist_callback(node_index, node_index_next)
                print "Route for vehicle " + str(
                    vehicle_nbr) + ":\n\n" + route + "\n"
                print "Distance of route " + str(vehicle_nbr) + ": " + str(
                    route_dist)
                print "Demand met by vehicle " + str(vehicle_nbr) + ": " + str(
                    route_demand) + "\n"
        else:
            print 'No solution found.'
    else:
        print 'Specify an instance greater than 0.'