Prolog - 子树的高度(深度)

时间:2016-07-06 17:21:10

标签: recursion tree prolog

我有关系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树中最长的路径?或者我应该在之前将树结构保存在列表中?

2 个答案:

答案 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开头(并设置AB作为鉴别器参数)和将结果返回为H