检查是否连接了两个节点

时间:2014-05-17 12:25:55

标签: haskell recursion graph

g成为无向图,为简单起见,我们将表示为Integers对的列表。 例如

g = [(1,1),(2,2),(3,3),(4,4),(1,2),(2,3),(1,3)]

假设我已经定义了一个函数adj node,它将相邻节点的有序列表提供给node中的g。 例如

> adj 1
[2,3]
> adj 4
[]

我想检查两个节点是否在相邻节点处以递归方式连接,推广到任意数量的检查此函数

connected start end
| start == end = True
| elem end (adj start) = True
| elem end (extract (map adj (adj start))) = True
| elem end (extract (map adj (extract (map adj (adj start))))) = True
  -- to make this function work on a graph or arbitrary size, I should put here
  -- an endless number of lines like the ones above
| otherwise = False
where
    extract (x:xs) = x ++ extract xs
    extract _ = []

1 个答案:

答案 0 :(得分:1)

要递归检查,您必须执行递归调用。这里只是关于应用连接到adj start的所有成员并查看是否有任何结果:

connected :: Int -> Int -> Bool
connected start end | elem end adjs = True
                    | otherwise     = any (flip connected end) $ adjs
  where  adjs = adj start

你还必须检查周期。这可以通过保留已经遇到的节点的列表来完成,作为第一种方法。如果你关心性能和大图,那么你可能不得不使用基本列表以外的东西:

connected :: Int -> Int -> Bool
connected start end = go start end [start]
  where
    go start end seen | elem end adjs = True
                      | otherwise     = any (\x -> go x end (x:seen))
                                        . filter (not . (flip elem seen))
                                        $ adjs
      where adjs = adj start