Tree 在Prolog程序中,生成假子树?

Tree 在Prolog程序中,生成假子树?,tree,prolog,subtree,Tree,Prolog,Subtree,我在一门课上学习序言。作为练习,我需要部分生成给定树的所有子树。 问题是它会生成错误的子树 这是密码 build_tree3(T):- T=t(t(t(nil, -5, nil), 4, t(t(nil, 15, nil), -20, t(nil, 10, nil))), 2, t(nil, -8, t(t(nil, 9, nil),12,t(nil, 10, nil)))). get_sol(Tree, List, N):- without_root(Tree, List1, N1), wi

我在一门课上学习序言。作为练习,我需要部分生成给定树的所有子树。 问题是它会生成错误的子树

这是密码

build_tree3(T):-
T=t(t(t(nil, -5, nil), 4, t(t(nil, 15, nil), -20, t(nil, 10, nil))), 2, t(nil, -8, t(t(nil, 9, nil),12,t(nil, 10, nil)))).

get_sol(Tree, List, N):-
without_root(Tree, List1, N1),
with_root(Tree, List2, N2),!,
max_set(List1, N1, List2, N2, List, N).

max_set(List1, N1, List2, N2, List, N) :-
    (N1>N2,List=List1,N=N1;
     N2>N1,List=List2,N=N2;
    N2=:=N1,N=N1,(List=List1;List=List2)).

without_root(nil, _, 0).
without_root(t(L, _, R), List, N):-
    get_sol(L, LeftList, LeftN),
    get_sol(R, RightList, RightN),
    append(LeftList, RightList, List),
    N is LeftN + RightN.


with_root(nil, [], 0).
with_root(t(L, X, R), [X|List], N):-
    with_root(L, LeftList, LeftN),
    with_root(R, RightList, RightN), 
    append(LeftList, RightList, List),
    N is LeftN + RightN + X.
这是控制台

build_tree3(T), get_sol(T, L, N).
其结果是 L=[15,10,12,9,10], N=56; 应该是什么时候 L=[12,9,10], N=31


您的解决方案返回L=[15,10,12,9,10],因为它找到了最大独立集,所以不必返回子树。您可以按以下代码更改某些部分:

sol_tree(Tree,List,N):-
    sol_tree_noroot(Tree,L1,N1),
    sol_tree_withroot(Tree,L2,N2),!,
    max_set(L1,N1,L2,N2,List,N).

max_set(List1, N1, List2, N2, List, N) :-
    (N1>N2,List=List1,N=N1;
     N2>N1,List=List2,N=N2;
    N2=:=N1,N=N1,(List=List1;List=List2)).    

sol_tree_noroot(nil,[],0).
sol_tree_noroot(t(L,_,R),List,N):-
      sol_tree(L,L1,N1),sol_tree(R,R1,N2),!,
      max_set(L1, N1, R1, N2, List, N).

sol_tree_withroot(nil,[],0).
sol_tree_withroot(t(L,X,R),[X|List],N3):-
     sol_tree_withroot(L,L1,N1),sol_tree_withroot(R,R1,N2),
     max_set2(L1,N1,R1,N2,List,N),
     N3 is N+X.

max_set2(L1,N1,L2,N2,List,N):-
    (N1>0,N2>0,N is N1+N2,append(L1,L2,List);
     N1>=0,N2<0,N is N1 ,List=L1;
     N1<0,N2>=0,N is N2 ,List=L2;
     N1<0,N2<0,N1<N2,N is N2 ,List=L2;
     N1<0,N2<0,N1>N2,N is N1 ,List=L1;
     N1>0,N2=0,N is N1,(List=L1;append(L1,L2,List));
     N1=0,N2>0,N is N2,(List=L2;append(L1,L2,List));
     N1=0,N2=0,N is N1,(List=L1;List=L2;append(L1,L2,List))). 
solu树(树,列表,N):-
太阳树(树,L1,N1),
带根的sol_树(树,L2,N2),!,
最大集合(L1、N1、L2、N2、列表、N)。
最大集合(列表1,N1,列表2,N2,列表,N):-
(N1>N2,List=List1,N=N1;
N2>N1,List=List2,N=N2;
N2=:=N1,N=N1,(List=List1;List=List2))。
sol_tree_noroot(nil,[],0)。
sol_tree_noroot(t(L,R),List,N):-
太阳树(L,L1,N1),太阳树(R,R1,N2),!,
最大集合(L1、N1、R1、N2、列表、N)。
带根的sol_树(nil,[],0)。
带根的sol_树(t(L,X,R),[X|List],N3):-
有根的太阳树(L,L1,N1),有根的太阳树(R,R1,N2),
最大设置2(L1、N1、R1、N2、列表、N),
N3是N+X。
最大设置2(L1、N1、L2、N2、列表、N):-
(N1>0,N2>0,N为N1+N2,追加(L1,L2,List);

N1>=0,n2我假设L=[12,9,10],N=31是你期望的出口之一??你想返回所有子树,即使它们返回Nyes,事实上,你是对的。第二个问题呢??(从你的回答中,我知道你想要所有子树,即使第二部分是找到最大N的子树(其中N是节点值的总和)那么您对示例的回答是不正确的,因为它应该返回L=[2,4,-20,15,10,-8,12,9,10],N=34????