【发布时间】:2021-12-18 01:28:30
【问题描述】:
我有一个包含大约 800 个节点的加权图,每个节点的连接数从 1 到大约 300 不等。我需要使用一些额外标准找到两个节点之间的最短(最低成本)路径:
- 路径必须恰好包含五个节点。
- 每个节点都有一个属性(在示例代码中称为
position),它采用五个值之一;路径中的五个节点都必须具有该属性的唯一值。 - 该算法需要允许指定 1-2 个必需节点,路径必须以任意顺序在某个点包含这些节点。
- 算法的运行时间需要少于 10 秒,最好是时间越短,准确度损失越小。
我目前在 Python 中的解决方案是运行深度限制深度优先搜索,它递归地搜索每条可能的路径。为了使该算法在合理的时间内运行,我对在每个递归级别搜索的相邻节点的数量进行了限制。可以降低此数字以减少计算时间,但会以准确性为代价。目前这个算法太慢了,我最近的测试是 75 秒,邻居限制为 30。如果我再降低这个邻居限制,我的测试表明算法的准确性开始受到严重影响。我不知道如何在满足上述所有标准的同时解决这个问题。我的代码如下:
# The path must go from start -> end, be of length 5 and contain all nodes in middle
# Each node is represented as a tuple: (value, position)
def dfs(start, end, middle=[], path=Path(), best=Path([], math.inf)):
# If this is the first level of recursion, initialise the path variable
if len(path) == 0:
path = Path([start])
# If the max depth has been exceeded, check if the current node is the goal node
if len(path) >= depth:
# If it is, save the path
# Check that all required nodes have been visited
if len(path) == depth and start == end and path.cost < best.cost and all(x in path.path for x in middle):
# Store the new best path
best.path = path.path
best.cost = path.cost
return
# Run DFS on all of the neighbors of the node that haven't been searched already
# Use the weights of the neighbors as a heuristic; sort by lowest weight first
neighbors = sorted([x for x in graph.get(*start).connected_nodes], key=lambda x: graph.weight(start, x))
# Make sure that all neighbors haven't been visited yet and that their positions aren't already accounted for
positions = [x[1] for x in path.path]
# Only visit neighbouring nodes with unique positions and ids
filtered = [x for x in neighbors if x not in path.path and x[1] not in positions]
for neighbor in filtered[:neighbor_limit]:
if neighbor not in path.path:
dfs(neighbor, end, middle, Path(path.path + [neighbor], path.cost + graph.weight(start, neighbor)), best)
return best
Path类:
class Path:
def __init__(self, path=[], cost=0):
self.path = path
self.cost = cost
def __len__(self):
return len(self.path)
在改进此算法方面的任何帮助,甚至对解决问题的更好方法的建议将不胜感激,在此先感谢!
【问题讨论】:
标签: python algorithm recursion graph-theory path-finding