算法(一)——回溯法

      回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为"回溯点"。

      回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。

N皇后问题

【描述】

      在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上。

 

【分析】

      要解决N皇后问题,其实就是要解决好怎么放置这n个皇后,每一个皇后与前面的所有皇后不能在同一行、同一列、同一对角线,在这里我们可以以行优先,就是说皇后的行号按顺序递增,只考虑第i个皇后放置在第i行的哪一列,所以在放置第i个皇后的时候,可以从第1列判断起,如果可以放置在第1个位置,则跳到下一行放置下一个皇后。如果不能,则跳到下一列...直到最后一列,如果最后一列也不能放置,则说明此时放置方法出错,则回到上一个皇后向之前放置的下一列重新放置。此即是回溯法的精髓所在。当第n个皇后放置成功后,即得到一个可行解,此时再回到上一个皇后重新放置寻找下一个可行解...如此后,即可找出一个n皇后问题的所有可行解。

算法(一)——回溯法_第1张图片

迭代代码

不在同一对角线上:

(1)两个坐标之和相等(2)两个坐标之差相等。例如有两个点作为分别为(a,b)和(c,d),他们在同一对角线上的条件是(1)a+b=c+d (2) a-b=c-d    等价于   |a-b|=|c-d|.



int Place(int *Column,int index){
	int i;
	for(i=1;iColumn[i]=a   代表把皇后存放在第i行的第a个位置。
	int index=1;          //行数
	int i;               //循环变量
	int answer_num=0;    //解个数
	for(I =1;i <= n;i++)    //初始化数组Column
             Column[i]=0;
	while(index > 0){
	     Column[index]++;
	     while(Column[index] <= n && !Place(Column[index],index))   /*寻找皇后的位置*/
	         Column[index]++;
	     if(Column[index] <= n){
	         if(index== n){        //如果是最后一行时,即有一个解时
	             answer_num++;     
		     for(i = 1;i <= n;i++)
		         Column[index]++;
                  }
                  else{           /*继续寻找下一个皇后*/
		     index++;	
		     Column[index]=0;
                  }
              }
              else
	         index--;         /*当前皇后无法放置,回溯至上一个皇后*/
       }
}
递归代码

int queen(int index)   
{   
    if(index>n && n>0) //当放置的皇后超过n时,可行解个数加1,此时n必须大于0   
        answer_sum++;   
    else  
      for(int i=1;i<=n;i++)   
      {   
          Column[index] = i; //标明第t个皇后放在第i列   
          if(place(index)) //如果可以放在某一位置,则继续放下一皇后   
             queen(index+1);    
      }   
    return sum;   
}   

你可能感兴趣的:(其它)