博客
关于我
数据结构和算法躬行记(5)——回溯算法
阅读量:453 次
发布时间:2019-03-06

本文共 2836 字,大约阅读时间需要 9 分钟。

回溯算法入浅

回溯算法(Backtracking)是一种在搜索过程中,当发现某条路径不满足条件时,能智能地撤回一步,尝试其他可能性。这种方法类似于枚举,但比简单枚举更高效,因为它能够在发现问题早期就剪枝,不再继续走不必要的路。

在《》一文中,解决回溯问题实际上是一个决策树的遍历过程。要想高效地实现回溯算法,我们需要思考以下三个关键问题:

  • 路径(Path):已经做出的选择记录。
  • 选择列表(Choices):当前可以做的选择。
  • 结束条件(Termination Condition):到达决策树底层,无法再做选择的条件。
  • 以下是改编后的算法通用结构:

    function backtrack(路径, 选择列表) {
    if 满足结束条件
    console.log(路径)
    return
    for 选择 of 选择列表
    做选择
    backtrack(路径, 选择列表)
    撤销选择
    }

    回溯算法的典型应用

    1. N皇后问题

    N皇后问题是回溯算法的经典应用之一。目标是将N个皇后放置在N×N的棋盘上,使得它们彼此之间不能相互攻击。每个皇后所在的行、列以及对角线都不能有其他皇后。

    实现思路:

  • 从第一个 row=0 开始。
  • 循环列,尝试在每个 column 中放置皇后。
  • 如果方格(row, column)处于攻击范围内,跳过。
  • 在(row, column)处放置皇后,继续寻找下一个位置。
  • 当row与皇后数量相同时,说明找到了一种解法。
  • const N = 4;
    function backtrack(route, row) {
    if (row == N) {
    console.log(route);
    return;
    }
    for (let column = 0; column < N; column++) {
    if (!isValid(route, row, column)) {
    continue;
    }
    route[row] = column;
    backtrack(route, row + 1);
    route[row] = null;
    }
    }
    function isValid(route, row, column) {
    let leftup = column - 1;
    let rightup = column + 1;
    for (let i = row - 1; i >= 0; i--) {
    if (route[i] == column) {
    return false;
    }
    if (leftup >= 0) {
    if (route[i] == leftup) {
    return false;
    }
    }
    if (rightup < N) {
    if (route[i] == rightup) {
    return false;
    }
    }
    leftup--;
    rightup++;
    }
    return true;
    }

    2. 0-1背包问题

    0-1背包问题是一个经典的回溯问题。目标是从给定的物品中选择不超过背包容量的物品,使得背包中的物品总重量最大。

    实现思路:

    • 递归地尝试将物品装入背包或不装。
    • 在每一步选择中,检查当前物品是否超出背包容量或是否已经选过。
    • 当当前物品装入背包后,递归处理剩余物品。
    • 撤销选择后,继续尝试其他可能性。
    let max = Number.MIN_VALUE;
    let W = 100;
    function backtrack(route, goods) {
    let weight = route.length ? route.reduce((acc, cur) => acc + cur, 0) : 0;
    if (weight == W || route.length == goods.length) {
    if (weight > max && weight <= W) {
    max = weight;
    }
    console.log(route);
    return;
    }
    for (let i = 0; i < goods.length; i++) {
    if (weight + goods[i] > W || route.indexOf(goods[i]) > -1) {
    continue;
    }
    route.push(goods[i]);
    backtrack(route, goods);
    route.pop();
    }
    }

    3. 全排列问题

    全排列问题要求输出给定数字序列的全部可能排列。假设序列中的数字都是唯一的,可以利用回溯算法枚举出所有排列。

    实现思路:

    • 递归地尝试将数字放入排列中。
    • 在每一步选择中,检查当前数字是否已经被选过。
    • 当排列长度等于数字数量时,记录当前排列。
    • 撤销选择后,继续尝试其他可能性。
    function backtrack(route, nums) {
    if (route.length == nums.length) {
    console.log(route);
    return;
    }
    for (let i = 0; i < nums.length; i++) {
    if (route.indexOf(nums[i]) > -1) {
    continue;
    }
    route.push(nums[i]);
    backtrack(route, nums);
    route.pop();
    }
    }

    面试题解析

    • 面试题12面试题13:在二维方格或矩阵的运动中,可以用回溯法解决。
    • 面试题17:将问题转换成数字排列,用递归实现。

    通过以上例子可以看出,回溯算法在解决组合优化问题时表现出色,尤其是在需要枚举所有可能解的情况下。

    转载地址:http://cdafz.baihongyu.com/

    你可能感兴趣的文章
    npm和yarn清理缓存命令
    查看>>
    npm和yarn的使用对比
    查看>>
    npm如何清空缓存并重新打包?
    查看>>
    npm学习(十一)之package-lock.json
    查看>>
    npm安装 出现 npm ERR! code ETIMEDOUT npm ERR! syscall connect npm ERR! errno ETIMEDOUT npm ERR! 解决方法
    查看>>
    npm安装crypto-js 如何安装crypto-js, python爬虫安装加解密插件 找不到模块crypto-js python报错解决丢失crypto-js模块
    查看>>
    npm安装教程
    查看>>
    npm报错Cannot find module ‘webpack‘ Require stack
    查看>>
    npm报错Failed at the node-sass@4.14.1 postinstall script
    查看>>
    npm报错fatal: Could not read from remote repository
    查看>>
    npm报错File to import not found or unreadable: @/assets/styles/global.scss.
    查看>>
    npm报错TypeError: this.getOptions is not a function
    查看>>
    npm报错unable to access ‘https://github.com/sohee-lee7/Squire.git/‘
    查看>>
    npm淘宝镜像过期npm ERR! request to https://registry.npm.taobao.org/vuex failed, reason: certificate has ex
    查看>>
    npm版本过高问题
    查看>>
    npm的“--force“和“--legacy-peer-deps“参数
    查看>>
    npm的安装和更新---npm工作笔记002
    查看>>
    npm的常用操作---npm工作笔记003
    查看>>
    npm的常用配置项---npm工作笔记004
    查看>>
    npm的问题:config global `--global`, `--local` are deprecated. Use `--location=global` instead 的解决办法
    查看>>