我正在尝试编码“皇后区和平军”问题。目标是将可能的最大值等于no。棋盘上的黑白女王/王后,这样他们就不会互相攻击,但是可以用相同的颜色进行攻击。
我已经在SICStus 4.3.2上实现并尝试了以下代码。此代码的问题在于,直到国际象棋棋盘大小为8时,它的执行速度才会更快,但是N> 8则需要花费大量时间。 这里N是最大等于no。皇后(黑色和白色) S是用于显示黑白皇后在棋盘上的位置的矩阵。 棋盘的大小是7。
所以查询是
| ?- queens(S,7,N).
S = [[0,-1,-1,-1,0,0,0],[0,0,0,0,0,1,1],[-1,0,0,-1,0,0,0],[-1,-1,0,0,0,0,0],[0,0,0,0,1,0|...],[0,0,0,0,1|...],[0,0,0,0|...]],
N = 7 ?
yes
但是
需要很多时间| ?- queens(S,10,N).
所以问题是如何优化此代码,使其执行更快?
-1->黑皇后
0->自由场所
1->白皇后
Mat->用于在棋盘上显示黑白皇后位置的矩阵 暗->尺寸或棋盘大小 N->放置在棋盘上的黑白皇后的最大皇后数量。
:-use_module(library(clpfd)),use_module(library(lists)).
queens(Mat,Dim,N):-
Dim > 2,
Ls is Dim*Dim,
length(Sol, Ls),
N #> 0, N #< Ls/4,
domain(Sol, -1,1),
list_to_matrix(Sol, Dim, Mat),
row(Mat, 1, Row1),
domain(Row1, -1, 0),
column(Mat, 1, Col1),
domain(Col1, -1, 0),
row(Mat, Dim, RowDim),
domain(RowDim, 0, 1),
column(Mat, Dim, ColDim),
domain(ColDim, 0, 1),
diag(Mat, Dimiag, 0, Dim),
domain(Dimiag, 0, 1),
nth1(Dim, RowDim, LRow),
LRow is 1,
global_cardinality(Sol, [-1-N, 1-N, 0-_]),
check_rows(Mat),
transpose(Mat, B),
check_rows(B),
diag_to_list(Mat, X1, Dim),
check_rows(X1),
matrix_reverse(Mat, C),
diag_to_list(C, X2, Dim),
check_rows(X2),
labeling([maximize(N), ffc],Sol).