繁体   English   中英

八皇后启发式

[英]Eight Queens Heuristic

我正在开发一种启发式方法,可以将8个皇后放在8x8的棋盘上。 每个方格都有其自己的消除编号(以指示如果在一个方格中放置了一个皇后棋子,则将“消除”一个空棋盘的多少个方块。)并且每个方格都应放置在消除号最低的方格中。

我的问题是我不知道该怎么做才能继续减少其适当平方的特定消除数,因此,如果您能帮助我,我将非常感激。 另一个问题,我觉得我的代码很复杂,因此有什么注释可以使其更简单吗?

这是我的代码

public class Queen {
private final int SIZE = 8;
private int board[][] = new int[SIZE][SIZE]; // 8x8 board
private int hor[] = new int[SIZE]; // horizontal moves
private int ver[] = new int[SIZE]; // vertical moves
private int lowestValue = 22;
private int[][] queens = new int[SIZE][2]; // 8 queens 

public Queen () {
    // initialize each square with its own elimination number
    for (int row = 0; row < board.length; row++) {
        for (int col = 0; col < board[row].length; col++) {
            if (row == 0 || row == 7 || ((row >= 1 && row <= 6) && (col == 0 || col == 7))) {
                board[row][col] = 22;
            } 
            else if ((row == 1 || row == 6) && (col >= 1 && col <= 6) || (row > 1 && row < 6) && (col == 1 || col == 6)) {
                board[row][col] = 24;
            }
            else if ((row == 2 || row == 5) && (col >= 2 && col <= 5)|| (row > 2 && row < 5) && (col == 2 || col == 5)){
                board[row][col] = 26;
            }
            else if ((row == 3 || row == 4) && (col >= 3 && col <= 4)){
                board[row][col] = 28;
            }

        }
    }// end initializing

    // initialize moves
    //right
    hor[0] = 1;
    ver[0] = 0;
    //left
    hor[1] = -1;
    ver[1] = 0;
    //up
    hor[2] = 0;
    ver[2] = -1;
    //down
    hor[3] = 0;
    ver[3] = 1;
    //up right
    hor[4] = 1;
    ver[4] = -1;
    hor[7] = -1;
    ver[7] = 1;
    //up left
    hor[5] = -1;
    ver[5] = -1;
    //down right
    hor[6] = 1;
    ver[6] = 1;
    // down left

    for (int queen = 0; queen < queens.length; queen++) {
        placeQueens(queen);
    }
    displayBoard();
}// end constructor

// eliminate squares according to the place of the queen
private void eliminate (int queen_row, int queen_col) {

    // eliminate diagonal
    int rowCopy = queen_row;// helper row
    int colCopy = queen_col;// helper column
    try {
        // eliminate up right
        for (int move = 0; move < 8; move++) {
            rowCopy += ver[4];
            colCopy += hor[4];
            if (board[rowCopy][colCopy] > 0) {
                board[rowCopy][colCopy] = 0;
            }
        }
    } 
    catch (ArrayIndexOutOfBoundsException e) {      
    }

    try {
        rowCopy = queen_row;
        colCopy = queen_col;
        // eliminate up left
        for (int move = 0; move < 8; move++) {
            rowCopy += ver[5];
            colCopy += hor[5];
            if (board[rowCopy][colCopy] > 0) {
            board[rowCopy][colCopy] = 0;
            }
        }
    } 
    catch (ArrayIndexOutOfBoundsException e) {
    }

    try {
        rowCopy = queen_row;
        colCopy = queen_col;
        // eliminate down right
        for (int move = 0; move < 8; move++) {
            rowCopy += ver[6];
            colCopy += hor[6];
            if (board[rowCopy][colCopy] > 0) {
            board[rowCopy][colCopy] = 0;
            }
        }
    } 
    catch (ArrayIndexOutOfBoundsException e) {
    }
    try {
        rowCopy = queen_row;
        colCopy = queen_col;
        // eliminate down left
        for (int move = 0; move < 8; move++) {
            rowCopy += ver[7];
            colCopy += hor[7];
            if (board[rowCopy][colCopy] > 0) {
            board[rowCopy][colCopy] = 0;
            }
        }
    } 
    catch (ArrayIndexOutOfBoundsException e) {
    }

    // eliminate row
    for (int col = 0; col < 8;col++) {
        if (board[queen_row][col] > 0) {
        board[queen_row][col] = 0;
        }
    }
    // eliminate col
    for (int row = 0; row < 8; row++) {
        if (board[row][queen_col] > 0) {
        board[row][queen_col] = 0;
        }
    }

}// end elimination

// decrease elimination number of each square
public void decreaseElimination () {


}// end decrease elimination

public void countEliminated () {
    int counter = 0;
    for (int row = 0; row < board.length; row++) {
        for (int col = 0; col < board[row].length; col++) {
            if (board[row][col] == 0) {
                counter++;
            }

        }
    }
    System.out.printf("%d squares eliminated\n", counter);

}

public void placeQueens(int queenNum) {
    int targetRow;
    int targetCol;
    // find lowest elimination number
    for (int row = 0; row < board.length; row++) {
        for (int col = 0; col < board[row].length; col++) {
            if (board[row][col] > 0 && board[row][col] < lowestValue) {
                lowestValue = board[row][col];
                targetRow = row;
                targetCol = col;

                queens[queenNum][0] = targetRow;
                queens[queenNum][1] = targetCol;
            }
        }
    }

    System.out.printf("queen %d has been placed in [%d][%d]\n", queenNum + 1, queens[queenNum][0], queens[queenNum][1]);
    eliminate(queens[queenNum][0], queens[queenNum][1]);
    decreaseElimination();
    countEliminated();

}

// display board
public void displayBoard () {

    for (int row = 0; row < board.length; row++) {
        for (int col = 0; col < board[row].length; col++) {
                System.out.printf("|%2d|", board[row][col]); // display elimination number of each square
        }
        System.out.println();
    }

}// end displayBoard

}

我的主要方法是在单独的类中。

这段代码天生就有缺陷:

for (int queen = 0; queen < queens.length; queen++) {
    placeQueens(queen);
}

您不能决定将皇后区0放到哪里,而又不决定确切地将皇后区1至8放到哪里。 您已实现“首次试穿”:

首先适合

如上例所示,First Fit无法提供可行的解决方案。 本手册中的更多信息(包括有效的算法)。

这是一种有效的算法(但可伸缩): 回溯

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM