2013-12-13 5 views
1

Как сообщить Prolog/CLPFD только определенное количество доменов только в качестве последнего ресурса?Ограничение домена Prolog

E.g. : домен от 0 ... 8. Я хочу, чтобы Prolog использовал 0, только если нет другого варианта. Я использовал параметр «вниз» для маркировки, но назначено слишком много 0.

Context: Hoo-Doo game -> Generate 8x8 board solution, где любой столбец, строка или диагональ имеют номера от 1 до 8 без повторения (подобный Sudoku). Для завершения решения необходимо использовать две прозрачные части (представленные 0, которые могут быть где угодно).

Вот код:

... 

setDomain(H,BoardSize), 
maplist(all_distinct,H), 
IndexI is BoardSize - 1, 
IndexJ is BoardSize - 2, 
checkDiagonalsLR(H,IndexI,IndexJ,BoardSize), %calls the all_distinct 
IndexJ2 is BoardSize - 1, 
checkDiagonalsRL(H,1,IndexJ2,BoardSize), %calls the all_distinct 
transpose(H,Columns), maplist(all_distinct,Columns), 
useLabeling(Columns,BoardSize), printBoard(Columns). 

useLabeling([],N). 
useLabeling([H|T],N) :- labeling([down],H), useLabeling(T,N). 
+0

Пожалуйста, добавьте свой код к вопросу. –

+0

Только что добавленный код – user2884323

ответ

3

Одним из способов является использование булевых переменных Bs и реифицированные ограничений, так что B_i является 1 тогда и только тогда V_i равна нулю:

(V_i #= 0) #<==> B_i

сумма B_i переменными является число N нулей, которые встречаются в вашем решении:

sum(Bs, #=, N)

Затем вы можете использовать labeling/2 таким образом, что N минимальна:

labeling([min(N)], Vs)

Это работает (с небольшими корректировками), например, в SICStus и SWI.

+0

Как это могло бы работать в моем коде? Я использую SICStus. Я новичок в Prolog, извините за это – user2884323

+0

Как вам нужно ровно 2 нуля, нет необходимости минимизировать. У вас может быть ограничение суммы, например 'sum (Bs, # =, 2)', и оставить этикетки как есть. – jschimpf

+0

На самом деле это не совсем 2 нули. Он должен использовать только 0, если для завершения доски нет другого варианта, поэтому может быть 0,1 или 2 нуля (максимум 2). Это происходит из-за того, что размер платы является переменным, я просто использовал 8x8 в качестве примера (который имеет решение с двумя нулями) – user2884323

Смежные вопросы