I found code for the traveling salesman algorithm in python. But I want a different version, where the salesman will not return to the starting position. The path should be the shortest. Please suggest the solution.
I also tried the Held-Karp algorithm (this uses dynamic programming to solve TSP), but it returns a path that is not the shortest.
import json
import flask
import numpy as np
from flask import request, jsonify
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp
app = flask.Flask(__name__)
app.config["DEBUG"] = True
def create_data_model(distance_input_matrix):
"""Stores the data for the problem."""
data = {'distance_matrix': distance_input_matrix, 'num_vehicles': 1, 'depot': 0}
return data
def print_solution(manager, routing, solution):
"""Prints solution on console."""
# print('Objective: {} miles'.format(solution.ObjectiveValue()))
index = routing.Start(0)
# plan_output = 'Route for vehicle 0:\n'
plan_output = ''
route_distance = 0
while not routing.IsEnd(index):
plan_output += '{}->'.format(manager.IndexToNode(index))
previous_index = index
index = solution.Value(routing.NextVar(index))
route_distance += routing.GetArcCostForVehicle(previous_index, index, 0)
plan_output += '{}'.format(manager.IndexToNode(index))
return plan_output
# print(plan_output)
# plan_output += 'Route distance: {}miles\n'.format(route_distance)
def main(distance_input_matrix=None):
"""Entry point of the program."""
# Instantiate the data problem.
data = create_data_model(distance_input_matrix)
# 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:
return print_solution(manager, routing, solution)
@app.route('/', methods=['GET'])
def home():
return main()
@app.route('/optimize', methods=['POST'])
def optimize():
if request.json:
data_matrix = request.json['data']
narrows = len(data_matrix) # 3 rows in your example
narcs = len(data_matrix[0])
a = np.zeros((narrows + 1, narcs + 1), dtype='int32').tolist()
for i in range(len(data_matrix)):
for j in range(len(data_matrix[i])):
a[i][j] = data_matrix[i][j]
#result = main(a)
result = main(data_matrix)
r_l = result.split('->')
#r_l.remove(str(narrows))
return jsonify({'data': r_l})
app.run()
I also tried to add a new location which is at zero distance from all the existing points. Then solved it using TSP, and then removed the point. But it didn't give the correct result either.