печать визиток - своего рода рюкзак - PullRequest
4 голосов
/ 08 января 2012

Я новичок в Прологе, и у меня есть, вероятно, простая проблема с куском кода. Это проблема реального мира, которая возникла в прошлую пятницу, и поверьте мне, это не домашняя работа CS.

Мы хотим напечатать визитные карточки, которые можно печатать только блоками по 900 карточек (100 листов по 9 карточек на лист). Карты никому не следует распределять по нескольким блокам. Люди заказывали разное количество карточек, Е.Г .:

% "braucht" is german and means "needs"
braucht(anton,400).
braucht(berta,200).
braucht(claudia,400).
braucht(dorothee,100).
braucht(edgar,200).
braucht(frank,400).
braucht(georg,100).

Я собрал следующее определение, чтобы найти подходящий блок из 900 визитных карточек:

block(0,[]).
block(N,[H|T]) :-
    braucht(H,Nh),
%   \+(member(H,T)),
    D is N - Nh,
    D >= 0,
    block(D,T).

Это дает хороший список блоков людей, чьи карты помещаются вместе в блок из 900 карт. Но он перестает работать, если я активирую закомментированную строку «\ + member ....» и просто выдает мне «false». Но я должен заверить, что никто не получает более одного раза в этом блоке. Что я тут не так делаю?

Ответы [ 2 ]

3 голосов
/ 09 января 2012

Похоже, что вы хотите добиться, чтобы установить ограничение, которое H не появляется в хвосте T списка. Тем не менее, T по-прежнему не связан, когда вы вызываете member/2, так что member(H, T) будет успешным и, следовательно, \+ member(H,T) не удастся.

Если вы не хотите использовать Constraint Programming, но вместо этого используете чистый Prolog, вам следует использовать проверку в другом направлении и проверить, присутствует ли H в списке людей, которые были сгруппированы до этого точка. Что-то вроде:

block(0, List, List).
block(N, Rest, List) :-
  braucht(H, Nh),
  \+(memberchk(H, Rest)), % will fail when H is already in Rest
  D is N-Nh,
  D >= 0,
  block(D, [H|Rest], List).

Предикат block/3 может быть вызван из предиката block/2:

block(N, List) :-
  block(N, [], List).
2 голосов
/ 09 января 2012

Если вторым аргументом в вашем блочном предикате является «output», то ваша проблема в том, что T - свободная переменная, поэтому член (_, T) всегда будет успешным.Например:

?- member(anton,T).

T = [anton|_]
T = [_,anton|_]
T = [_,_,anton|_]

и так далее ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...