Пролог, возврат перестановок с максимальным значением - PullRequest
0 голосов
/ 21 мая 2018

Я создал расписание предикатов (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 ? 

Мне было интересно, есть ли способ, которым я могу вернуть только перестановки с максимальным счетом (или не вернуть любые перестановки, чей счет не максимальный).

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Не ясно, какую реализацию 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.

Это решение просто находит единственный максимальный результат.Если у вас есть несколько одинаковых максимумов, я оставлю это как упражнение для вас.Вам просто нужно выбрать первые элементы 2-го аргумента для reverse/2 с одинаковым счетом.

0 голосов
/ 22 мая 2018

Если ваш Пролог поддерживает его, вы можете использовать библиотеку ( агрегат ):

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.

Как выможно видеть, это просто вопрос правильного упорядочения аргументов ...

Редактировать :

Библиотека ( solutionsequence ) допускает 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

...