Prolog中的广度优先搜索

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Prolog中的广度优先搜索相关的知识,希望对你有一定的参考价值。

我是Prolog的新手,目前正在实施DFS(深度优先搜索)和BFS(广度优先搜索)算法。我的DFS可以正常工作,如下面的代码,但BFS在到达叶节点时终止并中止(它不会回溯并继续搜索)。我还阅读了一些关于此的示例代码,但是有些函数没有像s(Node,NewNode)那样定义......所以很难理解,或者版本使用Queue太复杂了。

这是我的代码:一些地面功能:

%connected(+Start, +Goal, -Weight)
connected(1,7,1).
connected(1,8,1).
connected(1,3,1).
connected(7,4,1).
connected(7,20,1).
connected(7,17,1).
connected(8,6,1).
connected(3,9,1).
connected(3,12,1).
connected(9,19,1).
connected(4,42,1).
connected(20,28,1).
connected(17,10,1).

connected2(X,Y,D) :- connected(X,Y,D).
connected2(X,Y,D) :- connected(Y,X,D).

next_node(Current, Next, Path) :-
    connected2(Current, Next, _),
    not(member(Next, Path)).

DFS实施:

depth_first(Goal, Goal, _, [Goal]).
depth_first(Start, Goal, Visited, [Start|Path]) :-
    next_node(Start, Next_node, Visited),
    write(Visited), nl,
    depth_first(Next_node, Goal, [Next_node|Visited], Path).

BFS实施:

breadth_first(Goal, Goal, _,[Goal]).
breadth_first(Start, Goal, Visited, Path) :-
    findall(X,
            (connected2(X,Start,_),not(member(X,Visited))),
            [T|Extend]),
    write(Visited), nl,
    append(Visited, [T|Extend], Visited2),
    append(Path, [T|Extend], [Next|Path2]),
    breadth_first(Next, Goal, Visited2, Path2).

Path类似于Queue列表。例如,当调用DFS时:

?- depth_first(1, 28, [1], P).

BFS:

?- breadth_first(1, 28, [1], []).
答案

首先,s(A,B)的通常概念就像你的connect2(A,B,_)

您应该使您的接口谓词显式:

depth_first( Start, Goal, Path):-
    depth_first( Start, Goal, [Start], Path).

在BFS中维护队列并不复杂。而不是Visited,有VisitedLists队列(从前面弹出;在末尾添加;因此FIFO):

consed(A,B,[B|A]).

bfs(Goal, [Visited|Rest], Path) :-                     % take one from front
    Visited = [Start|_],            
    Start == Goal,
    findall(X,
        (connected2(X,Start,_),not(member(X,Visited))),
        [T|Extend]),
    maplist( consed(Visited), [T|Extend], VisitedExtended),      % make many
    append(Rest, VisitedExtended, UpdatedQueue),       % put them at the end
    bfs( Goal, UpdatedQueue, Path ).

当达到目标时,Path被实例化:

bfs(Goal, [[Goal|Visited]|_], Path):- 
    reverse([Goal|Visited], Path).

接口调用需要相应调整。它应该是

breadth_first( Start, Goal, Path):- bfs( Goal, [[Start]], Path).

以上是关于Prolog中的广度优先搜索的主要内容,如果未能解决你的问题,请参考以下文章

基础扩展 | 16. 队列应用示例:广度优先搜索

广度优先搜索遍历图

广度优先搜索在树中的应用

基本算法——深度优先搜索(DFS)和广度优先搜索(BFS)

广度优先搜索中的c ++迭代器和指针使用

修改广度优先搜索算法以记住矩阵中的最短路径