0
edge(a, b).
edge(b, d).
edge(d, c).
edge(d, e).
edge(d, f).
edge(e, g).
edge(f, g).
edge(g, h).

(假设每条边的长度相同)。

例如,要获取 a 和 d 之间的路径长度: ?- length(a,d) 应该返回2*constant (a->b and b->d).

我知道要做一个递归过程,我已经开始调用它isConnected来测试两个节点之间是否存在连接:

isConnected(X1, X2) :- edge(X1, X2).

isConnected(X1, X2) :- edge(X1, X), isConnected(X, X2).

但我不确定如何从这里开始。我知道我应该有一个dist过程来调用isConnectedand 并且是移动到下一个边缘的结果,然后将结果添加到类似L is Length. 但我不知道该怎么做。

任何帮助,将不胜感激!

4

2 回答 2

1

Daniel 的回答是好的,你只需将 length/2 应用于返回的列表。这里有一种更直接的方法,在路径建立后添加单元步骤:

isConnected(X1, X2, 1) :- edge(X1, X2).
isConnected(X1, X2, D) :- edge(X1, X), isConnected(X, X2, T), D is T + 1.
于 2013-04-16T06:11:14.463 回答
0

信不信由你,你真的亲密!您甚至可以生成您需要的所有信息,只是没有将其保存在任何地方。我的意思是X在您的第二isConnected/2条规则中:这就是您需要保留的所有内容才能到达那里的其余部分。

isConnected(X1, X2, [X2])      :- edge(X1, X2).
isConnected(X1, X2, [X |Rest]) :- edge(X1, X),  isConnected(X, X2, Rest).

基本上就是这样:

?- isConnected(a,X,P).
X = b,
P = [b] ;
X = d,
P = [b, d] ;
X = c,
P = [b, d, c] ;
X = e,
P = [b, d, e] ;
X = f,
P = [b, d, f] ;
X = g,
P = [b, d, e, g] ;
X = h,
P = [b, d, e, g, h] ;
X = g,
P = [b, d, f, g] ;
X = h,
P = [b, d, f, g, h] ;
false.
于 2013-04-16T03:24:34.553 回答