【问题标题】:How to improve my TSP implementation ? (Using Backtracking) (Python)如何改进我的 TSP 实施? (使用回溯)(Python)
【发布时间】:2021-07-24 10:31:14
【问题描述】:

我正在尝试使用回溯编写 TSP 问题的递归实现。

尝试了几次,但我刚刚完成它,它似乎工作。

但是速度有点慢,所以我想弄清楚如何改进它。


def search_best_route(distance_matrix):

    best_route = [None] * (len(distance_matrix[0]))
    route = best_route.copy()
    visited = [False] * (len(distance_matrix[0]))
    current_distance = 0
    return search_routes(0, route, best_route, -1,  -1, current_distance, distance_matrix, visited, 0)


def search_routes(start_index1, route, best_route, min_distance, best_distance, current_distance, distance_matrix, visited, last_visited):

    if start_index1 == len(route):

        current_distance += distance_matrix[last_visited][0]

        if current_distance < best_distance or best_distance == -1:

            best_distance = current_distance

            for k in range(0, len(route)):

                best_route[k] = route[k]

    else:

        for k in range(len(route)):

            if not visited[k]:

                new_min = min_distance - distance_matrix[last_visited][k]

                if new_min < best_distance or start_index1 == 0:

                    new_current_distance = current_distance + distance_matrix[last_visited][k]
                    route[start_index1] = k
                    visited[k] = True
                    best_distance = search_routes(start_index1 + 1, route, best_route, new_min, best_distance,
                                                  new_current_distance, distance_matrix, visited, k)[1]
                    visited[k] = False

    return best_route, best_distance


def build_distance_matrix(x, y):

    distance_matrix = [[0 for col in range(len(x))] for row in range(len(x))]

    for i in range(len(x)):

        for j in range(len(x)):

            distance_matrix[i][j] = ((x[i] - x[j]) ** 2 + (y[i] - y[j]) ** 2) ** 0.5

    return distance_matrix


n = int(input())
x = [None] * n
y = x.copy()

for i in range(n):

    x_y = input()
    x[i] = x_y.split()[0]
    y[i] = x_y.split()[1]

x = list(map(float, x))
y = list(map(float, y))

best_route = search_best_route(build_distance_matrix(x, y))
print("%.4f" % best_route[1])
print(' '.join(map(str, best_route[0])))

对不起,如果我做错了什么,而你看到这个会死在里面哈哈。

【问题讨论】:

    标签: python algorithm recursion backtracking


    【解决方案1】:

    可能会有所帮助的一个小改动是,您在每一步都在遍历整个路由列表。您可以通过维护尚未访问的点列表来节省 n 因子,就像递归排列枚举算法所做的那样。

    在纸面上,n 的因子可能看起来很多,但由于算法仍然是 Θ(n!),因此在相同的运行时间内,改进相当于多一个点。为了做得更好,您需要实现分支和绑定。

    基本的分支定界并不难实现,因为递归回溯已经是“分支”部分的大部分工作。最简单的边界策略是检查到目前为止的距离是否超过当前最小值,如果是,则拒绝探索分支。如果您首先探索最有希望的分支(例如,通过增加与当前点的距离来排序候选的下一个点),这会更好。

    更复杂的一步是使用 1-tree bound。给定一些点上的路径,我们想估计将其扩展到游览而不经过的成本。每个这样的扩展都包含从给定路径中的最后一个点到某个未访问点的边、所有未访问点上的路径以及从某个未访问点返回到给定路径中第一个点的边。在未访问点上获得路径的最小成本是困难的——这基本上是 TSP。然而,我们可以通过计算这些点上最小生成树的成本来降低它,因为路径是生成树。我们的最终估计是

    • 当前路径的成本,
    • 从当前路径的第一个点到最近的未访问点的距离,
    • 从当前路径的最后一个点到最近的未访问点的距离,
    • 未访问点上最小生成树的成本。

    从那里开始,根据您对数学的流利程度,有大量关于改进精确 TSP 算法的文献。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-27
      • 2011-06-05
      • 2015-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多