[英]Haskell: get all paths
I'm looking for a smart way to get all paths traversing a given data structure.我正在寻找一种智能方法来获取遍历给定数据结构的所有路径。 I figured out that I need a function like this:
我发现我需要一个这样的函数:
allPaths :: (a -> [a]) -> a -> [[a]]
It takes a seed a
and a function a -> [a]
(from each "a", you can get to multiple a's).它需要一个种子
a
和一个函数a -> [a]
(从每个“a”,你可以得到多个 a)。 The result is a list of paths starting from the seed.结果是从种子开始的路径列表。
My definition is:我的定义是:
allPaths :: (a -> [a]) -> a -> [[a]]
allPaths f a = map (a:) (concatMap (allPaths f) (f a))
But it doesn't quite work:但它并不完全有效:
ghci> let f a = if a == 1 then [2, 3] else if a == 2 then [4] else []
ghci> allPaths f 1
[]
The result should be: [[1,2,4], [1,3]]
, representing all the possible paths starting from 1.结果应该是:
[[1,2,4], [1,3]]
,表示从 1 开始的所有可能路径。
The problem is that as soon as you arrive at a []
, you never prepend anything to that because there are no endpoints to walk towards.问题是,一旦您到达
[]
,您就永远不会在此之前添加任何内容,因为没有可以走向的端点。
Instead, []
should indicate that this is an endpoint.相反,
[]
应该表明这是一个端点。
allPaths f a = case f a of
[] -> [[a]]
fa -> map (a:) $ concatMap (allPaths f) fa
As an alternative to the other answer, if you want all paths, not just all paths that arrive at a dead-end, then you need to prepend []
to the solution at each step, not just the final one.作为另一个答案的替代方案,如果您想要所有路径,而不仅仅是到达死胡同的所有路径,那么您需要在每一步的解决方案中添加
[]
,而不仅仅是最后一步。
allPaths :: (a -> [a]) -> a -> [[a]]
allPaths f a = map (a:) ([] : concatMap (allPaths f) (f a))
On your proposed f
, this gives在您提出的
f
,这给出了
*Main> allPaths f 1
[[1],[1,2],[1,2,4],[1,3]]
It includes the two paths leading to a dead end, as your example does, but it also includes [1]
and [1,2]
, which are valid paths (they just aren't valid maximal paths).它包括通往死胡同的两条路径,就像您的示例一样,但它还包括
[1]
和[1,2]
,它们是有效路径(它们只是不是有效的最大路径)。 In particular, if your graph has cycles in it, then this approach will produce a valid infinite list of paths, whereas the other proposed answer will fail to produce any results as soon as it hits the cycle.特别是,如果您的图中有循环,那么这种方法将生成一个有效的无限路径列表,而其他建议的答案一旦遇到循环就无法产生任何结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.