dfs(S, Visited, Path) :-
move(S, S2),
\+member(S2, Visited),
dfs(S2, [S2|Visited], Path).
您好,
上面的代码是Prolog中dfs的原型。但是,move
基于回溯,因此我丢失Visited
列表,因此无法确保我访问每个节点一次。
如何在不使用全局变量的情况下处理它并且类似于它 - 我想使用纯逻辑解决方案。
答案 0 :(得分:1)
您可以使用迭代(基于堆栈)方法为您的dfs而不是递归,如How to implement depth first search for graph with non-recursive aprroach中所述。
将调用 Move
来检查可能的邻居是什么。这里的区别在于你首先遍历可能的候选人。通过始终将它们放在堆栈的前面,我们将迭代地首先进入深度,因为堆栈的顶部将首先被探索。
例如,可以使用findall
示例:强>
%% Dfs starting from a root
dfs(Root) :-
dfs([Root], []).
%% dfs(ToVisit, Visited)
%% Done, all visited
dfs([],_).
%% Skip elements that are already visited
dfs([H|T],Visited) :-
member(H,Visited),
dfs(T,Visited).
%% Add all neigbors of the head to the toVisit
dfs([H|T],Visited) :-
not(member(H,Visited)),
findall(Nb,move(H,Nb),Nbs),
append(Nbs,T, ToVisit),
dfs(ToVisit,[H|Visited]).