简体   繁体   English

Haskell:获取所有路径

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM