我需要在最大深度的树上实现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个以上的孩子上使用它。
答案 0 :(得分:0)
您将整个节点保留在visited
集中
| S.member node visited = ...
-- ^ Node s a
因此,您可以具有多个标记为4的节点,但它们具有不同的附加信息。
您可能只需要一个visited :: S.Set s
。