Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何改进我的TSP实现?(使用回溯)(Python)_Python_Algorithm_Recursion_Backtracking - Fatal编程技术网

如何改进我的TSP实现?(使用回溯)(Python)

如何改进我的TSP实现?(使用回溯)(Python),python,algorithm,recursion,backtracking,Python,Algorithm,Recursion,Backtracking,我正在尝试使用回溯编写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_

我正在尝试使用回溯编写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])))


def搜索最佳路径(距离矩阵):
最佳路径=[None]*(len(距离矩阵[0]))
路线=最佳路线。复制()
访问=[False]*(len(距离矩阵[0]))
当前距离=0
返回搜索路径(0,路径,最佳路径,-1,-1,当前路径距离,距离矩阵,已访问,0)
def搜索路径(开始索引1、路径、最佳路径、最小距离、最佳距离、当前距离、距离矩阵、已访问、上次访问):
如果start_index1==len(路线):
当前距离+=距离矩阵[上次访问][0]
如果当前_距离<最佳_距离或最佳_距离==-1:
最佳距离=当前距离
对于范围(0,长度(路线))中的k:
最佳路径[k]=路径[k]
其他:
对于范围内的k(长度(路线)):
如果未访问[k]:
新的最小距离=最小距离-距离矩阵[上次访问][k]
如果新的\u min<最佳\u距离或开始\u index1==0:
新建当前距离=当前距离+距离矩阵[上次访问][k]
路由[起始索引1]=k
已访问[k]=True
最佳距离=搜索路径(开始索引1+1,路径,最佳路径,新路径,最佳距离,
新的当前距离,距离矩阵,访问,k)[1]
已访问[k]=错误
返回最佳路线、最佳距离
def构建距离矩阵(x,y):
距离矩阵=[[0表示范围内的列(len(x))]表示范围内的行(len(x))]
对于范围内的i(len(x)):
对于范围内的j(len(x)):
距离矩阵[i][j]=((x[i]-x[j])**2+(y[i]-y[j])**2)**0.5
返回距离矩阵
n=int(输入())
x=[None]*n
y=x.copy()
对于范围(n)中的i:
x_y=输入()
x[i]=x_y.split()[0]
y[i]=x_y.split()[1]
x=列表(映射(浮动,x))
y=列表(映射(浮动,y))
最佳路径=搜索最佳路径(构建距离矩阵(x,y))
打印(“%.4f”%best_route[1])
打印(“”.join(映射(str,最佳路径[0]))

很抱歉,如果我做错了什么,而你在看这部电影时快死了,哈哈。

一个可能会有所帮助的小变化是,你在每一步都要迭代整个路线列表。通过维护待访问点的列表,可以节省n的因子,就像递归置换枚举算法那样

从理论上讲,n的因子似乎很多,但由于算法仍然是Θ(n!),因此改进相当于在相同的运行时间内多出一个点。要做得更好,您需要实现分支和绑定

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

复杂度提高的一步是使用1-树边界。给定一些点上的路径,我们希望估算将其扩展到旅游而不经过的成本。每个这样的扩展都包括从给定路径中的最后一个点到某个未访问点的边、所有未访问点上的路径以及从某个未访问点到给定路径中的第一个点的回边。在未访问的点上获取路径的最小成本是困难的——这基本上是TSP。然而,我们可以通过计算这些点上最小生成树的代价来降低它的绑定,因为路径是生成树。我们的最终估计是

  • 当前路径的成本
  • 从当前路径中的第一个点到最近未访问点的距离
  • 从当前路径中的最后一点到最近未访问点的距离
  • 未访问点上最小生成树的代价
从那以后,根据你对数学的熟练程度,有一整套关于精确TSP算法改进的文献