81 lines
2.5 KiB
Python
81 lines
2.5 KiB
Python
|
"""Simple Travelling Salesperson Problem (TSP) between cities."""
|
||
|
|
||
|
from ortools.constraint_solver import routing_enums_pb2
|
||
|
from ortools.constraint_solver import pywrapcp
|
||
|
|
||
|
|
||
|
def create_data_model():
|
||
|
"""Stores the data for the problem."""
|
||
|
data = {}
|
||
|
data["distance_matrix"] = [
|
||
|
[99, 2, 3, 1, 99, 99],
|
||
|
[99, 99, 99, 2, 2, 4],
|
||
|
[3, 99, 99, 2, 2, 99],
|
||
|
[1, 2, 99, 99, 99, 99],
|
||
|
[99, 99, 2, 2, 99, 1],
|
||
|
[99, 4, 3, 99, 1, 99],
|
||
|
]
|
||
|
data["num_vehicles"] = 1
|
||
|
data["depot"] = 0
|
||
|
return data
|
||
|
|
||
|
|
||
|
def print_solution(manager, routing, solution):
|
||
|
"""Prints solution on console."""
|
||
|
print(f"Objective: {solution.ObjectiveValue()} miles")
|
||
|
index = routing.Start(0)
|
||
|
plan_output = "Route for vehicle 0:\n"
|
||
|
route_distance = 0
|
||
|
while not routing.IsEnd(index):
|
||
|
plan_output += f" {manager.IndexToNode(index) + 1} ->"
|
||
|
previous_index = index
|
||
|
index = solution.Value(routing.NextVar(index))
|
||
|
route_distance += routing.GetArcCostForVehicle(previous_index, index, 0)
|
||
|
plan_output += f" {manager.IndexToNode(index)}\n"
|
||
|
plan_output += f"Route distance: {route_distance} miles\n"
|
||
|
print(plan_output)
|
||
|
|
||
|
|
||
|
def main():
|
||
|
"""Entry point of the program."""
|
||
|
# 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)
|
||
|
|
||
|
|
||
|
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)
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|