让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 _ = []
答案 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