假设我有以下谓词:
father(aaron, chloe).
father(aaron, dan).
father(aaron, emily).
father(frank, george).
mother(beth, chloe).
mother(beth, dan).
mother(beth, emily).
mother(emily, george).
sibling(X,Y) :-...
parents(X,Y) :-...
我想在家谱的两个成员之间找到最短路径(距离)。 例如,父母之间的距离是2,兄弟之间的距离是1。 我尝试了以下(但它不起作用):
parent(X,Y) :-
father(X,Y);
mother(X,Y).
sibling(X,Y):-
parent(Z,X), !, parent(Z,Y),
not(X=Y).
not_in_list(_,[]).
not_in_list(X,[Y|L]):-
not(X=Y),
not_in_list(X,L).
edge(X,Y):-
(parent(X,Y);
parent(Y,X);
sibling(X,Y)).
list_length(0,[]).
list_length(N,[_|Ys]):-
list_length(N1,Ys),
N is N1+1.
travel_graph(X,X,_).
travel_graph(From,To,[From|Path]):-
edge(From,Next),
not_in_list(Next,Path),
travel_graph(Next,To,Path).
degree(X,Y,N):-
travel_graph(X,Y,L),
list_length(N,L).
答案 0 :(得分:1)
通常,当您想要最短路径时,您需要先进行广度搜索。这里有一些讨论:Breadth-First in Prolog
Prolog将首先尝试找到解决方案深度,因此它将会看到特定推理线能走多远。当你想要最短的路径时,你宁愿Prolog尝试所有的第一个选项,然后从每个选项中向外迭代一个,直到找到解决方案。这样,您找到的第一个解决方案将是最短的。如果您可以拥有无限的解决方案(例如走迷宫,您可以备份并回溯您的步骤),这是唯一的方法。
不幸的是,没有神奇的开关你可以翻转以获得广度优先搜索,所以你必须实现它。 O'Keefe在 The Prraft 中非常清楚地解释了这一点,首先解释了如何将普通的Prolog搜索转换为显式的深度优先搜索,其中包含尚未成为的“开放式”东西。 -tried,然后如何更改表示开放集的列表的顺序,以获得广度优先行为。