我正在使用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++];
}
}
}
}
答案 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;
}