JS实现八皇后问题

背景
八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上

八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为 n×n ,而皇后个数也变成n 。当且仅当n = 1或n ≥ 4时问题有解。

盲目的枚举算法

通过N重循环,枚举满足约束条件的解(八重循环代码好多,这里进行四重循环),找到四个皇后的所有可能位置,然后再整个棋盘里判断这四个皇后是否会直接吃掉彼此,程序思想比较简单。

function check1(arr, n) {
  for(var i = 0; i < n; i++) {
    for(var j = i + 1; j < n; j++) {
      if((arr[i] == arr[j]) || Math.abs(arr[i] - arr[j]) == j - i) {
        return false;
      }
    }
  }
  return true;
}
function queen1() {
  var arr = [];
 
  for(arr[0] = 1; arr[0] <= 4; arr[0]++) {
    for(arr[1] = 1; arr[1] <= 4; arr[1]++) {
      for(arr[2] = 1; arr[2] <= 4; arr[2]++) {
        for(arr[3] = 1; arr[3] <= 4; arr[3]++) {
          if(!check1(arr, 4)) {
            continue;
          } else {
            console.log(arr);
          }
        }
      }
    }
  }
}
 
queen1();
//[ 2, 4, 1, 3 ]
//[ 3, 1, 4, 2 ]

回溯法

『走不通,就回头』,在适当节点判断是否符合,不符合就不再进行这条支路上的探索。

function check2(arr, n) {
  for(var i = 0; i <= n - 1; i++) {
    if((Math.abs(arr[i] - arr[n]) == n - i) || (arr[i] == arr[n])) {
      return false;
    }
  }
  return true;
}
 
function queen2() {
  var arr = [];
 
  for(arr[0] = 1; arr[0] <= 4; arr[0]++) {
    for(arr[1] = 1; arr[1] <= 4; arr[1]++) {
      if(!check2(arr, 1)) continue; //摆两个皇后产生冲突的情况
      for(arr[2] = 1; arr[2] <= 4; arr[2]++) {
        if(!check2(arr, 2)) continue; //摆三个皇后产生冲突的情况
        for(arr[3] = 1; arr[3] <= 4; arr[3]++) {
          if(!check2(arr, 3)) {
            continue;
          } else {
            console.log(arr);
          }
        }
      }
    }
  }
}
 
queen2();
//[ 2, 4, 1, 3 ]
//[ 3, 1, 4, 2 ]

非递归回溯法

function check2(arr, n) {
  for (var i = 0; i < n; i++) {
    if ((Math.abs(arr[i] - arr[n]) === n - i) || (arr[i] == arr[n])) return false;
  }
  return true;
}

function backdate(n) {
  let arr = [];
  let k = 1;// 第n个皇后
  arr[0] = 0;

  while (k > 0) {
    arr[k - 1] = arr[k - 1] + 1;
    while ((arr[k - 1] <= n) && (!check2(arr, k - 1))) {
      arr[k - 1]++;
    }
    // 这个皇后满足约束条件,进行下一步判断
    if (arr[k - 1] <= n) {
      if (k === n) {
        console.log(arr);
      } else {
        k++;// 下一个皇后
        arr[k - 1] = 0;
      }
    } else {
      k--;//回溯,上一个皇后
    }
  }
}

backdate(4);

递归回溯法

function check2(arr, n) {
  for (var i = 0; i < n; i++) {
    if ((Math.abs(arr[i] - arr[n]) === n - i) || (arr[i] == arr[n])) return false;
  }
  return true;
}

var arr = [], n = 4;
function backtrack(k) {
  if(k > n) {
    console.log(arr);
  } else {
    for(var i = 1;i <= n; i++) {
      arr[k-1] = i;
      if(check2(arr, k-1)) {
        backtrack(k + 1);
      }
    }
  }
}
 
backtrack(1);

参考:
JavaScript解八皇后问题的方法总结

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值