【问题标题】:Prolog - height (depth) of subtreeProlog - 子树的高度(深度)
【发布时间】:2016-07-07 19:29:41
【问题描述】:

我有关系child(X,Y),其中X 是根/父节点,Y 是子节点,因此是有向边。我想从动态关系height(R, H) 中的特定根节点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 树中最长的路径?还是应该先将树结构保存在列表中?

【问题讨论】:

    标签: recursion tree prolog


    【解决方案1】:

    最好提供路径作为参数而不是write it:

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

    【讨论】:

      【解决方案2】:

      如果你使用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.
      

      因此,您在以给定根元素 R 开头的每个路径的高度上运行 max 聚合(并将 AB 设置为鉴别器参数)并将结果返回为 H

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-06-27
        • 1970-01-01
        • 2012-01-17
        • 2022-01-25
        • 2011-02-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多