Python 查找最短距离,同时精确访问每个节点一次

Python 查找最短距离,同时精确访问每个节点一次,python,graph,permutation,Python,Graph,Permutation,出于实践的原因,我正在致力于代码2015的出现,我被困在了。目标是找到最短的距离,同时精确地访问图中的每个位置一次。每个点都相互直接连接,且终点必须与起点不同。我已经制定了一个解决方案,但最终的值是不正确的,我没有看到潜在的问题 首先,我创建一个带有位置和距离的graph对象。然后我收集每个排列的位置到一个列表中,然后我找到并总结每个排列的距离。最后,我打印出最小距离值,这是练习的解决方案 守则: from collections import defaultdict from itertool

出于实践的原因,我正在致力于代码2015的出现,我被困在了。目标是找到最短的距离,同时精确地访问图中的每个位置一次。每个点都相互直接连接,且终点必须与起点不同。我已经制定了一个解决方案,但最终的值是不正确的,我没有看到潜在的问题

首先,我创建一个带有位置和距离的graph对象。然后我收集每个排列的位置到一个列表中,然后我找到并总结每个排列的距离。最后,我打印出最小距离值,这是练习的解决方案

守则:

from collections import defaultdict
from itertools import permutations

with open("input.txt") as file:
    input_ = file.read().split("\n")[:-1]

class Graph():
    def __init__(self):
        self.edges = defaultdict(list)
        self.weights = {}
    
    def add_edge(self, from_node, to_node, weight):
        self.edges[from_node].append(to_node)
        self.edges[to_node].append(from_node)
        self.weights[(from_node, to_node)] = weight
        self.weights[(to_node, from_node)] = weight

graph = Graph()

edges = [(i.split()[0], i.split()[2], int(i.split()[-1])) for i in input_]
for edge in edges:
    graph.add_edge(*edge)
    
loc_set = set([i[0] for i in edges])
routes = list(permutations(loc_set, len(loc_set)))

dists = []
for i in routes:
    print(i)
    dist_temp = []
    for k in range(len(i))[1:]:
        dist_temp.append(graph.weights[(i[k-1], i[k])])
    dists.append(sum(dist_temp))
    print(dist_temp)
    print(sum(dist_temp))
    
print(min(dists))
在得到一个无效的值后,我手动检查了一些排列及其相应的距离,因此在代码中打印了一些内容

输入(复制并粘贴到记事本并将其保存为input.txt对于我的代码来说应该可以正常工作):


我很确定,对于这个问题有很多更完善的解决方案,我愿意接受建议,因为我只是一个业余爱好者。但是,如果我们能够找出我的方法的缺点并使其正常工作,我将非常高兴。

多亏了Setonix的评论,我发现了错误!事实证明,这种方法是有效的(正如MarkRansom所提到的,它很可能远不是TSP的一个很好的实现,但它仍然是功能性的!),在定义位置集时,我只是粗心大意

我假设每个位置在指令字符串的开头至少存在一次。然而,只有一个位置(“Arbre”)出现在说明末尾。因此,图形不完整,因此输出错误

作为一个快速解决方案,我已通过以下方式修改了代码:

loc_set = set([i[0] for i in edges])

此外,顺便说一句,该方法对本练习很好,因为第二部分要求最长的距离,可以通过末尾的一行额外代码找到:

print(max(dists))

你的情况怎么样?如果是这样,我可以帮忙。你能改变这行代码loc_set=set([I[0]表示边中的I])吗,所以它还添加了I[1]Ann Zen:目标是在图中找到最短路径。但是,开始和结束节点不是预定义的,唯一的要求是只访问图中的每个节点一次。Setonix:这到底有什么帮助呢?这就是所谓的,它并不像看上去那么简单。
loc_set = list(set([i[0] for i in edges]))
loc_set.append("Arbre")
print(max(dists))