要得到三个( 、 和 )中最大的两个数,V1
您V2
可以V3
进行如下操作: 对列表进行排序[V1,V2,V3]
并取最后两个列表项[_,X,Y]
,平方并求和。
:- use_module(library(lists)).
:- use_module(library(clpfd)).
squareTwoLargest(V1,V2,V3, R) :-
Zs = [_,X,Y],
chain(Zs, #=<),
permutation([V1,V2,V3],Zs),
R #= X*X + Y*Y.
示例查询:
?- squareTwoLargest(20,30,10, R).
R = 1300
更好的实施
上面的代码是基于“排列排序”的,这使得它在不止一个方面效率低下。
如果、 和中的两个或多个相等,则目标squareTwoLargest(X,Y,Z, R)
多次成功并给出冗余答案。这由以下两个查询显示:X
Y
Z
?- squareTwoLargest(0,10,10, R).
R = 200 ;
R = 200 ;
false.
?- squareTwoLargest(10,10,10, R).
R = 200 ;
R = 200 ;
R = 200 ;
R = 200 ;
R = 200 ;
R = 200 ;
false.
我们可以通过使用大小为 3 的排序网络来消除冗余答案。有关详细信息,请查看带有约束逻辑编程的问题
排序列表的答案。
list_sorted__SN3([A0,A1,A2], [D0,D1,C2]) :-
B1 #= min(A1,A2), B2 #= max(A1,A2),
C0 #= min(A0,B2), C2 #= max(A0,B2),
D0 #= min(C0,B1), D1 #= max(C0,B1).
squareTwoLargest__SN(V1,V2,V3, R) :-
list_sorted__SN3([V1,V2,V3],[_,X,Y]),
R #= X*X + Y*Y.
考虑以下查询:
?- squareTwoLargest__SN(20,30,10, R).
R = 1300. % works like it did before
?- squareTwoLargest__SN(20,20,10, R).
R = 800. % succeeds deterministically
?- squareTwoLargest__SN(20,20,20, R).
R = 800. % succeeds deterministically
请注意,上面显示的极端情况的所有冗余答案都已被消除。