js实现八皇后,回溯法

八皇后问题:将八个皇后摆在一张8*8的国际象棋棋盘上,使每个皇后都无法吃掉别的皇后,一共有多少种摆法?

两个皇后不能同时在同一行,同一列,和斜对角线的位置上,使用回溯法解决。

从第一行选个位置开始放棋子,第二行从0开始选择满足规则的位置,到第三行发现没有位置可以满足规则,那么就把第二行的棋子向后移动一个可以满足规则的位置,如果没有这个位置,就返回到第一行,将棋子向后移动一个,从头开始,以此类推。

这个同学的博客讲的很通俗易懂 https://www.cnblogs.com/bigmoyan/p/4521683.html

1、首先尝试使用嵌套for循环实现,发现只能找出第一种解法,没办法统计到所有的解法   

   var n = 8 ;   
  var arr = [];

  
var total = 0; function b() { for (var row = 0; row <= n;) { if (row == n) { total++; break; } else { var col = 0; if (arr[row] != undefined) {
       //说明是回溯回来重新选择位置的,要从上次的位置开始往后选
var col = arr[row] + 1; } for (; col <= n; col++) { if (col == n) {
        //当前行的所有列都走完了,都没有位置可以放棋子,则从上一行开始从新选择位置 arr[row]
= undefined; row--; if (row) break; } if (isOk(row, col)) { arr[row] = col; row++; break; } } } } } function isOk(row, col) { for (var i = 0; i < row; i++) { if (row == 0) {
//第一行随便放哪个位置都行
return true; } if (arr[i] == col || Math.abs(arr[i] - col) == Math.abs(i - row)) {
     //同一行,同一列或者斜对角线都不能放
return false; } } return true; } b(); console.info(total);

for循环太复杂了,当找到一个解法后,希望移动第一行的棋子,寻找其他解法时,这个时候,当回溯到第一行时,无法控制棋子的位置(比如已经从第0个位置移到2位置才寻找到了第一种解法,当寻找其他解法时,回溯到第一行时,就不应该在返回都0,1这个两个位置),for循环无法记录。

转用递归实现,此时每一行的for循环都能被记住当前是第几列

    var arr = [];
    var total = 0;
    var arr2=[];
   
    function ab(row){
      if(row == n){
        //当row已经成功走到最后一行,说明已经找到了一种解法
        arr2.push([].slice.call(arr));//找到一种解法,就把当前的位置记录下来
        total++;
      }
      for(var col=0;col<n;col++){      
        if(isOk(row,col)){
        //当前行的这一列不与前几行的位置冲突,则把这个位置记录下来,位置记录下来,是为了每次循环比较是否有冲突
          arr[row]=col;
          ab(row+1);//进入下一行选位置,因为递归,所以当里层的循环全部结束以后,会返回上一层继续循环,实现了回溯
        }        
      }
    }
    function isOk(row, col) {
      for (var i = 0; i < row; i++) {
        //从第0行开始比较和当前的位置是否有冲突
        if (row == 0) {
          return true;
        }
        if (arr[i] == col || Math.abs(arr[i] - col) == Math.abs(i - row)) {
          return false;
        }
      }
    //成功比较完了之前的所有行,说明这个位置可以放置
      return true;
    }
    ab(0);
    console.info(total);
    console.info(arr2);

 

posted @ 2019-03-28 21:00  abc1234_abc  阅读(805)  评论(0编辑  收藏  举报