Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Breadth First Search in Prolog

I'm new to Prolog and currently implementing DFS (depth-first search) and BFS (breadth-first search) algorithms. My DFS works fine as the code below, but the BFS is terminated and aborted when it reaches the leaf node (it doesn't backtrack and continue searching). I also read some sample code about this but there are some functions they don't define like s(Node, NewNode)... so it's hard to understand, or the version use Queue is too complicated.

Here is my code: Some ground functions:

%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 implement:

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 implement:

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).

The Path is something like the Queue list. For example when call DFS:

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

BFS:

?- breadth_first(1, 28, [1], []).
like image 882
Trần Trọng Tín Avatar asked Dec 04 '15 07:12

Trần Trọng Tín


People also ask

What is meant by breadth-first search?

The breadth-first search or BFS algorithm is used to search a tree or graph data structure for a node that meets a set of criteria. It begins at the root of the tree or graph and investigates all nodes at the current depth level before moving on to nodes at the next depth level.

How do you use breadth-first search?

Breadth-first search (BFS) is a method for exploring a tree or graph. In a BFS, you first explore all the nodes one step away, then all the nodes two steps away, etc. Breadth-first search is like throwing a stone in the center of a pond. The nodes you explore "ripple out" from the starting point.

What is DFS in Prolog?

Prolog's default search algorithm is depth-first search (DFS), which is sometimes not convenient: DFS doesn't always find the solution for all problems, and when it does, it might not find the optimal solution.

Is best first search Breadth first?

BFS(Breadth First Search) uses Queue data structure for finding the shortest path. DFS(Depth First Search) uses Stack data structure. 3.


1 Answers

First, the usual notion of s(A,B) is just like your connect2(A,B,_).

You should make your interface predicates explicit:

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

Maintaining a queue in BFS is not complicated at all. Instead of Visited, have VisitedLists queue (pop from front; add at end; thus FIFO):

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

bfs( Goal, [Visited|Rest], Path) :-                     % take one from front
    Visited = [Start|_],            
    Start \== Goal,
    findall( X,
        ( connected2(X, Start, _), \+ 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 ).

When the goal is reached, Path is instantiated:

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

The interface call needs to be adjusted correspondingly. It should be

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

later note: repeated appending of course causes quadratic slowdown, so for efficiency this should be re-written with difference lists (also a straightforward task).

like image 65
Will Ness Avatar answered Sep 30 '22 00:09

Will Ness