python - Python 中 TSP 的可扩展实现

标签 python

我有(比方说)100 分。我想在它们之间生成一条路径,越短越好。这是Travelling salesperson problem .自 TSP is NP-hard ,我对没有找到全局解决方案感到满意。我的方法可以快速提供解决方案并且可以很好地扩展。

生成示例点:

import numpy as np
points = np.random.RandomState(42).rand(100,2)

生成距离矩阵,其中 i,j 条目包含 point[i]point[j] 之间的距离。使用this回答:

z = np.array([[complex(*c) for c in points]]) # notice the [[ ... ]]
distance_matrix = abs(z.T-z)

我如何继续寻找至少具有局部最小路径长度的最短路径?


一些相关问题:

本主题:Travelling Salesman in scipy提供用于寻找 TSP 解决方案的代码。不过它以迭代方式工作,因此如果要访问的点数很大,脚本不会在合理的时间内生成解决方案。

本主题:How to solve the Cumulative Traveling Salesman Problem using or-tools in python?没有代码答案,也不关注经典 TSP。

本主题:Optimizing a Traveling Salesman Algorithm (Time Traveler Algorithm)为问题提供迭代解决方案(这意味着扩展性差)

最佳答案

这是一个基于 simulated annealing 的示例(pip install frigidum)。它很可能比其他解决方案慢。我希望发布的 Google OR 会更好,但由于它是一种不同的方法,因此可能会引起人们的兴趣(尽管是为了学习/教育)。

import numpy as np
import frigidum

from frigidum.examples import tsp

points = np.random.RandomState(42).rand(100,2)

tsp.nodes = points
tsp.nodes_count = points.shape[0]

z = np.array([[complex(*c) for c in points]]) # notice the [[ ... ]]
distance_matrix = abs(z.T-z)

tsp.dist_eu = distance_matrix

我们可以使用以下模拟退火方案(<30 秒); (为了获得更好的解决方案,让 alpha 更接近 .999,和/或以更长的计算成本增加 repeats)

local_opt = frigidum.sa(random_start=tsp.random_start,
           objective_function=tsp.objective_function,
           neighbours=[tsp.euclidian_bomb_and_fix, tsp.euclidian_nuke_and_fix, tsp.route_bomb_and_fix, tsp.route_nuke_and_fix, tsp.random_disconnect_vertices_and_fix],
           copy_state=frigidum.annealing.naked,
           T_start=5,
           alpha=.8,
           T_stop=0.001,
           repeats=10**2,
           post_annealing = tsp.local_search_2opt)

local_opt 是一个元组,其第一个元素是解决方案,第二个元素是目标值(路线长度)。最后它将输出统计信息和找到的最小值; (这不是绘制的那个)。

(Local) Minimum Objective Value Found: 
   7.46016765

我使用 zabop 绘图代码来绘制解决方案;

import matplotlib.pyplot as plt

plt.scatter(points[:,0],points[:,1])

route = local_opt[0]
for a, b in zip(route[:-1],route[1:]):
    x = points[[a,b]].T[0]
    y = points[[a,b]].T[1]
    plt.plot(x, y,c='r',zorder=-1)
plt.gca().set_aspect('equal')

https://i.imgur.com/rg9Fgzk.png https://imgur.com/rg9Fgzk

关于python - Python 中 TSP 的可扩展实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71196078/

相关文章:

python - 基于抽象基类捕获异常

python - python 3的主管?

python - 如何调整SVM的参数以获得更好的训练

python - 使用 Pyramid 返回 xlsxwriter 响应时的解码问题

Python 3.5 : slice vs islice vs alternatives? 效率对比

python - 在 Python 中绘制 3D 圆柱面图

python - 如何从嵌套列表中提取特定项目并附加到新列?

python - 如何删除以用户选择的字母开头的所有项目?

python - 关于 Monty Hall 问题的程序未返回预期结果

python - Django - 将用户设置为不活动 5 秒