Prolog域名限制

时间:2013-12-13 13:53:10

标签: prolog sudoku clpfd

如何告诉Prolog / CLPFD仅将特定数量的域仅用作最后一个资源?

E.g。 :域名从0 ... 8。我希望Prolog只在没有其他选项的情况下使用0。我使用'down'选项进行标记,但是分配了太多的0。

上下文:Hoo-Doo游戏 - >生成8x8电路板解决方案,其中任何列,行或对角线的数字均为1-8而不重复(数独)。必须使用两个透明部分(由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).

1 个答案:

答案 0 :(得分:3)

一种方法是使用布尔变量Bs和具体约束,以便B_i为1 iff V_i为零:

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

B_i变量的总和就是解决方案中出现的零的N个数:

sum(Bs, #=, N)

然后,您可以labeling/2N最小化的方式使用labeling([min(N)], Vs)

{{1}}

这适用于(例如在SICStus和SWI中进行小调整)。