树遍历-DFS

时间:2019-05-01 14:55:16

标签: haskell

我需要在最大深度的树上实现DFS遍历(例如,如果深度为0,则仅显示根)。

successors节点将返回(Int,Tree)的列表,其中Tree基本上是我Node的a中的“ s”

limitedDfsRec :: (ProblemState s a, Ord s, Ord a) => [Node s a] -> Int -> S.Set (Node s a)-> [Node s a] -> [Node s a]
limitedDfsRec [] _ _ result = reverse result
limitedDfsRec (node:coada) max_depth visited result | adancime node > max_depth = limitedDfsRec coada max_depth visited result
                                                    | S.member node visited = limitedDfsRec coada max_depth visited result
                                                    | otherwise =
                                                    let succesori = [(Nod copil (Just actiune_copil) (Just $ stare node) ((adancime node) + 1) []) | (actiune_copil,copil) <- successors (stare node)]
                                                    in limitedDfsRec (succesori ++ coada) max_depth (S.insert node visited) (node : result)   

如果节点的深度大于允许的最大深度,则从节点开始,然后转到列表中的下一个元素(加拿大)。 如果该元素已经被访问过,那么您将转到列表中的下一个元素。 否则,您将获得所有孩子(succesori)并将其放入列表(coada)中,然后将元素添加到访问的对象和最终结果中。 该功能与该功能一起使用:

instance ProblemState Tree Int where
    successors (Tree n)
        | n == 2    = [(1, Tree 4), (2, Tree 6)]  -- 4 instead of 5 => cycle
        | otherwise = [(1, Tree $ 2 * n + 1), (2, Tree $ 2 * n + 2)]

    isGoal (Tree n) = n == 13

哪个产生孩子。好吧,问题在于,即使这些节点位于已访问集合中,上面的函数仍会访问该节点,而我不明白为什么。

例如,从树0开始,最大深度为2,您应该得到[0,1,3,4,2,6],但是我的函数得到[0,1,3,4,2,4 ,6],因为当到达2时,它会将4和6放在列表中,但是当到达4时,它会看到尚未访问4并将其放在输出中(结果)。 我想看看此代码的问题,而不是它的其他工作方式,因为我需要在2个以上的孩子上使用它。

1 个答案:

答案 0 :(得分:0)

您将整个节点保留在visited集中

| S.member node visited = ...
        -- ^ Node s a

因此,您可以具有多个标记为4的节点,但它们具有不同的附加信息。 您可能只需要一个visited :: S.Set s