Ejemplo n.º 1
0
def vrp_script(data, company_list, params, printer=False):
    # Create the routing index manager.
    manager = pywrapcp.RoutingIndexManager(len(data['distance_matrix']),
                                           data['num_vehicles'], data['depot'])

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

    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)

        # data['demands'] adds the loading time to the travel time
        return (data['loadtimes'][from_node] *
                60) + data['distance_matrix'][from_node][to_node]

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

    transit_callback_index = routing.RegisterTransitCallback(time_callback)

    # Define cost of each arc.
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
    time = 'Time'
    routing.AddDimension(
        transit_callback_index,
        500,  # allow waiting time
        14400,  # 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])
    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.AUTOMATIC)
    #GEBRUIK NU PATH_MOST_CONSTRAINED_ARC

    # sets the time limit in seconds
    search_parameters.time_limit.seconds = 5

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

    if assignment:
        if printer == True:
            list_of_routes, time = pt.print_solution(data, manager, routing,
                                                     assignment, company_list)
        else:
            list_of_routes, time = pt.create_list_of_routes(
                data, manager, routing, assignment, company_list)
        return list_of_routes, time

    return 0, 0
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
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 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')

    # Add Distance constraint.
    dimension_name = 'Distance'
    routing.AddDimension(
        transit_callback_index,
        0,  # no slack
        3500,  # 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 wit time limit if solution not found
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.time_limit.seconds = 5
    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)
Ejemplo n.º 4
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)

#  ADD THE DISTANCE CALLBACK
    # ADD THE DEMAND CALLBACK AND CAPACITY COSTRAINTS
    # In addition to the distance callback, the solver also requires a demand callback, 
    # which returns the demand at each location, and a dimension for the capacity constraints.
    
    # 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)

#!!! NB
    # Unlike the distance callback, which takes a pair of locations as inputs, 
    # the demand callback only depends on the location (from_node) of the delivery.
    # The code also creates a dimension for capacities, we use the AddDimensionWithVehicleCapacity method, 
    # which takes a vector of capacities.
    # Since all the vehicle capacities in this example are the same, you could use the the 
    # AddDimension method, which takes a single upper bound for all vehicle quantities. 
    # But AddDimensionWithVehicleCapacity handles the more general case in which different 
    # vehicles have different capacities.
    
    # 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, modify it if you accept unmet demand
        data['vehicle_capacities'],  # vehicle maximum capacities set by the user
        True,  # start cumul to zero
        'Capacity')
    
    # you can find other research method here:
    # https://developers.google.com/optimization/routing/routing_options
    
    # Setting first solution heuristic:
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
#    search_parameters.first_solution_strategy = (
#        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

    # Setting metaheuristic search method:
    search_parameters.local_search_metaheuristic = (
        routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
    # Setting time limit to the method
    search_parameters.time_limit.seconds = 30
    
    # Solve the problem.
    assignment = routing.SolveWithParameters(search_parameters)

    # Search status 
    print('\n')
    solver_index = routing.status()
    description = ['ROUTING_NOT_SOLVED','ROUTING_SUCCESS','ROUTING_FAIL',
                   'ROUTING_FAIL_TIMEOUT','ROUTING_INVALID']
    print("Solver status:",description[solver_index],'\n')
    
    # Print solution on console.
    if assignment:
        print_solution(data, manager, routing, assignment)
Ejemplo n.º 5
0
    def optimize(self):
        # find max z:
        maxZTarget = 0
        units = None
        for line in self.data.gcode:
            line = stripComments(line)
            gString = line[line.find("G"): line.find("G") + 3]
            if gString == "G21":
                if units is not None and units != "G21":
                    print("Error, units switch in file")
                    return False
                units = "G21"
            if gString == "G20":
                if units is not None and units != "G20":
                    print("Error, units switch in file")
                    return False
                units = "G20"
            if gString == "G00" or gString == "G0 ": #found G0/G00
                zTarget = getZFromGCode(line)
                if zTarget is not None:
                    if float(zTarget) > float(maxZTarget):
                        maxZTarget = zTarget
        pathList = []
        inPath = False
        index = 0
        startLine = 0
        startX = None
        startY = None
        currentX = None
        currentY = None
        inHeader = True
        headerEnd = 0
        tool = 0
        toolList = [0]
        footerStart = 0
        #path list will hold the parsed gcode groups between G0 moves.
        for line in self.data.gcode:
            line = stripComments(line)
            tString = findInLine(line, "T", 2) # search for tool command
            if len(tString) > 1:
                toolVal = getNumberAfterCode(line, "T")
                toolVal = int(toolVal)
                print(line)
                print(toolVal)
                if toolVal != tool:
                    if inPath: #close off current path
                        endX = currentX
                        endY = currentY
                        pathList.append(
                            Path(x0=startX, y0=startY, x1=endX, y1=endY, startLine=startLine, finishLine=index, tool=tool))
                        #currentX, currentY = getXYFromGCode(line, currentX, currentY) #there won't be a currentX, currentY in this code
                        inPath = False
                    toolList.append(toolVal)
                    tool = toolVal
                    print("Current tool is now: "+str(tool))
            gString = findInLine(line, "G", 3)
            if True:
                if gString == "G00" or gString == "G0 ": #found G0/G00
                    if not inPath:
                        if currentX is None and currentY is None:
                            startX, startY = getXYFromGCode(line, currentX, currentY)
                            currentX = startX
                            currentY = startY
                            inHeader = False
                        else:
                            startX = currentX
                            startY = currentY
                            endX, endY = getXYFromGCode(line, currentX, currentY)
                            currentX = endX
                            currentY = endY
                            inHeader = False
                    else:
                        endX = currentX
                        endY = currentY
                        pathList.append(Path(x0=startX, y0=startY, x1=endX,y1=endY, startLine=startLine, finishLine=index, tool=tool))
                        currentX, currentY = getXYFromGCode(line, currentX, currentY)
                        inPath = False

                elif gString == "G01" or gString == "G1 " or gString == "G02" or gString == "G2 " or gString == "G03" or gString == "G3 ": #found G1/G01/G2/G02/G3/G03
                    endX, endY = getXYFromGCode(line, currentX, currentY)
                    if startX is None or startY is None:
                        headerEnd = index
                    else:
                        if not inPath:
                            startLine = index
                            startX = currentX
                            startY = currentY
                        if endX is None:
                            endX = startX
                        if endY is None:
                            endY = startY
                        currentX = endX
                        currentY = endY
                        inPath = True
                        inHeader = False
                else:
                    if inHeader:
                        headerEnd = index
            #print(line)
            #print(str(inPath)+"=>"+ str(startX) + ", " + str(startY)+" - "+str(currentX) + ", " + str(currentY))
            index = index + 1

        #print("last"+str(inPath)+"=>"+ str(startX) + ", " + str(startY)+" - "+str(currentX) + ", " + str(currentY))

        newGCode = []
        newGCode.append(units)
        for i in range(0, headerEnd+1):
            line = self.data.gcode[i]
            gString = line[line.find("G"): line.find("G") + 3]
            if gString != "G21" and gString != "G20": # don't setup units anymore
                newGCode.append(self.data.gcode[i])

        #repeat for each tool:
        print("ToolList")
        print(toolList)
        for tool in toolList:
            """Entry point of the program."""
            # Instantiate the data problem.
            newGCode.append("M6 T"+str(tool))
            data = create_data_model(pathList, tool)
            if len(data['locations']) > 0: #could be nulled out because first tool is not 0
                manager = pywrapcp.RoutingIndexManager(len(data['locations']), data['num_vehicles'], data['depot'])
                routing = pywrapcp.RoutingModel(manager)
                distance_matrix = compute_euclidean_distance_matrix(data['locations'])

                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 distance_matrix[from_node][to_node]

                transit_callback_index = routing.RegisterTransitCallback(distance_callback)
                routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
                search_parameters = pywrapcp.DefaultRoutingSearchParameters()
                search_parameters.first_solution_strategy = (
                    routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
                solution = routing.SolveWithParameters(search_parameters)
                if solution:
                    print_solution(manager, routing, solution)

                """Prints solution on console."""
                index = routing.Start(0)
                route_distance = 0
                while not routing.IsEnd(index):
                    pathIndex = manager.IndexToNode(index)
                    startLine = data['locations'][pathIndex][4]
                    finishLine = data['locations'][pathIndex][5]
                    newGCode.append("G0 Z" + str(maxZTarget))
                    newGCode.append("G0 X" + str(data['locations'][pathIndex][0]) + " Y" + str(data['locations'][pathIndex][1]))
                    line = self.data.gcode[startLine]
                    gString = line[line.find("G"): line.find("G") + 3]
                    if gString == "G01" or gString == "G1 ":  # found G0/G00
                        X, Y = getXYFromGCode(line, None, None)
                        if X is None and Y is None:
                            zTarget = getZFromGCode(line)
                            if float(zTarget) < 0:
                                newGCode.append("G0 Z0.5")
                    for i in range(startLine, finishLine):
                        newGCode.append(self.data.gcode[i])
                    previous_index = index
                    index = solution.Value(routing.NextVar(index))
                    route_distance += routing.GetArcCostForVehicle(previous_index, index, 0)
            else:
                print("No locations for tool"+str(tool))

        newGCode.append("G0 Z" + str(maxZTarget))
        newGCode.append("G0 X" + str(currentX) + " Y" + str(currentY))

        print('Objective: {} units\n'.format(solution.ObjectiveValue()/100))
        print('Path distance: {} units\n'.format(route_distance/100))

        '''
        for path in bestRoute:
            newGCode.append("G0 Z" + str(maxZTarget))
            newGCode.append("G0 X" + str(path.x0) + " Y" + str(path.y0))
            #print("G0 Z" + str(maxZTarget))
            #print("G0 X" + str(path.x0) + " Y" + str(path.y0))
            for i in range(path.startLine, path.finishLine ):
                newGCode.append(self.data.gcode[i])
                #print(self.data.gcode[i])
        '''
        finalGCode = ""
        for i in newGCode:
            finalGCode = finalGCode + i + "\n"
        self.data.actions.updateGCode(finalGCode)

        return True
Ejemplo n.º 6
0
    def optimize(self, data, manager, routing):
        def make_time_callbacks(vehicle_ind):
            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)
                result = data['time_matrices'][vehicle_ind][from_node][to_node]
                # print(
                # f"time_callback: from_node: {from_node}, to_node: {to_node}, result: {result}")
                return result

            return time_callback

        def make_cost_callback(vehicle_ind):
            def cost_callback(from_index, to_index):
                from_node = manager.IndexToNode(from_index)
                to_node = manager.IndexToNode(to_index)
                result = data["cost_matrixes"][vehicle_ind][from_node][to_node]
                # print(
                # f"cost_callback: from_node: {from_node}, to_node: {to_node}, result: {result}")
                return result

            return cost_callback

        def make_draft_callback(vehicle_ind):
            def draft_callback(to_index, from_index):

                # NON_CARGO_WEIGHT = 2500
                # dwt = 4000  # comes from vessel description
                # immersion_summer = 200000  # comes from vessel description
                # draft = 100  # comes from vessel description

                # if from_index == 0:
                #     # This gets hit multiple times
                #     print(f"hitting from_index_0, {vehicle_ind}")
                #     return data["vessel_empty_draft"][vehicle_ind]

                # if from_index == -1:
                #     print(
                #         f"setting the default draft: {vehicle_ind} to {data['vessel_empty_draft'][vehicle_ind]}")
                #     return data["vessel_empty_draft"][vehicle_ind]

                from_node = manager.IndexToNode(from_index)
                cargo = data["draft_demands"][from_node]
                # dwt = data["dwt"][vehicle_ind]
                immersion_summer = data["immersion_summer"][vehicle_ind]
                # draft = data["draft"][vehicle_ind]

                # cargo_capacity = dwt - NON_CARGO_WEIGHT
                # cargo_capacity_unused = cargo_capacity - cargo_on_board
                centimeter_change_in_draft = cargo / immersion_summer

                # This does not work because call back is called many times
                # if vehicle_ind not in self.vessel_draft_set:
                #     centimeter_change_in_draft += data["vessel_empty_draft"][vehicle_ind]
                #     self.vessel_draft_set[vehicle_ind] = True

                # print(
                # f"vehicle_ind: {vehicle_ind}: change in draft: {centimeter_change_in_draft}")

                return centimeter_change_in_draft

            return draft_callback

        def make_draft_callback_2(vehicle_ind):
            def draft_callback(to_index, from_index):

                to_node = manager.IndexToNode(to_index)
                cargo = data["draft_demands"][to_node]
                immersion_summer = data["immersion_summer"][vehicle_ind]
                centimeter_change_in_draft = cargo / immersion_summer

                return centimeter_change_in_draft

            return draft_callback

        def volume_demand_callback(from_index):
            """Returns the demand of the node."""
            # Convert from routing variable Index to demands NodeIndex.
            from_node = manager.IndexToNode(from_index)
            # print(f"volume demand: {data['volume_demands'][from_node]}")
            return data['volume_demands'][from_node]

        def weight_demand_callback(from_index):
            """Returns the demand of the node."""
            # Convert from routing variable Index to demands NodeIndex.
            from_node = manager.IndexToNode(from_index)
            # print(f"weight demand: {data['volume_demands'][from_node]}")
            return data['weight_demands'][from_node]

        # def draft_callback(from_index):
        #     from_node = manager.IndexToNode(from_index)
        #     cargo_on_board = data["weight_demands"][from_node]

        #     NON_CARGO_WEIGHT = 2500
        #     dwt = 4000  # comes from vessel description
        #     immersion_summer = 200000  # comes from vessel description
        #     draft = 100  # comes from vessel description

        #     cargo_capacity = dwt - NON_CARGO_WEIGHT
        #     cargo_capacity_unused = cargo_capacity - cargo_on_board
        #     centimeter_reduction_in_draft = cargo_capacity_unused / immersion_summer

        #     calculated_draft = draft - (0.01 * centimeter_reduction_in_draft)

        #     return calculated_draft

        time_callbacks = [
            make_time_callbacks(x) for x in range(data["num_vehicles"])
        ]

        cost_callbacks = [
            make_cost_callback(x) for x in range(data["num_vehicles"])
        ]

        draft_callbacks = [
            make_draft_callback(x) for x in range(data["num_vehicles"])
        ]

        draft_callbacks_2 = [
            make_draft_callback_2(x) for x in range(data["num_vehicles"])
        ]

        transit_callback_indexes = [
            routing.RegisterTransitCallback(cb) for cb in time_callbacks
        ]

        transit_callback_cost_indexes = [
            routing.RegisterTransitCallback(cb) for cb in cost_callbacks
        ]

        transit_callback_draft_indexes = [
            routing.RegisterTransitCallback(cb) for cb in draft_callbacks
        ]

        transit_callback_draft_2_indexes = [
            routing.RegisterTransitCallback(cb) for cb in draft_callbacks_2
        ]

        for ind, cb_index in enumerate(transit_callback_cost_indexes):
            routing.SetArcCostEvaluatorOfVehicle(cb_index, ind)

        time_for_vehicles = "time_for_vehicles"

        routing.AddDimensionWithVehicleTransits(transit_callback_indexes, 10,
                                                10000, False,
                                                time_for_vehicles)

        cost_for_vehicles = "cost_for_vehicles"

        routing.AddDimensionWithVehicleTransits(transit_callback_cost_indexes,
                                                0, 10000, False,
                                                cost_for_vehicles)

        time_dimension = routing.GetDimensionOrDie(time_for_vehicles)

        if "draft_demands" in data:

            draft_for_vehicles = "draft_for_vehicles"
            routing.AddDimensionWithVehicleTransits(
                transit_callback_draft_indexes,
                0,
                1000,  # sets max draft any vessel can have
                True,
                draft_for_vehicles)

            draft_for_vehicles_2 = "draft_for_vehicles_2"

            routing.AddDimensionWithVehicleTransits(
                transit_callback_draft_2_indexes,
                0,
                1000,  # sets max draft any vessel can have
                True,
                draft_for_vehicles_2)

            draft_dimension = routing.GetDimensionOrDie(draft_for_vehicles)
            draft_dimension_2 = routing.GetDimensionOrDie(draft_for_vehicles_2)

        # Add capacity restraints
        volume_demand_callback_index = routing.RegisterUnaryTransitCallback(
            volume_demand_callback)

        routing.AddDimensionWithVehicleCapacity(
            volume_demand_callback_index,
            0,  # null capacity slack
            data['vehicle_volume_capacities'],  # vehicle maximum capacities
            True,  # start cumul to zero
            "volume")

        weight_demand_callback_index = routing.RegisterUnaryTransitCallback(
            weight_demand_callback)

        routing.AddDimensionWithVehicleCapacity(
            weight_demand_callback_index,
            0,  # null capacity slack
            data['vehicle_weight_capacities'],  # vehicle maximum capacities
            True,  # start cumul to zero
            "weight")

        weight_dimension = routing.GetDimensionOrDie("weight")

        for pickups_deliveries, vehicle_for_cargo in zip(
                data['pickups_deliveries'], data["vehicle_for_cargo"]):
            pickup, dropoff = pickups_deliveries

            pickup = manager.NodeToIndex(pickup)
            dropoff = manager.NodeToIndex(dropoff)

            routing.AddPickupAndDelivery(pickup, dropoff)
            if vehicle_for_cargo is not None:
                routing.solver().Add(
                    routing.VehicleVar(pickup) == vehicle_for_cargo)
                routing.solver().Add(
                    routing.VehicleVar(pickup) == routing.VehicleVar(dropoff))
            else:
                routing.solver().Add(
                    routing.VehicleVar(pickup) == routing.VehicleVar(dropoff))
            routing.solver().Add(
                time_dimension.CumulVar(pickup) <= time_dimension.CumulVar(
                    dropoff))

            if "draft_demands" in data:
                draft_dimension.CumulVar(pickup).SetMax(
                    data["port_max_draft"][pickup])
                draft_dimension_2.CumulVar(dropoff).SetMax(
                    data["port_max_draft"][dropoff])

        # add constraints on pickup and dropoff locations
        for pickup_dropoff, time_window, load_and_dropoff_times in zip(
                data["pickups_deliveries"], data["time_windows"],
                data["load_and_dropoff_times"]):
            pickup = pickup_dropoff[0]
            dropoff = pickup_dropoff[1]
            load_time = load_and_dropoff_times["load"]
            dropoff_time = load_and_dropoff_times["dropoff"]

            start_load, end_load = time_window["load_window"]
            start_dropoff, end_dropoff = time_window["dropoff_window"]

            # I think this does what it is supposed to do, but it is also slow
            # routing.solver().Add(time_dimension.CumulVar(pickup) >= (start_load + load_time))
            # routing.solver().Add(time_dimension.CumulVar(pickup) < end_load)

            # routing.solver().Add(time_dimension.CumulVar(dropoff) >= start_dropoff)
            # routing.solver().Add(time_dimension.CumulVar(
            #     dropoff) < (end_dropoff - dropoff_time))

            time_dimension.CumulVar(pickup).SetRange(start_load + load_time,
                                                     end_load)
            time_dimension.CumulVar(dropoff).SetRange(
                start_dropoff, end_dropoff - dropoff_time)

        # This allows for incomplete solutuon,
        for node in range(1, len(data['distance_matrix'])):
            routing.AddDisjunction([manager.NodeToIndex(node)], 1000)

        # Just testing minStart and minEnd

        # It looks like it is working

        # vehicle_index = routing.Start(0)
        # time_dimension.CumulVar(vehicle_index).SetRange(0, 20)
        # routing.AddToAssignment(time_dimension.SlackVar(vehicle_index))

        # end testing minStart and min End

        # for pv in data["port_to_allowed_vehicles"]:
        #     index = manager.NodeToIndex(pv["port"])
        #     routing.VehicleVar(index).SetValues([-1] + pv["vehicles"])

        # for ind, start_time in enumerate(data["vehicle_starting_time"]):
        #     index = routing.Start(ind)
        #     time_dimension.CumulVar(index).SetRange(start_time, start_time)
        #     routing.AddToAssignment(time_dimension.SlackVar(index))

        for i in range(data['num_vehicles']):
            routing.AddVariableMinimizedByFinalizer(
                time_dimension.CumulVar(routing.Start(i)))
            routing.AddVariableMinimizedByFinalizer(
                time_dimension.CumulVar(routing.End(i)))

        search_parameters = pywrapcp.DefaultRoutingSearchParameters()

        # PARALLEL_CHEAPEST_INSERTION is faster, but not finding the solution...

        search_parameters.first_solution_strategy = (
            self.first_solution_strategy)
        # search_parameters.time_limit.seconds = 90
        # we can set a limit, but it won't guarantee to find a solution!
        # if time expires before we find first solution
        # we get nothing back
        search_parameters.solution_limit = self.solution_limit

        search_parameters.local_search_metaheuristic = (
            self.local_search_metaheuristic)

        # search_parameters.time_limit.seconds = None

        search_parameters.log_search = True

        assignment = routing.SolveWithParameters(search_parameters)

        if assignment:
            solution = get_solution(data, manager, routing, assignment)
            d_solution = dedummify(solution, data["dummy_to_ind"])

            return {"solution": solution, "d_solution": d_solution}
        else:
            print("NO SOLUTION FOUND!!!")
            return None
Ejemplo n.º 7
0
    def route_agents(self):
        """
        Using vehicle routing algorithm to determine near-optimal
        agent assignments by minimizing the total build time.

        Inputs: Nothing

        Returns: assignments
          assignments :: list of dicts
            Each element is one assignment with keys
              'agent' : the agent number
              'location' : where they are
              'arrive' : when they arrived
              'link' : the portal to which they throw a link
              'depart' : when they leave
        """
        #
        # If num_agents is 1, then we have a trivial problem because
        # the order is already set
        #
        if self.num_agents == 1:
            assignments = []
            for i in range(len(self.ordered_links)):
                if i == 0:
                    arrive = 0
                else:
                    arrive = (depart +
                              self.portals_dists[self.ordered_links[i - 1][0],
                                                 self.ordered_links[i][0]] //
                              _WALKSPEED)
                depart = arrive + _LINKTIME
                location = self.ordered_links[i][0]
                link = self.ordered_links[i][1]
                assignments.append({
                    'agent': 0,
                    'location': location,
                    'arrive': arrive,
                    'link': link,
                    'depart': depart
                })
            return assignments
        #
        # If the same origin appears multiple times sequentially, we
        # can remove the extras since the agent doesn't need to move.
        # Get that origin portal as well as the count of sequential
        # occurances
        #
        ordered_cut_origins, count_cut_origins = \
            zip(*[(x, len(list(y))) for x, y in
                  itertools.groupby(self.ordered_origins)])
        #
        # Create origins_dists matrix, which has the distances between
        # each origin portal in the correct order.
        #
        origins_dists = np.array(
            [[self.portals_dists[o1][o2] for o1 in ordered_cut_origins]
             for o2 in ordered_cut_origins])
        #
        # Optimize the agent routes. This is a vehicle routing
        # problem, with the constraint that each portal must be
        # visited in order.
        #
        # Since our agents can start and end at any portal, we add a
        # "dummy node" to the first row and column of origins_dists
        # that has a distance 0 to every other portal. Too, we cast
        # the distances between portals to an integer, which shouldn't
        # cause any problems since most (all?) portals are separated
        # by at least 1 meter.
        #
        origins_dists = np.hstack((np.zeros(
            (origins_dists.shape[0], 1)), origins_dists))
        origins_dists = np.vstack(
            (np.zeros(origins_dists.shape[1]), origins_dists))
        origins_dists = np.array(origins_dists, dtype=np.int)
        #
        # Create the routing index manager
        # Set starting and ending locations to index 0 for the dummy
        # depot
        #
        manager = pywrapcp.RoutingIndexManager(len(origins_dists),
                                               self.num_agents, 0)
        #
        # Create the routing model
        #
        routing = pywrapcp.RoutingModel(manager)
        #
        # Set the time callback
        #
        time_callback_index = routing.RegisterTransitCallback(
            functools.partial(time_callback(origins_dists, count_cut_origins),
                              manager))
        #
        # Set the cost function to minimize total time
        #
        routing.SetArcCostEvaluatorOfAllVehicles(time_callback_index)
        #
        # Add the total time as a dimension
        # 1000000 = can wait at each portal for a long time,
        # 1000000 = can take a long time to complete
        # False = do not start each agent at 0 time.
        #
        routing.AddDimension(time_callback_index, 1000000, 1000000, False,
                             'time')
        time_dimension = routing.GetDimensionOrDie('time')
        time_dimension.SetGlobalSpanCostCoefficient(100)
        #
        # Force order. If any of the links in the next group depend
        # on any of the links in this group, then the next group can't
        # be started until this one is finished. Otherwise, they can
        # be built at the same time.
        #
        for i in range(1, len(origins_dists) - 1):
            # N.B. node i corresponds to count_cut_origins[i-1] since
            # the later has no depot.
            this_index = manager.NodeToIndex(i)
            next_index = manager.NodeToIndex(i + 1)
            #
            # Get dependencies
            #
            this_link = int(np.sum(count_cut_origins[:i - 1]))
            this_size = count_cut_origins[i - 1]
            next_link = int(np.sum(count_cut_origins[:i]))
            next_size = count_cut_origins[i]
            for linki in range(this_link, this_link + this_size):
                for linkj in range(next_link, next_link + next_size):
                    if ((self.ordered_links[linki]
                         in self.ordered_links_depends[linkj])
                            or (self.ordered_links[linki][0]
                                in self.ordered_links_depends[linkj])):
                        # Dependency conflict
                        break
                else:
                    # No conflict yet
                    continue
                # Dependency conflict
                break
            else:
                # No conflict, so they can be started simultaneously
                routing.solver().Add((time_dimension.CumulVar(next_index) >=
                                      time_dimension.CumulVar(this_index)))
                continue
            # is a conflict, so next has to be after this is finished
            # and communicated
            routing.solver().Add(
                (time_dimension.CumulVar(next_index) >
                 (time_dimension.CumulVar(this_index) +
                  count_cut_origins[i - 1] * _LINKTIME + _COMMTIME)))
        #
        # Start immediately, and we're trying to minimize total time.
        #
        for i in range(self.num_agents):
            time_dimension.CumulVar(routing.Start(i)).SetRange(0, 0)
            routing.AddVariableMinimizedByFinalizer(
                time_dimension.CumulVar(routing.End(i)))
        #
        # Set search parameters, then close the model
        #
        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.solution_limit = self.max_route_solutions
        search_parameters.time_limit.seconds = self.max_route_runtime
        #search_parameters.log_search = True
        routing.CloseModelWithParameters(search_parameters)
        #
        # A naive initial solution is that agents alternate portals
        #
        naive_route = [
            list(range(1, len(origins_dists)))[i::self.num_agents]
            for i in range(self.num_agents)
        ]
        naive_solution = \
            routing.ReadAssignmentFromRoutes(naive_route, True)
        #
        # Solve with initial solution
        #
        solution = routing.SolveFromAssignmentWithParameters(
            naive_solution, search_parameters)
        if not solution:
            raise ValueError("No valid assignments found")
        #
        # Package results
        #
        assignments = []
        for agent in range(self.num_agents):
            #
            # Loop over all assignments, except first (dummy depot)
            #
            index = routing.Start(agent)
            index = solution.Value(routing.NextVar(index))
            while not routing.IsEnd(index):
                node = manager.IndexToNode(index)
                #
                # Get time agent arrives at this node
                #
                arrive = solution.Min(time_dimension.CumulVar(index))
                #
                # Node is index in origins_dists, which corresponds
                # to index-1 in ordered_cut_origins since
                # ordered_cut_origins doesn't have depot. This is
                # related to the index in ordered_links via
                #
                linki = int(np.sum(count_cut_origins[:node - 1]))
                #
                # Loop over all links starting now at this origin
                #
                for i in range(linki, linki + count_cut_origins[node - 1]):
                    #
                    # add link time. Final link at this origin
                    # includes communication time
                    #
                    location = self.ordered_links[i][0]
                    link = self.ordered_links[i][1]
                    depart = arrive + _LINKTIME
                    assignments.append({
                        'agent': agent,
                        'location': location,
                        'arrive': arrive,
                        'link': link,
                        'depart': depart
                    })
                    arrive = depart
                #
                # Get next index and move on
                #
                index = solution.Value(routing.NextVar(index))
        #
        # Sort assignments by arrival time
        #
        assignments = sorted(assignments, key=lambda k: k['arrive'])
        return assignments
Ejemplo n.º 8
0
def optimize(inst, capacity):
    def create_data_model(inst, capacity):
        data = {}
        data['distance_matrix'] = inst.distances
        data['demands'] = inst.demands
        data['vehicle_capacities'] = [capacity] * inst.size
        data['num_vehicles'] = sum(inst.demands)
        data['depot'] = 0
        return data

    def get_routes(solution, routing, manager):
        """Get vehicle routes from a solution and store them in an array."""
        # Get vehicle routes and store them in a two dimensional array whose
        # i,j entry is the jth location visited by vehicle i along its route.
        routes = []
        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 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]

    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]

    # --- RUN PROGRAM ---

    # Zero cost if no demands
    if all(dem == 0 for dem in inst.demands):
        return [[]]

    # Set up data model
    data = create_data_model(inst, capacity)

    # 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
    transit_callback_index = routing.RegisterTransitCallback(distance_callback)

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

    # Add capacity constraint
    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)
    all_routes = get_routes(solution, routing, manager)
    nonempty_routes = [route for route in all_routes if not all(i == 0 for i in route)]

    # Remove the depot from the optimal routes
    parsed_routes = [route[1:-1] for route in nonempty_routes]

    return parsed_routes
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
def main(input,
         time=None,
         solution_limit=None,
         lns_time=None,
         penalty=None,
         log_search=bool,
         first_solution_method=None,
         second_solution_method=None):
    """Entry point of the program."""
    # Instantiate the data problem.
    data = create_data_madel(input)

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

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

    add_distance_callback(routing, manager, data)

    if penalty != None:
        for node in range(1, len(data['distance_matrix'])):
            routing.AddDisjunction([manager.NodeToIndex(node)], penalty)

    search_parameters = pywrapcp.DefaultRoutingSearchParameters()

    if solution_limit != None:
        search_parameters.solution_limit = solution_limit

    if time != None:
        search_parameters.time_limit.seconds = time

    if lns_time != None:
        search_parameters.lns_time_limit.seconds = lns_time

    # Setting first solution heuristic.

    if first_solution_method == 'PATH_CHEAPEST_ARC':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
    elif first_solution_method == 'SAVINGS':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.SAVINGS)
    elif first_solution_method == 'SWEEP':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.SWEEP)
    elif first_solution_method == 'CHRISTOFIDES':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.CHRISTOFIDES)
    elif first_solution_method == 'BEST_INSERTION':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.BEST_INSERTION)
    elif first_solution_method == 'PARALLEL_CHEAPEST_INSERTION':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION
        )
    elif first_solution_method == 'FIRST_UNBOUND_MIN_VALUE':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.FIRST_UNBOUND_MIN_VALUE)
    elif first_solution_method == 'LOCAL_CHEAPEST_ARC':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.LOCAL_CHEAPEST_ARC)
    elif first_solution_method == 'GLOBAL_CHEAPEST_ARC':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.GLOBAL_CHEAPEST_ARC)
    elif first_solution_method == 'AUTOMATIC':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.AUTOMATIC)
    elif first_solution_method == 'LOCAL_CHEAPEST_INSERTION':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.LOCAL_CHEAPEST_INSERTION)
    elif first_solution_method == 'ALL_UNPERFORMED':
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.ALL_UNPERFORMED)
    elif first_solution_method == 'GREEDY_DESCENT':
        search_parameters.local_search_metaheuristic = (
            routing_enums_pb2.LocalSearchMetaheuristic.GREEDY_DESCENT)

    if second_solution_method == 'TABU_SEARCH':
        search_parameters.local_search_metaheuristic = (
            routing_enums_pb2.LocalSearchMetaheuristic.TABU_SEARCH)
    elif second_solution_method == 'GUIDED_LOCAL_SEARCH':
        search_parameters.local_search_metaheuristic = (
            routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
    elif second_solution_method == 'SIMULATED_ANNEALING':
        search_parameters.local_search_metaheuristic = (
            routing_enums_pb2.LocalSearchMetaheuristic.SIMULATED_ANNEALING)
    elif second_solution_method == 'OBJECTIVE_TABU_SEARCH':
        search_parameters.local_search_metaheuristic = (
            routing_enums_pb2.LocalSearchMetaheuristic.OBJECTIVE_TABU_SEARCH)
    elif second_solution_method == 'GREEDY_DESCENT':
        search_parameters.local_search_metaheuristic = (
            routing_enums_pb2.LocalSearchMetaheuristic.GREEDY_DESCENT)
    elif second_solution_method == 'AUTOMATIC':
        search_parameters.local_search_metaheuristic = (
            routing_enums_pb2.LocalSearchMetaheuristic.AUTOMATIC)

    if log_search == True:
        search_parameters.log_search = True

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

    # Print solution on console.
    routes = get_routes(data, solution, routing, manager)

    if solution:
        return routes
Ejemplo n.º 11
0
    def dispatch_jobs_1_cluster(self):
        cluster_begin_time = datetime.now()

        # Create and register a transit callback.

        def distance_callback(from_index, to_index):
            # Convert from routing variable Index to distance matrix NodeIndex.
            from_node = manager.IndexToNode(from_index)  # - 1
            to_node = manager.IndexToNode(to_index)  # - 1

            if from_node == to_node:
                return 0
            return self._get_travel_time_2locations(
                self.cluster_list[from_node][1:3],
                self.cluster_list[to_node][1:3])

        self.distance_callback_func = distance_callback
        # Create the routing index manager.
        manager = pywrapcp.RoutingIndexManager(len(self.cluster_list), 1, 0)

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

        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
            900,  # 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()
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
        search_parameters.log_search = True
        search_parameters.time_limit.seconds = self.config["max_exec_seconds"]

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

        cluster_total_time = datetime.now() - cluster_begin_time
        print(
            f"Algorithm Done. nbr workers: {len(self.worker_slots)}, nbr jobs: {len(self.cluster_list)}, Elapsed: {cluster_total_time}"
        )

        # Print solution on console.
        if solution:
            self.print_solution(manager, routing, solution)
            self.save_solution(manager, routing, solution)

        else:
            print(f"Failed on cluster")
Ejemplo n.º 12
0
def main():
    """Solve the CVRP problem."""
    # Instantiate the data problem.
    # [START data]
    num_locations = 20
    num_vehicles = 5
    depot = 0
    # [END data]

    # Create the routing index manager.
    # [START index_manager]
    manager = pywrapcp.RoutingIndexManager(num_locations, num_vehicles, 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 1

    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]

    # Setting first solution heuristic.
    # [START parameters]
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
    search_parameters.local_search_metaheuristic = (
        routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
    search_parameters.log_search = True
    search_parameters.time_limit.FromSeconds(10)
    # [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(manager, routing, solution)
Ejemplo n.º 13
0
    def routeMultiVehicle(self):
        '''

        Returns:

        '''
        """Entry point of the program."""
        # Instantiate the data problem.
        data = self.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.
        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
            999999999999,  # vehicle maximum travel distance
            True,  # start cumul to zero
            dimension_name)
        distance_dimension = routing.GetDimensionOrDie(dimension_name)
        distance_dimension.SetGlobalSpanCostCoefficient(self._span_cost_coeff)

        # 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()
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)

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

        if solution:
            ordered_indices = self.get_formatted_output(
                manager, routing, solution)

            route_solution_nonformatted = []
            ordered_coords = []
            route_solution = []
            for i in range(len(ordered_indices)):
                rsn_row = []
                oc_row = []
                for j in ordered_indices[i]:
                    rsn_row.append(self._addresses[j])
                    oc_row.append(self._coordinates[j])
                route_solution_nonformatted.append(rsn_row)
                ordered_coords.append(oc_row)
                route_solution.append(
                    basicrouter.maputil.getmappedaddresses(
                        rsn_row, self._apikey))

            self.output = (route_solution_nonformatted, ordered_coords,
                           ordered_indices, route_solution)
            return self.output

        else:
            raise Exception('No solution is found.')
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'],
                                           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)
Ejemplo n.º 15
0
    routing.AddVariableMinimizedByFinalizer(
        time_dimension.CumulVar(routing.Start(i)))
    routing.AddVariableMinimizedByFinalizer(
        time_dimension.CumulVar(routing.End(i)))
    # configure speedy clients
    for idx in data['speedy_idx']:
        index = manager.NodeToIndex(idx)
        capacity_dimension.SlackVar(index).SetValue(0)
        for vehicle_index in range(len(data['ends'])):
              end_index = routing.End(i)
              routing.solver().Add(
                     capacity_dimension.CumulVar(end_index) <= 
                     capacity_dimension.CumulVar(index) + 3)

#"""
nodes = []
for i in range(cars_start):
      nodes.append(routing.AddDisjunction([manager.NodeToIndex(i)],2147483647999))
search_parameters = pywrapcp.DefaultRoutingSearchParameters()
search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION)
#search_parameters.time_limit.seconds = 4
routing.SetArcCostEvaluatorOfAllVehicles(time_callback_index)
assignment = routing.SolveWithParameters(search_parameters)
if assignment:
   print_solution(manager,routing,assignment,data)
else:
   print('no solution')

#with open('data.json', 'w', encoding='utf-8') as f:
#    json.dump(data, f, ensure_ascii=False, indent=4)
Ejemplo n.º 16
0
def main():  # pylint: disable=too-many-locals,too-many-branches
    """Entry point of the program."""
    parser = argparse.ArgumentParser(description='Output VRP as svg image.')
    parser.add_argument('-tsp',
                        '--tsp',
                        action='store_true',
                        help='use 1 vehicle')
    parser.add_argument('-vrp',
                        '--vrp',
                        action='store_true',
                        help='use 4 vehicle')
    parser.add_argument('-gs',
                        '--global-span',
                        action='store_true',
                        help='use global span constraints')
    parser.add_argument('-c',
                        '--capacity',
                        action='store_true',
                        help='use capacity constraints')
    parser.add_argument('-r',
                        '--resources',
                        action='store_true',
                        help='use resources constraints')
    parser.add_argument('-dn',
                        '--drop-nodes',
                        action='store_true',
                        help='allow drop nodes (disjuntion constraints)')
    parser.add_argument('-tw',
                        '--time-windows',
                        action='store_true',
                        help='use time-window constraints')
    parser.add_argument('-se',
                        '--starts-ends',
                        action='store_true',
                        help='use multiple starts & ends')
    parser.add_argument('-pd',
                        '--pickup-delivery',
                        action='store_true',
                        help='use pickup & delivery constraints')
    parser.add_argument('-fifo',
                        '--fifo',
                        action='store_true',
                        help='use pickup & delivery FIFO Policy')
    parser.add_argument('-lifo',
                        '--lifo',
                        action='store_true',
                        help='use pickup & delivery LIFO Policy')
    parser.add_argument('-s',
                        '--solution',
                        action='store_true',
                        help='print solution')
    args = vars(parser.parse_args())

    # Instantiate the data problem.
    # [START data]
    data = DataModel(args)
    # [END data]

    if not args['solution']:
        # Print svg on cout
        printer = SVGPrinter(args, data)
        printer.print_to_console()
        return 0

    # Create the routing index manager.
    # [START index_manager]
    if args['starts_ends']:
        manager = pywrapcp.RoutingIndexManager(len(data.locations),
                                               data.num_vehicles, data.starts,
                                               data.ends)
    else:
        manager = pywrapcp.RoutingIndexManager(len(data.locations),
                                               data.num_vehicles, data.depot)
    # [END index_manager]

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

    # [END routing_model]

    # Register distance callback
    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]

    distance_callback_index = routing.RegisterTransitCallback(
        distance_callback)

    # Register time callback
    def time_callback(from_index, to_index):
        """Returns the manhattan distance travel time 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.time_matrix[from_node][to_node]

    time_callback_index = routing.RegisterTransitCallback(time_callback)

    # Register demands callback
    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)

    if args['time_windows'] or args['resources']:
        routing.SetArcCostEvaluatorOfAllVehicles(time_callback_index)
    else:
        routing.SetArcCostEvaluatorOfAllVehicles(distance_callback_index)

    if args['global_span'] or args['pickup_delivery']:
        dimension_name = 'Distance'
        routing.AddDimension(distance_callback_index, 0, 3000, True,
                             dimension_name)
        distance_dimension = routing.GetDimensionOrDie(dimension_name)
        distance_dimension.SetGlobalSpanCostCoefficient(100)

    if args['capacity'] or args['drop_nodes']:
        routing.AddDimensionWithVehicleCapacity(demand_callback_index, 0,
                                                data.vehicle_capacities, True,
                                                'Capacity')

    if args['drop_nodes']:
        # Allow to drop nodes.
        penalty = 1000
        for node in range(1, len(data.locations)):
            routing.AddDisjunction([manager.NodeToIndex(node)], penalty)

    if args['pickup_delivery']:
        dimension_name = 'Distance'
        routing.AddDimension(distance_callback_index, 0, 3000, True,
                             dimension_name)
        distance_dimension = routing.GetDimensionOrDie(dimension_name)
        distance_dimension.SetGlobalSpanCostCoefficient(100)
        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))
        if args['fifo']:
            routing.SetPickupAndDeliveryPolicyOfAllVehicles(
                pywrapcp.RoutingModel.PICKUP_AND_DELIVERY_FIFO)
        if args['lifo']:
            routing.SetPickupAndDeliveryPolicyOfAllVehicles(
                pywrapcp.RoutingModel.PICKUP_AND_DELIVERY_LIFO)

    if args['starts_ends']:
        dimension_name = 'Distance'
        routing.AddDimension(distance_callback_index, 0, 2000, True,
                             dimension_name)
        distance_dimension = routing.GetDimensionOrDie(dimension_name)
        distance_dimension.SetGlobalSpanCostCoefficient(100)

    time = 'Time'
    if args['time_windows'] or args['resources']:
        routing.AddDimension(time_callback_index, 30, 30, False, time)
        time_dimension = routing.GetDimensionOrDie(time)
        # Add time window constraints for each location except depot and 'copy' the
        # slack var in the solution object (aka Assignment) to print it.
        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])
            routing.AddToAssignment(time_dimension.SlackVar(index))
        # Add time window constraints for each vehicle start node and 'copy' the
        # slack var in the solution object (aka Assignment) to print it.
        for vehicle_id in range(data.num_vehicles):
            index = routing.Start(vehicle_id)
            time_window = data.time_windows[0]
            time_dimension.CumulVar(index).SetRange(time_window[0],
                                                    time_window[1])
            routing.AddToAssignment(time_dimension.SlackVar(index))

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

    if args['resources']:
        # Add resource constraints at the depot.
        time_dimension = routing.GetDimensionOrDie(time)
        solver = routing.solver()
        intervals = []
        for i in range(data.num_vehicles):
            # Add loading time at start of routes
            intervals.append(
                solver.FixedDurationIntervalVar(
                    time_dimension.CumulVar(routing.Start(i)),
                    data.vehicle_load_time, 'depot_interval'))
            # Add unloading time at end of routes.
            intervals.append(
                solver.FixedDurationIntervalVar(
                    time_dimension.CumulVar(routing.End(i)),
                    data.vehicle_unload_time, 'depot_interval '))

        depot_usage = [1 for i in range(data.num_vehicles * 2)]
        solver.AddConstraint(
            solver.Cumulative(intervals, depot_usage, data.depot_capacity,
                              'depot'))

    # Setting first solution heuristic (cheapest addition).
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    # pylint: disable=no-member
    if not args['pickup_delivery']:
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
    else:
        search_parameters.first_solution_strategy = (
            routing_enums_pb2.FirstSolutionStrategy.PARALLEL_CHEAPEST_INSERTION
        )

    search_parameters.local_search_metaheuristic = (
        routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
    search_parameters.time_limit.FromSeconds(2)

    # Solve the problem.
    assignment = routing.SolveWithParameters(search_parameters)
    # Print the solution.
    printer = SVGPrinter(args, data, manager, routing, assignment)
    printer.print_to_console()
    return 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.PARALLEL_CHEAPEST_INSERTION)
    search_parameters.local_search_metaheuristic = (
        routing_enums_pb2.LocalSearchMetaheuristic.TABU_SEARCH)
    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("Tabu search - Parallel cheapest insertion")

    plt.show()
Ejemplo n.º 18
0
def solve_CVRPTW_PD(data, solverParams: SolverParameters, priorities) -> [pywrapcp.RoutingIndexManager, pywrapcp.RoutingModel, pywrapcp.Assignment]:

    # 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 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['time_matrix'][from_node][to_node]

    transit_callback_index = routing.RegisterTransitCallback(distance_callback)

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

     # Add Time Windows constraint.
    time = 'Time'
    routing.AddDimension(
        transit_callback_index,
        30000,  # allow waiting time
        3000,  # 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(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])

    # 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 = solverParams.unServedDemandPenalty
    for node in range(1, len(data['time_matrix'])):
        routing.AddDisjunction([manager.NodeToIndex(node)], priorities[node-1])



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

     # Define Transportation Requests.
    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))
    
   

    # 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(solverParams.maxTimeLimitSecs)

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


    return [manager, routing, solution]
Ejemplo n.º 19
0
def main():
    """Solve the VRP with time windows."""
    # 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['time_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 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)
    # [END transit_callback]

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

    # Add Time Windows constraint.
    # [START time_windows_constraint]
    time = 'Time'
    routing.AddDimension(
        transit_callback_index,
        30,  # allow waiting time
        30,  # 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 == data['depot']:
            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.
    depot_idx = data['depot']
    for vehicle_id in range(data['num_vehicles']):
        index = routing.Start(vehicle_id)
        time_dimension.CumulVar(index).SetRange(
            data['time_windows'][depot_idx][0],
            data['time_windows'][depot_idx][1])
    # [END time_windows_constraint]

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

    # 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)
Ejemplo n.º 20
0
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
        3_000,  # vehicle maximum travel distance
        True,  # start cumul to zero
        dimension_name)
    distance_dimension = routing.GetDimensionOrDie(dimension_name)
    distance_dimension.SetGlobalSpanCostCoefficient(100)
    # [END distance_constraint]

    routing.AddConstantDimensionWithSlack(
        0,  # transit 0
        42 * 16,  # capacity: be able to store PEAK*ROUTE_LENGTH in worst case
        42,  # slack_max: to be able to store peak in slack
        True,  #  Fix StartCumulToZero not really matter here
        'One')
    dim_one = routing.GetDimensionOrDie('One')

    routing.AddConstantDimensionWithSlack(
        0,  # transit 0
        42 * 16,  # capacity: be able to have PEAK value in CumulVar(End)
        42,  # slack_max: to be able to store peak in slack
        True,  #  Fix StartCumulToZero YES here
        'Two')
    dim_two = routing.GetDimensionOrDie('Two')

    # force depot Slack to be cost since we don't have any predecessor...
    for v in range(manager.GetNumberOfVehicles()):
        start = routing.Start(v)
        dim_one.SlackVar(start).SetValue(data['cost'][0])
        routing.AddToAssignment(dim_one.SlackVar(start))

        dim_two.SlackVar(start).SetValue(data['cost'][0])
        routing.AddToAssignment(dim_two.SlackVar(start))

    # Step by step relation
    # Slack(N) = max( Slack(N-1) , cost(N) )
    solver = routing.solver()
    for node in range(1, 17):
        index = manager.NodeToIndex(node)
        routing.AddToAssignment(dim_one.SlackVar(index))
        routing.AddToAssignment(dim_two.SlackVar(index))
        test = []
        for v in range(manager.GetNumberOfVehicles()):
            previous_index = routing.Start(v)
            cond = routing.NextVar(previous_index) == index
            value = solver.Max(dim_one.SlackVar(previous_index),
                               data['cost'][node])
            test.append(cond * value)
        for previous in range(1, 17):
            previous_index = manager.NodeToIndex(previous)
            cond = routing.NextVar(previous_index) == index
            value = solver.Max(dim_one.SlackVar(previous_index),
                               data['cost'][node])
            test.append(cond * value)
        solver.Add(solver.Sum(test) == dim_one.SlackVar(index))

    # relation between dimensions, copy last node Slack from dim ONE to dim TWO
    for node in range(1, 17):
        index = manager.NodeToIndex(node)
        values = []
        for v in range(manager.GetNumberOfVehicles()):
            next_index = routing.End(v)
            cond = routing.NextVar(index) == next_index
            value = dim_one.SlackVar(index)
            values.append(cond * value)
        solver.Add(solver.Sum(values) == dim_two.SlackVar(index))

    # Should force all others dim_two slack var to zero...
    for v in range(manager.GetNumberOfVehicles()):
        end = routing.End(v)
        dim_two.SetCumulVarSoftUpperBound(end, 0, 1000)

    # Setting first solution heuristic.
    # [START parameters]
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
    search_parameters.local_search_metaheuristic = (
        routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
    # search_parameters.log_search = True
    search_parameters.time_limit.FromSeconds(5)
    # [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)
    else:
        print('No solution found !')
Ejemplo n.º 21
0
def solve_with_ortools(input_data):
# def solve_it(input_data):
    """Simple travelling salesman problem between cities."""

    """Stores the data for the problem."""
    lines = input_data.split('\n')
            
    nodeCount = int(lines[0])
            
    points = []
    for i in range(1, nodeCount+1):
        line = lines[i]
        parts = line.split()
        points.append(Point(float(parts[0]), float(parts[1])))

    data = {}
    data['distance_matrix'] = build_distance_matrix_from_input(points)
    # [
    #     [0, 2451, 713, 1018, 1631, 1374, 2408, 213, 2571, 875, 1420, 2145, 1972],
    #     [2451, 0, 1745, 1524, 831, 1240, 959, 2596, 403, 1589, 1374, 357, 579],
    #     [713, 1745, 0, 355, 920, 803, 1737, 851, 1858, 262, 940, 1453, 1260],
    #     [1018, 1524, 355, 0, 700, 862, 1395, 1123, 1584, 466, 1056, 1280, 987],
    #     [1631, 831, 920, 700, 0, 663, 1021, 1769, 949, 796, 879, 586, 371],
    #     [1374, 1240, 803, 862, 663, 0, 1681, 1551, 1765, 547, 225, 887, 999],
    #     [2408, 959, 1737, 1395, 1021, 1681, 0, 2493, 678, 1724, 1891, 1114, 701],
    #     [213, 2596, 851, 1123, 1769, 1551, 2493, 0, 2699, 1038, 1605, 2300, 2099],
    #     [2571, 403, 1858, 1584, 949, 1765, 678, 2699, 0, 1744, 1645, 653, 600],
    #     [875, 1589, 262, 466, 796, 547, 1724, 1038, 1744, 0, 679, 1272, 1162],
    #     [1420, 1374, 940, 1056, 879, 225, 1891, 1605, 1645, 679, 0, 1017, 1200],
    #     [2145, 357, 1453, 1280, 586, 887, 1114, 2300, 653, 1272, 1017, 0, 504],
    #     [1972, 579, 1260, 987, 371, 999, 701, 2099, 600, 1162, 1200, 504, 0],
    # ]  # yapf: disable
    data['num_vehicles'] = 1
    data['depot'] = 0

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

    def distance_callback(from_index, to_index):
        """Returns the distance between the two nodes."""
        # Convert from routing variable Index to distance matrix NodeIndex.
        from_node = manager.IndexToNode(from_index)
        to_node = manager.IndexToNode(to_index)
        return data['distance_matrix'][from_node][to_node]
    
    transit_callback_index = routing.RegisterTransitCallback(distance_callback)
    
    # Define cost of each arc.
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)
    
    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.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(manager, routing, solution)

    # print(solution)
    value = 0
    index = routing.Start(0)
    while not routing.IsEnd(index):
        newindex = solution.Value(routing.NextVar(index))
        value += length(points[manager.IndexToNode(index)],points[manager.IndexToNode(newindex)])
        index = newindex
    # print("value",value)
    
    # output_data = '%.2f' % solution.ObjectiveValue() + ' ' + str(0) + '\n'
    output_data = '%.2f' % value + ' ' + str(0) + '\n'
    index = routing.Start(0)
    route_distance = 0
    while not routing.IsEnd(index):
        sol = manager.IndexToNode(index)
        output_data += " " + str(sol)
        index = solution.Value(routing.NextVar(index))
    # output_data += ' '.join(map(str, solution))
    return output_data
Ejemplo n.º 22
0
def main():
    """Solve the CVRP problem."""
    # Instantiate the data problem.
    mode = int(
        input(
            "press 1 to run with default values, 2 to run with custom values \n enter your choice: "
        ))
    if (mode == 1):
        bus_cap = 32
        max_dist_veh = 100
        print(
            "Running with default values.\nbus capacity = 32, max vehicle distance = 100km"
        )
    if (mode == 2):
        bus_cap = int(input("Enter the capacity of each bus: "))
        max_dist_veh = int(
            input("enter the max vehicle distance a vehicle can travel: "))
    else:
        bus_cap = 32
        max_dist_veh = 100
        print(
            "incorrect option choosed, running with default values.\nbus capacity = 32, max vehicle distance = 100km"
        )
    data = create_data_model(bus_cap)

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

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

    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.local_search_metaheuristic = (
        routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
    search_parameters.time_limit.seconds = 10
    search_parameters.log_search = True

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

    # Print solution on console.
    if assignment:
        print_solution(data, manager, routing, assignment)
    else:
        print('NO SOLUTION')
Ejemplo n.º 23
0
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 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')
    # Allow to drop nodes.
    penalty = 1000
    for node in range(1, len(data['distance_matrix'])):
        routing.AddDisjunction([manager.NodeToIndex(node)], penalty)
    # [END capacity_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]
    assignment = routing.SolveWithParameters(search_parameters)
    # [END solve]

    # Print solution on console.
    # [START print_solution]
    if assignment:
        print_solution(data, manager, routing, assignment)
Ejemplo n.º 24
0
def solvemulti_nodistlim(data):
    """Solve the CVRP problem."""

    # 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.
    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
        #set to data['penalty'] since we do not want there to be an effective distance constraint
        data['penalty'],  # vehicle maximum travel distance
        True,  # start cumul to zero
        dimension_name)
    distance_dimension = routing.GetDimensionOrDie(dimension_name)

    #uncomment the below line to make the solver prioritize minimizing the maximum distance of any vehicle (we usually want to prioritize # nodes visited)
    #we want the max path length of any vehicle to be minimized in mapping applications where we must visit every node,
    #and assuming infinite battery swaps.
    distance_dimension.SetGlobalSpanCostCoefficient(100)

    #do NOT allow drops --> there should be no situation in which nodes are dropped.
    """
    penalty = data['penalty']
    for node in range(1, len(data['distance_matrix'])):
        routing.AddDisjunction([manager.NodeToIndex(node)], penalty)
    """

    # Setting first solution heuristic.
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.local_search_metaheuristic = (
        routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
    #search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
    #search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.PATH_MOST_CONSTRAINED_ARC)
    #search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.SAVINGS)
    #search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.SWEEP)
    search_parameters.time_limit.seconds = 20
    search_parameters.solution_limit = 200

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

    # Print solution on console.
    if solution:
        return manager, routing, solution

    else:
        return None, None, None
Ejemplo n.º 25
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)
Ejemplo n.º 26
0
def solveconnecteddepots(data):
    """Solve the CVRP problem."""
    # 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
        #set to data['max_distance'] if restricting distance of vehicle
        data['max_distance'],  # vehicle maximum travel distance
        True,  # start cumul to zero
        dimension_name)
    distance_dimension = routing.GetDimensionOrDie(dimension_name)

    #uncomment the below line to make the solver prioritize minimizing the maximum distance of any vehicle (we usually want to prioritize # nodes visited)
    #distance_dimension.SetGlobalSpanCostCoefficient(100)

    #allow drops --> penalty of dropping a node should be high EXCEPT FOR DEPOTS
    penalty = data['penalty']
    for node in range(data['num_depots'], len(data['distance_matrix'])):
        routing.AddDisjunction([manager.NodeToIndex(node)], penalty)

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

    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    #search_parameters.local_search_metaheuristic = (routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
    #search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.PATH_MOST_CONSTRAINED_ARC)
    #search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.SAVINGS)
    #search_parameters.first_solution_strategy = (routing_enums_pb2.FirstSolutionStrategy.SWEEP)
    search_parameters.time_limit.seconds = 10
    #search_parameters.solution_limit = 200

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

    # Print solution on console.
    if solution:
        return manager, routing, solution

    else:
        return None, None, None
Ejemplo n.º 27
0
def main():
    """Solve the VRP with time windows."""
    # 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['time_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 time_callback(from_index, to_index):
        """Returns the travel time + service 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] + data['service_time'][
            from_node]

    transit_callback_index = routing.RegisterTransitCallback(time_callback)
    # [END transit_callback]

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

    # Add Time Windows constraint.
    time = 'Time'
    routing.AddDimension(
        transit_callback_index,
        10,  # needed optional waiting time to place break
        180,  # maximum time per vehicle
        True,  # Force start cumul to zero.
        time)
    time_dimension = routing.GetDimensionOrDie(time)
    time_dimension.SetGlobalSpanCostCoefficient(10)

    # Breaks
    # [START break_constraint]
    # warning: Need a pre-travel array using the solver's index order.
    node_visit_transit = [0] * routing.Size()
    for index in range(routing.Size()):
        node = manager.IndexToNode(index)
        node_visit_transit[index] = data['service_time'][node]

    break_intervals = {}
    for v in range(data['num_vehicles']):
        break_intervals[v] = [
            routing.solver().FixedDurationIntervalVar(
                50,  # start min
                60,  # start max
                10,  # duration: 10 min
                False,  # optional: no
                f'Break for vehicle {v}')
        ]
        time_dimension.SetBreakIntervalsOfVehicle(
            break_intervals[v],  # breaks
            v,  # vehicle index
            node_visit_transit)
    # [END break_constraint]

    # Setting first solution heuristic.
    # [START parameters]
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC)
    search_parameters.local_search_metaheuristic = (
        routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH)
    #search_parameters.log_search = True
    search_parameters.time_limit.FromSeconds(2)
    # [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(manager, routing, solution)
    else:
        print('No solution found !')
Ejemplo n.º 28
0
def generate_planning(timeout,
                      verbose,
                      calculate_distance,
                      engineers=None,
                      car_locations=None,
                      work_items=None,
                      availabilities=None):
    """
    The main planning function. This function does the following:
        - Create a datamodel for the routing manager to reference.
        - Create a routing manager.
        - Add constraints based on business rules.
        - Calculate an optimal solution withing a given timeframe.
        - Log the solution.
        - Returns a list of engineers and workitems.
    :return:
    """
    print("Timeout set to", timeout)
    print('Creating datamodel')
    data_model = create_data_model(engineers, car_locations, work_items,
                                   availabilities)

    print('Creating manager')
    manager = pywrapcp.RoutingIndexManager(data_model.number_of_nodes,
                                           data_model.number_of_engineers,
                                           data_model.start_positions,
                                           data_model.end_positions)

    routing = pywrapcp.RoutingModel(manager)

    print('Applying constraints')
    routing = DistanceConstraint().apply(manager, routing, data_model)
    routing = CapacityConstraint().apply(manager, routing, data_model)
    routing = PenaltyConstraint().apply(manager, routing, data_model)
    routing = IsAllowedToVisitConstraint().apply(manager, routing, data_model)

    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.local_search_metaheuristic = routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
    search_parameters.time_limit.seconds = timeout

    datetime.now().strftime("%H:%M:%S")
    print("date and time: ", datetime.now().strftime("%H:%M:%S"))

    def record_solution():
        print("date and time: ", datetime.now().strftime("%H:%M:%S"))
        print(routing.CostVar().Max())

    routing.AddAtSolutionCallback(record_solution)

    print('Calculating solutions')
    for i in range(0, 3):
        solution = routing.SolveWithParameters(search_parameters)
        # solution = routing.SolveFromAssignmentWithParameters(
        #    initial_solution, search_parameters)
        print(solution.ObjectiveValue())
        print('Solution calculated')
        if solution:
            print('Processing solution')
            planning = process_solution(data_model, manager, routing, solution,
                                        calculate_distance)
            if data_model.verify_planning(planning, solution):
                break
        else:
            print('No solution found')
            return [], [engineer['id'] for engineer in data_model.engineers], \
                   [work_item['id'] for work_item in data_model.work_items], {}

    return data_model.best_planning
Ejemplo n.º 29
0
def main():
    """Solve the VRP with time windows."""
    # 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['time_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 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)
    # [END transit_callback]

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

    # Add Time Windows constraint.
    # [START time_windows_constraint]
    time = 'Time'
    routing.AddDimension(
        transit_callback_index,
        60,  # allow waiting time
        60,  # 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
    # and 'copy' the slack var in the solution object (aka Assignment) to print it
    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])
        routing.AddToAssignment(time_dimension.SlackVar(index))
    # Add time window constraints for each vehicle start node
    # and 'copy' the slack var in the solution object (aka Assignment) to print it
    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])
        routing.AddToAssignment(time_dimension.SlackVar(index))
    # [END time_windows_constraint]

    # Add resource constraints at the depot.
    # [START depot_load_time]
    solver = routing.solver()
    intervals = []
    for i in range(data['num_vehicles']):
        # Add time windows at start of routes
        intervals.append(
            solver.FixedDurationIntervalVar(
                time_dimension.CumulVar(routing.Start(i)),
                data['vehicle_load_time'], 'depot_interval'))
        # Add time windows at end of routes.
        intervals.append(
            solver.FixedDurationIntervalVar(
                time_dimension.CumulVar(routing.End(i)),
                data['vehicle_unload_time'], 'depot_interval'))
    # [END depot_load_time]

    # [START depot_capacity]
    depot_usage = [1 for i in range(len(intervals))]
    solver.AddConstraint(
        solver.Cumulative(intervals, depot_usage, data['depot_capacity'],
                          'depot'))
    # [END depot_capacity]

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

    # 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]
    assignment = routing.SolveWithParameters(search_parameters)
    # [END solve]

    # Print solution on console.
    # [START print_solution]
    if assignment:
        print_solution(data, manager, routing, assignment)
    # [END print_solution]
    else:
        print('No solution found !')
Ejemplo n.º 30
0
def solve_it(input_data):
    # Modify this code to run your optimization algorithm

    # parse the input
    lines = input_data.split('\n')

    parts = lines[0].split()
    customer_count = int(parts[0])
    vehicle_count = int(parts[1])
    vehicle_capacity = int(parts[2])

    customers = []
    for i in range(1, customer_count + 1):
        line = lines[i]
        parts = line.split()
        customers.append(
            Customer(i - 1, int(parts[0]), float(parts[1]), float(parts[2])))

    #the depot is always the first customer in the input
    depot = customers[0]
    vehicle_tours = []
    outputData = ""

    print("nodes: %s" % customer_count)
    useGoogleVRPSolver = True
    timeLimit = 60
    solutionStrategy = routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC
    localSearchStrategy = routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
    if customer_count == 200:  #problem 5
        useGoogleVRPSolver = False
        #timeLimit = 18000
        #solutionStrategy = routing_enums_pb2.FirstSolutionStrategy.GLOBAL_CHEAPEST_ARC
        #localSearchStrategy = routing_enums_pb2.LocalSearchMetaheuristic.TABU_SEARCH
    elif customer_count == 101:  #problem 4
        timeLimit = 1800
    elif customer_count == 421:  #problem 6
        timeLimit = 1800

    if useGoogleVRPSolver == True:
        # Create the routing index manager.
        manager = pywrapcp.RoutingIndexManager(len(customers), vehicle_count,
                                               depot.index)

        # 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)
            #absLength = int(length(customers[from_node], customers[to_node])*100)
            #print("from: %s to %s = " %(from_node, to_node), end="")
            #print(absLength)
            return length(customers[from_node], customers[to_node]) * 100

        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]
            #print("customer %s = " %from_node, end="")
            #print(customers[from_node].demand)
            return customers[from_node].demand

        vehicleCap = [vehicle_capacity for i in range(vehicle_count)]
        #print(vehicleCap)
        demand_callback_index = routing.RegisterUnaryTransitCallback(
            demand_callback)
        routing.AddDimensionWithVehicleCapacity(
            demand_callback_index,
            0,  # null capacity slack
            vehicleCap,  # vehicle maximum capacities
            True,  # start cumul to zero
            'Capacity')

        # Setting first solution heuristic.
        search_parameters = pywrapcp.DefaultRoutingSearchParameters()
        search_parameters.first_solution_strategy = (solutionStrategy)
        search_parameters.local_search_metaheuristic = (localSearchStrategy)
        search_parameters.time_limit.seconds = timeLimit
        #search_parameters.lns_time_limit.seconds = 20
        search_parameters.log_search = False

        # Solve the problem.
        assignment = routing.SolveWithParameters(search_parameters)
        print("Solver status: ", routing.status())

        if assignment:
            vehicle_tours = print_solution(manager, routing, assignment,
                                           vehicle_count, customers)

        # calculate the cost of the solution; for each vehicle the length of the route
        obj = 0
        for v in range(0, vehicle_count):
            vehicle_tour = vehicle_tours[v]
            #print("Vehicle %s - " %v, end="")
            #print(vehicle_tour)
            if len(vehicle_tour) > 0:
                obj += length(depot, customers[vehicle_tour[0]])
                for i in range(0, len(vehicle_tour) - 1):
                    obj += length(customers[vehicle_tour[i]],
                                  customers[vehicle_tour[i + 1]])
                obj += length(customers[vehicle_tour[-1]], depot)

        # prepare the solution in the specified output format
        #print("Output")
        outputData = '%.2f' % obj + ' ' + str(0) + '\n'
        for v in range(0, vehicle_count):
            #outputData += str(depot.index) + ' ' + ' '.join([str(customer.index) for customer in vehicle_tours[v]]) + ' ' + str(depot.index) + '\n'
            v_tour = vehicle_tours[v]
            for node in range(0, len(v_tour)):
                outputData += str(v_tour[node]) + ' '
            outputData += "\n"

    # build a trivial solution
    # assign customers to vehicles starting by the largest customer demands
    #vehicle_tours = []
    #for v in range(0, vehicle_count):
    #    vehicle_tours.append([])
    #vehicle_tours[v].append(v)
    #print(vehicle_tours[v])

    else:
        remaining_customers = set(customers)
        remaining_customers.remove(depot)

        for v in range(0, vehicle_count):
            # print "Start Vehicle: ",v
            vehicle_tours.append([])
            capacity_remaining = vehicle_capacity
            #print("Vehicle %s " %v, end="")

            while sum([
                    capacity_remaining >= customer.demand
                    for customer in remaining_customers
            ]) > 0:
                used = set()
                order = sorted(remaining_customers,
                               key=lambda customer: -customer.demand)
                for customer in order:
                    if capacity_remaining >= customer.demand:
                        capacity_remaining -= customer.demand
                        vehicle_tours[v].append(customer)
                        # print '   add', ci, capacity_remaining
                        used.add(customer)
                remaining_customers -= used

    # checks that the number of customers served is correct
    #assert sum([len(v) for v in vehicle_tours]) == len(customers) - 1

    # calculate the cost of the solution; for each vehicle the length of the route
        obj = 0
        for v in range(0, vehicle_count):
            vehicle_tour = vehicle_tours[v]
            #print("Vehicle %s - " %v, end="")
            #print(vehicle_tour)
            if len(vehicle_tour) > 0:
                obj += length(depot, vehicle_tour[0])
                for i in range(0, len(vehicle_tour) - 1):
                    obj += length(vehicle_tour[i], vehicle_tour[i + 1])
                obj += length(vehicle_tour[-1], depot)

        # prepare the solution in the specified output format
        outputData = '%.2f' % obj + ' ' + str(0) + '\n'
        for v in range(0, vehicle_count):
            outputData += str(depot.index) + ' ' + ' '.join([
                str(customer.index) for customer in vehicle_tours[v]
            ]) + ' ' + str(depot.index) + '\n'

    return outputData