NQueen problem是backtracking的一个着名例子。从source阅读后,我尝试了以下代码段。
int isSafe(int k,int i,int *x)
{
int j;
for(j=0;j<k;j++)
{
//old queen is placed at jth row of x[j] column
//new queen to be placed at kth row of ith column
if(i==x[j] || abs(k-j)==abs(i-x[j]))
return 0;
}
return 1;
}
int Nqueen(int k, int* sol, int N)
{
int col;
if( k == N )
{
printSol(sol,N);
return 1;
}
else
{
for(col = 1;col <= N; col++) //determines appropriate column number of the kth queen to be placed
{
if( isSafe(k,col,sol) )
{
sol[k] = col;
if( Nqueen(k+1, sol, N) )
return 1;
sol[k] = 0; // backtrack
}
}
return 0; // solution not possible
}
}
我得到的是output:
1 5 8 6 3 7 2 4
然而,当我评论回溯的声明时,我得到了相同的output没有任何问题。
int Nqueen(int k, int* sol, int N)
{
int col;
if( k == N )
{
printSol(sol,N);
return 1;
}
else
{
for(col = 1;col <= N; col++) //determines appropriate column number of the kth queen to be placed
{
if( isSafe(k,col,sol) )
{
sol[k] = col;
if( Nqueen(k+1, sol, N) )
return 1;
// sol[k] = 0; <-------------- Notice this change
}
}
return 0;
}
}
究竟是什么造成了NQueen问题,一个回溯问题?
这不是一个简单的递归方法吗?
答案 0 :(得分:6)
sol[k] = 0
不是回溯部分。回溯是在递归调用中完成的:if( Nqueen(k+1, sol, N) )
。
回溯的想法是一个详尽的搜索 - 你试图搜索所有可能性,直到找到一个。在这里,你正在尝试董事会中所有可能的女王任务,如果仍然安全的话,“继续”。如果您发现它不安全,则从失败的递归返回,并尝试下一个选项。
我相信注释掉的行只能确保如果找不到解决方案,结果数组是[0,...,0]
,而不是一些无意义的数组。
答案 1 :(得分:1)
回溯问题是一种编程范例,您可以尝试每种可能的组合。然后对于每个组合,检查到目前为止的组合是否正确。 以下是N(或8)女王问题的几个步骤。
通过将Queen放在每个可能的列上并检查它是否安全来进行此类操作。 您可以省略明显的错误条件,例如您不会将2个皇后放在同一行中。 下面是我的8皇后问题的代码,打印所有可能的解决方案。
#include<stdio.h>
int abs(int a){
return a>0? a : -a;
}
int isSafe(int col[],int row){
int row2,col2,i,yDiff,xDiff;
if(row == 0) return 1;
for(row2=0;row2<row;row2++){
if(col[row2] == col[row])
return 0;
xDiff = col[row2] - col[row];
xDiff = abs(xDiff);
yDiff = row - row2;
if(xDiff == yDiff)
return 0;
}
return 1;
}
int Nqueen(int col[],int n, int row){
int i;
if(row==n){
printf("\n");
for(i=0;i<n;i++)
printf("%d ",col[i]+1);
}else{
for(i=0;i<n;i++){
col[row] = i;
if(isSafe(col,row)){
queen(col,n,row+1);
}
}
}
}
int main(){
int col[8];
queen(col,8,0);
}
答案 2 :(得分:0)
首先,你真的需要理解算法(这会告诉你注释那些东西并不重要)。您已经注意到,此算法是递归的。它是回溯因为你
参见步骤3,我们“回到”第k个女王。这就是我如何解释自己为何被称为回溯的原因。