【发布时间】:2021-07-18 05:41:28
【问题描述】:
您好,我在 python 中找到了旅行商算法。但我想要一个不同的版本,其中推销员不会回到起始位置。路径应该是最短的。请提出解决方案。我还尝试了 Held-Karp(它使用动态编程来解决 TSP),但它也返回了错误的结果。路径不是最短的。 谢谢。
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()
我尝试添加一个新位置的另一种方法,该位置与所有现有点的距离为零。使用 TSP 解决它并删除该点。但它也没有给出正确的结果。
【问题讨论】:
-
也许在运筹学 StackExchange 上问这个问题? or.stackexchange.com
-
添加虚拟位置应该是要走的路。你给程序提供了哪些输入,它输出了什么用于复制?