我有关系child(X,Y)
,其中X
是根/父节点,Y
是子节点,因此是有向边。我想计算动态关系H
中特定根节点R
中每个子树的高度height(R, H)
。
我之前的代码:
child(a,b).
child(a,f).
child(f,g).
child(f,h).
child(b,c).
child(c,d).
child(b,e).
child(c,l).
child(l,j).
height(R, H) :-
path(R,_,B,H),
write(B).
path(X,Y,[X,Y],1) :-
child(X,Y).
path(X,Y,[X|P],C) :-
child(X,Z),
path(Z,Y,P,Cn),
C is Cn+1.
它从节点R
开始查找所有路径(和长度)。有没有办法在递归中找到n-nary树中最长的路径?或者我应该在之前将树结构保存在列表中?
答案 0 :(得分:1)
最好将路径作为参数而不是write
来提供:
height(Node, Height, Path) :- path(Node, _, Path, Height).
结果如下:
| ?- height(a, H, P).
H = 1
P = [a,b] ? ;
H = 1
P = [a,f] ? ;
...
当您使用write
时,结果将显示在显示中,但不会捕获它们以供您在程序中使用。您可以使用setof/3
来收集路径及其高度的配对。由于setof/3
按升序对结果进行排序,因此从给定节点开始获取最短(或最长)路径变得很简单:
max_height_path_for_node(Node, MaxHeight, MaxPath) :-
setof(Height-Path, height(Node, Height, Path), Paths),
reverse(Paths, [MaxHeight-MaxPath | _]).
reverse/2
用于获取列表前面的最大高度,然后从那里“挑选”结果。
要查找所有节点的最大路径:
max_height_path(MaxHeight, MaxPath) :-
setof(Height-Path, Node^height(Node, Height, Path), Paths),
reverse(Paths, [MaxHeight-MaxPath | _]).
答案 1 :(得分:0)
如果您使用aggregate
库,则可以使用单行解决此问题:
height(R,H) :-
aggregate(max(Hi),A^B^path(R,A,B,Hi),H).
示例查询:
?- height(A,H).
A = a,
H = 4 ;
A = b,
H = 3 ;
A = c,
H = 2 ;
A = f,
H = 1 ;
A = l,
H = 1.
?- height(a,H).
H = 4.
?- height(f,H).
H = 1.
?- height(f,3).
false.
?- height(A,3).
A = b ;
false.
因此,您在每个路径的高度上运行max
聚合,该路径以给定的根元素R
开头(并设置A
和B
作为鉴别器参数)和将结果返回为H
。