如何告诉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).
答案 0 :(得分:3)
一种方法是使用布尔变量Bs
和具体约束,以便B_i
为1 iff V_i
为零:
(V_i #= 0) #<==> B_i
B_i
变量的总和就是解决方案中出现的零的N
个数:
sum(Bs, #=, N)
然后,您可以labeling/2
以N
最小化的方式使用labeling([min(N)], Vs)
:
{{1}}
这适用于(例如在SICStus和SWI中进行小调整)。