【发布时间】:2017-12-03 20:10:32
【问题描述】:
我正在尝试通过具有给定起点和目的地的图形获取所有可能路径的列表。 图表如下:
data Node = N1 | N2 | N3 | N4 | N5 deriving (Show, Eq)
neighbor :: Node -> [Node]
neighbor N1 = [N2, N4, N5]
neighbor N2 = [N1, N3]
neighbor N3 = [N1, N4, N5]
neighbor N4 = [N5]
neighbor N5 = [N1]
问题是:给定一个起始节点和一个目的地节点(例如,起始节点 = N1 和目的地 = N4)所有可能的路线,没有循环,应该是从起点到目的地的结果。在给出的示例中,它将是:
[[N1, N2, N3, N4],[N1, N4]]
我试图解决这个问题的功能是:
generatePaths :: (Node -> [Node]) -> Node -> Node -> [[Node]]
这里第一个参数应该是邻居函数,第二个是起始节点,第三个是目标节点。
我的主要问题是我现在找到了如何遍历所有邻居并调用generatePaths 并将每个邻居作为新的开始节点的方法。
非常感谢任何帮助
编辑: 感谢 Krom 和 RoadRunner,我想出了一个实现。
dfs_h :: (Node -> [Node]) -> [Node] -> [Node] -> Node -> [[Node]]
dfs_h graph visited [] _ = [visited]
dfs_h graph visited (n:ns) end
| elem n visited = (dfs_h graph visited ns end)
| elem end ns = [reverse (end:visited)] ++ (dfs_h graph visited (n:[neigh|neigh <- ns, neigh /= end]) end)
| n == end = [reverse (end:visited)] ++ (dfs_h graph visited ns end)
| otherwise = dfs_h graph (n:visited) ((graph n) ++ ns) end
dfs start end = filter (\x -> elem end x) (dfs_h neighbor [start] (neighbor start) end
我知道这不是最漂亮的解决方案,只是我想出的第一个。
编辑2: 但是这个算法的一个问题是当图形看起来像这样时:
neighbor :: Node -> [Node]
neighbor N1 = [N2, N3]
neighbor N2 = [N5]
neighbor N3 = [N4]
neighbor N4 = [N2, N1]
neighbor N5 = [N1]
并且应该找到从N1到N4的路径,那么函数的结果是
[[N1, N2, N5, N3, N4]]
现在我不打算实施什么,因此不应包含在解决方案中的 N2 和 N5 不会被包括在内。
有什么建议吗?
【问题讨论】:
-
很遗憾,我不能给你一个错误的实现,因为我删除了它以从头开始。但我的方法是这样的辅助函数:
generatePaths_h :: (Node -> [Node]) -> [Node] -> [Node] -> Node -> Node -> [[Node]]其中第二个参数现在是通向当前节点的路径,第二个参数应该是仍然需要迭代的邻居列表。其余参数同generatePaths -
图是有向的吗?您尝试实现哪种算法来解决这个问题?
-
如果图是有向的,就使用深度优先搜索算法。
-
感谢 dfs 的提示。我已经考虑过了,但放弃了这个想法,因为我找不到生成列表列表(即路径列表)的方法。我在原始问题中发布了我的实现。
标签: haskell