家庭关系序言 - 距离

时间:2013-01-24 20:02:27

标签: graph prolog

假设我有以下谓词:

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

1 个答案:

答案 0 :(得分:1)

通常,当您想要最短路径时,您需要先进行广度搜索。这里有一些讨论:Breadth-First in Prolog

Prolog将首先尝试找到解决方案深度,因此它将会看到特定推理线能走多远。当你想要最短的路径时,你宁愿Prolog尝试所有的第一个选项,然后从每个选项中向外迭代一个,直到找到解决方案。这样,您找到的第一个解决方案将是最短的。如果您可以拥有无​​限的解决方案(例如走迷宫,您可以备份并回溯您的步骤),这是唯一的方法。

不幸的是,没有神奇的开关你可以翻转以获得广度优先搜索,所以你必须实现它。 O'Keefe在 The Prraft 中非常清楚地解释了这一点,首先解释了如何将普通的Prolog搜索转换为显式的深度优先搜索,其中包含尚未成为的“开放式”东西。 -tried,然后如何更改表示开放集的列表的顺序,以获得广度优先行为。