我制作了一个谓词时间表(A,B,C),用于回溯列表A,B,C中的可能排列和回溯
| ?- schedule(A,B,C).
A = [im204,im212,im217]
B = [im209,im214,im218]
C = [im210,im216] ? ;
A = [im204,im212,im218]
B = [im209,im214,im217]
C = [im210,im216] ? ;
A = [im204,im212,im216]
B = [im209,im214,im218]
C = [im210,im217] ?
我还有谓词schedule_score(A,B,C,S),它从A,B,C到S列表返回得分(不记得得分的含义)。
| ?- score_schedule([im204,im209,im212],[im210,im214,im216],[im217,im218],S).
S = 578
在我的新谓语中
all_schedule_scores(A,B,C,S):-
schedule(A,B,C),
score_schedule(A,B,C,S).
它返回可能的排列和分数
| ?- all_schedule_scores(A,B,C,S).
A = [im204,im212,im217]
B = [im209,im214,im218]
C = [im210,im216]
S = 342 ? ;
A = [im204,im212,im218]
B = [im209,im214,im217]
C = [im210,im216]
S = 371 ? ;
A = [im204,im212,im216]
B = [im209,im214,im218]
C = [im210,im217]
S = 294 ?
我想知道是否有一种方法我只能返回最高分数的排列(或者不返回任何分数不是最大的排列)。
答案 0 :(得分:2)
目前尚不清楚您正在使用的Prolog实施方式。这是一个使用setof/3
(将结果从低到高排序)的解决方案:
max_scored(MaxA, MaxB, MaxC, MaxS) :-
setof((S,A,B,C), all_scheduled_scores(A,B,C,S), AllScoresLowToHigh),
reverse(AllScoresLowToHigh, [(MaxS,MaxA,MaxB,MaxC)|_]).
排序使用自然排序,因此如果(S1,A1,B1,C1)
大于(S2,A2,B2,C2)
,则S1
被视为大于S2
。
此解决方案只找到一个最大结果。如果您有多个相同的最大值,我会将其作为练习留给您。您只需要选择具有相同分数的reverse/2
的第二个参数的第一个元素。
答案 1 :(得分:0)
如果您的Prolog支持它,您可以使用库(aggregate):
max_scored_schedule(ScA,ScB,ScC,Score) :-
aggregate(max(S,[A,B,C]), (schedule(A,B,C),score_schedule(A,B,C,S)), max(Score,[ScA,ScB,ScC])).
使用您提供的硬编码数据进行测试:
?- max_scored_schedule(A,B,C,S).
A = [im204, im209, im212],
B = [im210, im214, im216],
C = [im217, im218],
S = 578.
正如您所看到的,只需要正确排序参数......
修改:
库(solutionsequences)允许类似SQL的查询,它可以解决您的问题
?- order_by([desc(S)], group_by(S, (A,B,C), (schedule(A,B,C),score_schedule(A,B,C,S)), G)).
但是@lurker的直截了当的答案是整洁的(+1),并且不要求你将另一个库移植到你的Prolog