在2D数组中对角检查对象的Java方法

时间:2015-10-24 22:39:27

标签: java multidimensional-array n-queens

我正在使用Java进行N皇后计划。我能够打印出每个Queen位于不同行和列的所有解决方案。现在我需要跟踪碰撞的对角线。因此2D阵列上有2n-1条对角线。该算法要求我们在棋盘上有2n-1个负对角线和2n-1个正对角线。有一个大小为2n-1的数组,称为d1,它跟踪每个2n-1个负对角线上的皇后数,即碰撞次数。如果在第m个负对角线上有k个皇后,则在该对角线上存在k-1个冲突。该 数字k被写入d1数组的第m个元素。同样,我们选择另一个大小为2n-1的数组,称为d2,用于2n-1个正对角线。

这是我的D2方法,但我完全迷失了。我知道所有向上的对角线都是行+ col,但就是这样。

      public void D2(){
          int[] upDiag = new int[2*board.length - 1];
          int numberOfCollisions = 0;
             for(int row = 0; row < board.length; row++){
                 for(int col = 0; col < board.length; col++){
                    if(isQueen(row, col)){
                    upDiag[numberOfCollisions++];
                  }   
                }
               }
             }

1 个答案:

答案 0 :(得分:1)

我写了关于八皇后/ N皇后问题的三部曲系列。

Here's问题的概要和递归解决方案。

Here's遗传算法解决方案。

Here's模拟退火解决方案。

对于碰撞检查本身,这样的事情非常有效:

double assessFitness(Integer[] candidate) {
    int collisions = 0;
    final int MAXIMUM_COLLISIONS = calculateMaxCollisions();
    for (int i = 0; i < GRID_SIZE - 1; i++) {
        for (int j = i + 1; j < GRID_SIZE; j++) {
            if ((candidate[i].equals(candidate[j])) || j - i == Math.abs(candidate[i] - candidate[j]))
                collisions++;
        }
    }
    return (MAXIMUM_COLLISIONS - collisions) / (double) MAXIMUM_COLLISIONS;
}

请注意,这是根据我的遗传算法解决方案改编的。我确实解释了为什么我在博客文章中返回一个从0到1扩展的值,但在你的情况下稍作修改就会产生你想要的结果:

int countCollisions(Integer[] candidate) {
    int collisions = 0;
    final int MAXIMUM_COLLISIONS = calculateMaxCollisions();
    for (int i = 0; i < GRID_SIZE - 1; i++) {
        for (int j = i + 1; j < GRID_SIZE; j++) {
            if ((candidate[i].equals(candidate[j])) || j - i == Math.abs(candidate[i] - candidate[j]))
                collisions++;
        }
    }
    return collisions;
}

为了使其正常工作,您需要计算N-Queens问题的最大允许碰撞次数。

private int calculateMaxCollisions() {
    int sum = 0;
    for (int i = GRID_SIZE - 1; i > 0; i--) {
        sum += i;
    }
    return sum;
}