开发者

graph path in prolog

开发者 https://www.devze.com 2023-02-19 23:06 出处:网络
I\'ve made the rules to obtain a path of a graph with the edges defined as follows: graph(a,b). graph(a,a).

I've made the rules to obtain a path of a graph with the edges defined as follows:

graph(a,b).
graph(a,a).
graph(b,c).

but now I need to do it when the facts being, for example:

graph(a,[a,b,e]).
graph(b,[c,d]).
graph(d,[]).

I had this:

path(Origin, Dest, List) :- path(Origin, Dest, List, [Origin]).
path(X, X, List, Temp) :- reverse(Temp, List).
path(Origin, Dest, List, Temp) :- graph(Origin, Inter),
                                 not(member(Inter, Temp)),
                                 path(Inter, Dest, List, [Inter|Temp]).

and I know that problem is in graph(Origin, Inter), but I don't know how to tweak it so it can go inside the list, I've tried graph开发者_Go百科(Origin, [Inter|_]) but obviously it just checks the first one. Any help (even if it's not code) would be greatly appreciated.


Assuming directed graphs:

edge(X,Y) :- graph(X,Nodes), member(Y,Nodes).


I managed to solve it, in case someone else has the same problem:

node(X) :- graph(X,_).
allnodes(Nodes) :- setof(X, node(X), Nodes).

path(Origin,Dest,List) :- allnodes(X),
                          path(Origin, Dest, List1, X, X),
                          reverse(List1,List),!.
path(X,X,[X],_,_).
path(Origin,Dest,[Dest|List],[X|_],AN) :- graph(X, Inter),
                                 member(Dest, Inter),
                                 path(Origin,X,List,AN,AN).
path(Origin,Dest,List,[X|Y],AN) :- graph(X, Inter),
                                 \+ member(Dest, Inter),
                                 path(Origin,Dest,List,Y,AN).


Here's my solution that works on directed or undirected graphs, with or without cycles.

Using @larsmans suggestion you can make this work with adjacency-list like input.

edge(X,Y) :- graph(X,Nodes), member(Y,Nodes).

It also tries to find all paths, without revisiting.

c(1,2).
% ... c(X,Y) means X and Y are connected

d(X,Y):- c(X,Y).
d(X,Y):- c(Y,X).
% Use d instead of c to allow undirected graphs

findPathHelper(_, Begin, [], End):- d(Begin, End).
findPathHelper(Front, Begin, [Next|NMiddle], End):-
    not(member(Begin,Front)),
    d(Begin, Next),
    append([Front,[Begin]], NFront),
    findPathHelper(NFront, Next, NMiddle, End).

findPath(Start, End, Path):-
    findPathHelper([], Start, Middle, End),
    append([[Start],Middle,[End]], Path).
0

精彩评论

暂无评论...
验证码 换一张
取 消