dfs在prolog中。访问节点一次

时间:2016-06-17 18:48:22

标签: prolog

dfs(S, Visited, Path) :-
    move(S, S2),
    \+member(S2, Visited),
    dfs(S2, [S2|Visited], Path).

您好,

上面的代码是Prolog中dfs的原型。但是,move基于回溯,因此我丢失Visited列表,因此无法确保我访问每个节点一次。 如何在不使用全局变量的情况下处理它并且类似于它 - 我想使用纯逻辑解决方案。

1 个答案:

答案 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]).