Prolog - 算术平均和合并
Prolog - Arithmetic mean and merge
我在 Prolog 中有这个查询:
?- order([[person1, [7,8,8,9]], [person2, [8,9,8,9]], [person3,
[6,7,5,4]]],X).
我需要每个人的算术平均值,然后使用合并排序,就像这样:
X=[[person2,[8,9,8,9],8.5],[person1,[7,8,8,9],8],[person3,[6,7,5,4],5.5]].
我知道如何计算一个列表的算术平均值,但我想在这种情况下我需要一些递归的东西。
有人可以帮助我吗?
将谓词应用于列表的每个成员以获得新列表是 maplist
的目的。对于排序,您可以使用内置的 keysort/2
,或者,如果您有最新的 SWI-Prolog 版本,则可以使用 sort/4
。但是,如果您使用成对(例如)而不只是列表中的另一个项目(毕竟您知道 "things" 的数量)会更好:
person_vals_mean([P, Vs], Mean-[P, Vs]) :-
numlist_mean(Vs, Mean). % assuming you have defined it elsewhere
order(PVs, Ordered) :-
maplist(person_vals_mean, PVs, PVMs),
keysort(PVMs, Ordered_rev),
reverse(Ordered_rev, Ordered).
完全删除列表可能是明智的:为什么 [person, [1,2,3]]
而不是 person_vals(person, [1,2,3])
?使用这种表示,您可以将 person_vals_mean/2
重写为:
person_vals_mean(person_vals(P, Vs), Mean-person_vals(P, Vs)) :- ...
或者,如果可以使用 sort/4
,甚至:
person_vals_mean(person_vals(P, Vs), person_vals_mean(P, Vs, M)) :-
numlist_mean(Vs, M).
order_by_means(PVs, Ordered) :-
maplist(person_vals_mean, PVs, PVMs),
sort(3, @>=, PVMs, Ordered).
然后:
?- order_by_means([person_vals(person1, [7,8,8,9]),
person_vals(person2, [8,9,8,9]),
person_vals(person3, [6,7,5,4])],
Ordered).
Ordered = [person_vals_mean(person2, [8, 9, 8, 9], 8.5),
person_vals_mean(person1, [7, 8, 8, 9], 8),
person_vals_mean(person3, [6, 7, 5, 4], 5.5)].
事实上,SWI-Prolog 中的所有排序内置函数都使用归并排序算法,但这是用 C 实现的,实际上无关紧要。
我在 Prolog 中有这个查询:
?- order([[person1, [7,8,8,9]], [person2, [8,9,8,9]], [person3, [6,7,5,4]]],X).
我需要每个人的算术平均值,然后使用合并排序,就像这样:
X=[[person2,[8,9,8,9],8.5],[person1,[7,8,8,9],8],[person3,[6,7,5,4],5.5]].
我知道如何计算一个列表的算术平均值,但我想在这种情况下我需要一些递归的东西。
有人可以帮助我吗?
将谓词应用于列表的每个成员以获得新列表是 maplist
的目的。对于排序,您可以使用内置的 keysort/2
,或者,如果您有最新的 SWI-Prolog 版本,则可以使用 sort/4
。但是,如果您使用成对(例如)而不只是列表中的另一个项目(毕竟您知道 "things" 的数量)会更好:
person_vals_mean([P, Vs], Mean-[P, Vs]) :-
numlist_mean(Vs, Mean). % assuming you have defined it elsewhere
order(PVs, Ordered) :-
maplist(person_vals_mean, PVs, PVMs),
keysort(PVMs, Ordered_rev),
reverse(Ordered_rev, Ordered).
完全删除列表可能是明智的:为什么 [person, [1,2,3]]
而不是 person_vals(person, [1,2,3])
?使用这种表示,您可以将 person_vals_mean/2
重写为:
person_vals_mean(person_vals(P, Vs), Mean-person_vals(P, Vs)) :- ...
或者,如果可以使用 sort/4
,甚至:
person_vals_mean(person_vals(P, Vs), person_vals_mean(P, Vs, M)) :-
numlist_mean(Vs, M).
order_by_means(PVs, Ordered) :-
maplist(person_vals_mean, PVs, PVMs),
sort(3, @>=, PVMs, Ordered).
然后:
?- order_by_means([person_vals(person1, [7,8,8,9]),
person_vals(person2, [8,9,8,9]),
person_vals(person3, [6,7,5,4])],
Ordered).
Ordered = [person_vals_mean(person2, [8, 9, 8, 9], 8.5),
person_vals_mean(person1, [7, 8, 8, 9], 8),
person_vals_mean(person3, [6, 7, 5, 4], 5.5)].
事实上,SWI-Prolog 中的所有排序内置函数都使用归并排序算法,但这是用 C 实现的,实际上无关紧要。