现在下面是一个dictonary,我正在尝试找到最短的路径。我们必须在最短的时间内去所有5个房子。每个键都是一个房子,每个值列表都是以秒为单位的时间。例如,第一个房子的时间为0,因为它很明显,现在从第一个房子到第二个房子有74秒......依此类推。每个指数都是下一个房子的时间代表。
现在是第二行,以2为关键。从第二宫到第一宫它是74秒,现在从第二宫到第三宫它是4069秒,如下图所示。
我正在努力为此找到最好的算法我很困惑应该使用什么?组合?置换?
我们的目标是找到下面所示的房屋与房屋之间的最短路径,以及您找到的最短路径中所有时间路线的总和
list = 0, 74 , 2213, 816, 1172 ,
最短路径。
1 -> 2 -> 5 -> 4 -> 3 -> 1
我们必须再次回到第一宫,这就是为什么1再次出现
数字1到5代表房屋 列表遍历每个键,值找到min的最小值和索引。将时间添加到time_list
使用上一个
将min的索引与下一个home匹配,在home中忽略零和 在以前的家乡时代已经遇到的时间
答案 0 :(得分:1)
您可以尝试通过跟踪当前房屋和到目前为止访问过的所有房屋来减少要检查的路径数量。我们假设您有路径[1, 2, 3, 4]
和[1, 3, 2, 4]
,您可以检查哪一个更短,只能继续使用。以下是您提供的数据的示例,它将距离存储在2D数组中而不是dict
,但原理是相同的:
dist = [
[0, 74, 4109, 3047, 2266],
[74, 0, 4069, 2999, 2213],
[4109, 4069, 0, 1172, 1972],
[3047, 2999, 1172, 0, 816],
[2266, 2213, 1972, 816, 0]
]
# Helper function to calculate path length
def path_len(path):
return sum(dist[i][j] for i, j in zip(path, path[1:]))
# Set of all nodes to visit
to_visit = set(xrange(len(dist)))
# Current state {(node, visited_nodes): shortest_path}
state = {(i, frozenset([0, i])): [0, i] for i in xrange(1, len(dist[0]))}
for _ in xrange(len(dist) - 2):
next_state = {}
for position, path in state.iteritems():
current_node, visited = position
# Check all nodes that haven't been visited so far
for node in to_visit - visited:
new_path = path + [node]
new_pos = (node, frozenset(new_path))
# Update if (current node, visited) is not in next state or we found shorter path
if new_pos not in next_state or path_len(new_path) < path_len(next_state[new_pos]):
next_state[new_pos] = new_path
state = next_state
# Find the shortest path from possible candidates
shortest = min((path + [0] for path in state.itervalues()), key=path_len)
print 'path: {0}, length: {1}'.format(shortest, path_len(shortest))
它将输出最短路径之一和总距离:
path: [0, 2, 3, 4, 1, 0], length: 8384
请注意,根据您提供的数据,有两种可能的解决方案具有相同的长度:[0, 2, 3, 4, 1, 0]
和[0, 1, 4, 3, 2, 0]
。