prolog从事实列表中找到最大值

时间:2013-03-03 16:04:21

标签: prolog

对不起,我是Prolog的新手。假设我有一个事实列表说6个事实,第一列数字代表人员ID,第二列代表一个人的胜利数。如果我想找到获胜最多的人,我该怎么做呢?

wins(1, 22).
wins(2, 24).
wins(3, 23).
wins(4, 20).
wins(5, 21).
wins(6, 19).
这样的事情?哈哈老实说,我真的不知道我在做什么

X = wins(_, Xs) 
Y = wins(_, Ys)
most wins(X) :- Xs > Ys  

1 个答案:

答案 0 :(得分:1)

获取该信息的方法不止一种。

most_wins(Id) :-
    wins(Id, W), \+ (wins(_, W1), W1 > W).

或者,如果您的Prolog有库(aggregate): -

most_wins(Id) :-
    aggregate(max(W, Id), wins(Id, W), max(_, Id)).

或者您可以使用setof / 3

most_wins(Id) :-
    setof(N-Id, W^(wins(Id, W), N is -W), [_-Id|_]).

有明显的速度/内存权衡:第一种方式是内存效率,O(1),但时间复杂度为O(N ^ 2),因为它扫描候选集的2倍。第二和第三个(我认为)实际上是等效的,在SWI-prolog的当前实现中,都构建了候选列表(然后是空间中的O(N)),然后及时选择元素-O(N log N)。

如果候选人是事实,请先使用第一个。

编辑另一种方式,从效率角度来看,更好地利用不可回溯的分配。只需扫描候选人,保持最大限度。 Plain Prolog将要求断言/撤回执行此类任务,使其效率相当低。但是许多Prologs有更有效的方法来存储“全球”变量......