我正在研究基于遗传算法的Java代码。我想解决N皇后问题,需要计算对角线上的冲突/冲突。我无法正确找到对角线中的碰撞。
我找到了一种算法,但是无法正确理解它如何在我的代码中实现。 我生成一个8x8的二维数组
char Queens[][]={
{'.','.','.','.','.','.','.','.'},
{'.','.','.','.','.','.','.','.'},
{'.','.','.','.','.','.','.','.'},
{'.','.','.','.','.','.','.','.'},
{'.','.','.','.','.','.','.','.'},
{'.','.','.','.','.','.','.','.'},
{'.','.','.','.','.','.','.','.'},
{'.','.','.','.','.','.','.','.'},
};
我已经找到列和行的冲突。只需计算对角线冲突即可。
for(int i=0;i<8;i++){
Queens[myarr[i]][i] = 'q';
}
int conflict=0;
for (int i=0;i<8;i++){
for (int j=0;j<8;j++){
if(Queens[i][j]=='q'){
for(int left=j-1;left>=0;left--){
// System.out.print(left+" "+j);
if(Queens[i][left]=='q'){
conflict++;
}
}
for(int right=j+1;right<8;right++)
{
if(Queens[i][right]=='q'){
conflict++;
}
}
这是我找到的算法,但无法在我的Queens[][]
阵列上实现
# calculate diagonal clashes
for i in range(len(chromosome)):
for j in range(len(chromosome)):
if ( i != j):
dx = abs(i-j)
dy = abs(chromosome[i] - chromosome[j])
if(dx == dy):
clashes += 1
return 28 - clashes
答案 0 :(得分:2)
您的代码存在一些问题:
代码对冲突进行两次计数。没必要,因为如果q1
和q2
之间存在冲突,则对称原因也会在q2
和q1
之间发生冲突。 。因此,原则上只在一个方向上向左或向右计数就足够了。以编程方式,这意味着仅应使用两个内部循环之一(带有right
计数器的循环或带有left
计数器的循环)。
因此,第一个更改应该是删除一个内部循环。出于性能原因,这也是有道理的。
第二个问题是,目前仅计算相同行中的冲突,而没有计算相同列中的冲突。
因此,第二个更改应该是考虑同一列中的冲突。从编程上讲,它类似于先前的情况,但是现在您必须考虑类别 top和bottom 而不是 left和right 。
接下来的问题涉及对角线上的冲突的考虑(这是原始问题)。
您有关对角线冲突的伪代码可能来自here。在这种方法中,候选溶液被视为具有n
基因的染色体。每个基因对应于nxn
棋盘的一行,并指示皇后在该行中的位置。即候选解决方案对应于大小为n
的数组,其中每个元素都包含女王/王后在属于相应元素的行中的位置。
相比之下,您的代码使用nxn
矩阵直接表示棋盘。这意味着解决方案候选者对应于一个nxn
矩阵,其中每个与带有皇后的字段相对应的元素都包含字符q
。
我看不到如何将伪代码与您的方法结合起来。这就是为什么我建议以下与您的方法兼容的替代方法:
对角线分为两类:
一个类别包括从左上到右下的对角线。这种情况可以按以下方式处理:
for (int bottom = i + 1, right = j + 1; bottom < 8 && right < 8; bottom++, right++) {
if (Queens[bottom][right] == 'q') {
conflict++;
}
}
其他类别包括从右上到左下的对角线。从编程上来说,这类似于先前的情况 因此可以类似的方式实现。
进行所有更改后,总共有四个内部循环。第一个考虑了行内的冲突,第二个考虑了列内的冲突,以及对角线内的第三个和第四个冲突。使用以下矩阵进行测试...
{ 'q', '.', '.', '.', '.', '.', '.', 'q' },
{ '.', '.', '.', '.', '.', '.', '.', '.' },
{ '.', '.', 'q', '.', '.', 'q', '.', '.' },
{ '.', '.', '.', '.', '.', '.', '.', '.' },
{ '.', '.', '.', '.', '.', '.', '.', '.' },
{ '.', '.', 'q', '.', '.', 'q', '.', '.' },
{ '.', '.', '.', '.', '.', '.', '.', '.' },
{ 'q', '.', '.', '.', '.', '.', '.', 'q' },
...应导致20个冲突(2个对角线各6个= 3 + 2 + 1个冲突,4行各1个冲突和4列各1个冲突:2 * 6 + 4 * 1 + 4 * 1 = 20)。