Tuesday, 27 April 2021

Travel Sales man algorithm without returning to the starting point

Hi i have found the travelling salesman algorithm in python. But i want a different version where salesman will not return to the starting position. The path should be the shortest. Please suggest the solution. I also tried the Held-Karp (this uses dynamic programming to solve TSP) but it also returning the wrong result. The path is not the shortest. Thanks.

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

The another approach I tried to add a new location which is at zero distance from all the existing points. Solve it using TSP and remove the point. But it also didn't give the correct result.



from Travel Sales man algorithm without returning to the starting point

No comments:

Post a Comment