Поскольку здесь не достаточно вопросов, чтобы ответить, вот несколько общих советов для решения такого рода проблем Пролога.
Вы можете создавать списки указанной длины, используя length/2
с аргументом несвязанного списка, например:
?- length(X, 3).
X = [_3192, _3198, _3204].
Это часто полезно при попытке ответить на вопросы, касающиеся списков. Вы можете взять длину списка, а затем снова использовать length/2
для построения списка результатов.
select/3
также является полезным предикатом для ответа на вопросы такого рода, поскольку его можно использовать для выбора элементов из списка. Например, если бы я хотел выбрать два элемента из списка, я мог бы сделать что-то вроде этого:
picktwo(L, [X,Y]) :- select(X, L, L0), select(Y, L0, _).
Здесь я просто собираюсь вернуть два элемента, игнорируя остальную часть списка, который был бы доступен в позиции, которую я имею _
.
?- picktwo([7,18,3,4,19], X).
X = [7, 18] ;
X = [7, 3] ;
X = [7, 4] ;
X = [7, 19] ;
X = [18, 7] ;
X = [18, 3] ;
X = [18, 4] ;
X = [18, 19] ;
X = [3, 7] ;
X = [3, 18] ;
X = [3, 4] ;
X = [3, 19] ;
X = [4, 7] ;
X = [4, 18] .
(Поклонники DCG, такие как я, могут быть удивлены этой альтернативной реализацией: phrase((select(X), select(Y)), [7,18,3,4,19], _).
)
Существует встроенная система суммирования списков, которая называется sumlist/2
.
Максимизация проблем часто может быть решена довольно, но крайне неэффективно, если попросить Prolog найти решение, которое больше, чем все другие решения. Такой код часто выглядит так:
solve(Solution) :-
find_solution(Solution),
\+ (find_solution(Solution2), Solution2 > Solution1).
Здесь вы декларативно говорите, что Решение лучше, потому что нет другого решения, которое лучше. Прологу, конечно, придется сделать комбинаторную вещь, чтобы найти лучшее решение, так что это определенно превращает то, что может быть O (N log N), в поиск O (N ^ 2), но для небольших данных все будет работать нормально наборы. Вот пример для нахождения самых больших пар значений:
sumpairs(List, X, Y, Sum) :-
select(X, List, L0), select(Y, L0, _), Sum is X + Y.
largest(List, X, Y) :-
sumpairs(List, X, Y, Sum),
\+ (sumpairs(List, _, _, ABSum), ABSum > Sum).
Это производит:
?- largest([7,18,3,4,19], X, Y).
X = 18,
Y = 19 ;
X = 19,
Y = 18 ;
false.
Итак, вы можете видеть, что он настолько неэффективен, что фактически находит один и тот же ответ дважды с помощью перестановки, но вы можете придумать несколько способов предотвратить это, если вам не все равно.
Этой коробки деталей, вероятно, достаточно, чтобы вы самостоятельно нашли ответ на свой вопрос, удачи!