如何优化此代码以使其执行更快

时间:2019-07-01 12:31:56

标签: prolog clpfd n-queens sicstus-prolog

我正在尝试编码“皇后区和平军”问题。目标是将可能的最大值等于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).

0 个答案:

没有答案