js 回溯算法(八皇后问题、0-1背包问题)

回溯算法是一种通过探索所有可能的解空间来求解问题的方法。它采用深度优先搜索的策略,在搜索过程中通过递归和回溯来探索所有的解,并找到满足问题要求的解。下面是使用回溯算法解决八皇后问题和0-1背包问题的示例:

八皇后问题:

function solveNQueens(n) {
  const result = []; // 存储解的结果

  // 检查当前位置是否合法
  function isSafe(board, row, col) {
    // 检查当前列是否有冲突
    for (let i = 0; i < row; i++) {
      if (board[i][col] === 'Q') {
        return false;
      }
    }

    // 检查左上方是否有冲突
    for (let i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
      if (board[i][j] === 'Q') {
        return false;
      }
    }

    // 检查右上方是否有冲突
    for (let i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
      if (board[i][j] === 'Q') {
        return false;
      }
    }

    return true;
  }

  // 回溯求解
  function backtrack(board, row) {
    // 如果已经放置了n个皇后,找到了一个解
    if (row === n) {
      result.push(board.map(row => row.join('')));
      return;
    }

    for (let col = 0; col < n; col++) {
      // 检查当前位置是否合法
      if (isSafe(board, row, col)) {
        // 放置皇后
        board[row][col] = 'Q';
        // 继续下一行的回溯
        backtrack(board, row + 1);
        // 撤销放置的皇后
        board[row][col] = '.';
      }
    }
  }

  // 初始化棋盘
  const board = new Array(n).fill('.').map(() => new Array(n).fill('.'));
  backtrack(board, 0);

  return result;
}

console.log(solveNQueens(4));  // 输出:[ [ '.Q..', '...Q', 'Q...', '..Q.' ], [ '..Q.', 'Q...', '...Q', '.Q..' ] ]

在以上示例中,我们使用回溯算法解决八皇后问题。从棋盘的第一行开始,逐行放置皇后,并检查每个位置是否满足规则。如果满足规则,继续放置下一行的皇后,直到所有皇后都放置完毕,此时找到了一个解。通过不断尝试不同的放置方法,我们可以找到所有的解。

0-1背包问题:

function knapSack(capacity, weights, values) {
  const n = weights.length;
  let maxProfit = 0;

  // 回溯求解
  function backtrack(index, currentWeight, currentProfit) {
    // 达到容量或者所有物品都已经尝试过
    if (currentWeight === capacity || index === n) {
      maxProfit = Math.max(maxProfit, currentProfit);
      return;
    }

    // 不选当前物品
    backtrack(index + 1, currentWeight, currentProfit);
    
    // 选当前物品
    if (currentWeight + weights[index] <= capacity) {
      backtrack(index + 1, currentWeight + weights[index], currentProfit + values[index]);
    }
  }

  backtrack(0, 0, 0);

  return maxProfit;
}

const capacity = 10;
const weights = [2, 3, 4, 5];
const values = [3, 4, 5, 6];

console.log(knapSack(capacity, weights, values));  // 输出:8

在以上示例中,我们使用回溯算法解决0-1背包问题。通过递归的方式尝试所有可能的放置方式,对于每个物品,可以选择放入背包或者不放入背包。在递归过程中,我们记录当前的重量和价值,并更新最大的价值。当达到背包容量或者所有物品都已经尝试过时,回溯结束,返回最大的价值。

在本例中,背包的容量为10,物品的重量和价值分别为[2, 3, 4, 5]和[3, 4, 5, 6]。通过调用knapSack函数,我们可以得到最大的价值为8。

猜你喜欢

转载自blog.csdn.net/weixin_39273589/article/details/132540019