• 算法:JavaScript语言描述


    14天阅读挑战赛
    努力是为了不平庸~
    算法学习有些时候是枯燥的,这一次,让我们先人一步,趣学算法!欢迎记录下你的那些努力时刻(算法学习知识点/算法题解/遇到的算法bug/等等),在分享的同时加深对于算法的理解,同时吸收他人的奇思妙想,一起见证技术er的成长~

    回溯

    当搜索到某一步时,如果原先的选择不是最优选择或者达不到目标,就回退一步重新选择,如果再不通就再退回重新选择的方法叫做回溯法。满足回溯条件的某个状态叫做回溯点。

    解题步骤:

    1. 确定解的形式和解空间
    2. 确定解空间的组织结构
    3. 搜索解空间

    解空间

    • 解空间是由所有的解组成的空间,可以通过定义解的组织形式和显约束确定解空间,解空间越小搜索效率越高,解空间越大搜索效率越低
      解的组织形式:使用回溯法得到的解的组织形式一般为n元的一维数组,达到目标的结果的表现形式
      可行结果
      显约束:对解分量的取值范围的限定

    解空间的组织结构

    • 解空间的组织结构:解空间按照树形结构显示叫做解空间树

    搜索解空间

    隐约束:对能否得到问题的可行解或最优解而做出的约束,如果不符合隐约束,说明当前分支不存在问题的解就没有必要搜索
    隐约束分为约束函数和限界函数。对能否得到问题的可行解的约束称为约束函数。对能否得到问题的最优解的约束称为限界函数。

    示例

    题目背景:把重量为w,价值为v的物品,逐个放进一个总容量为W的背包中,在不超过背包容量的情况下,使背包内的物品价值最大,求能够放进哪些东西?

    假设物品的重量和价值信息如下

    let weight = [10,20,3,7,9,15]
    let value = [23,30,10,14,15,25]
    
    • 1
    • 2

    根据之前的解题步骤,解题流程如下:

    1. 解空间:根据题目,求的是能够放进背包中的物品有哪几件,说明从一个集合中选择一个子集,因此,解空间就是一个集合,{x1, x2, ……, xn}
    2. 解空间的组织结构用树形结构表示
    3. 搜索解空间:
      • 约束条件:选择物品的重量总和小于等于背包容量
      • 限界条件:选择物品的重量总和小于等于背包容量且总价值最大
    let weight = [10, 20, 3, 7, 9, 15];
    let value = [23, 30, 10, 14, 15, 25];
    // 对应索引的物品是否装入,1表示装入,0表示不装入
    let x = [0, 0, 0, 0, 0, 0];
    // 当前最优解集合
    let bestx = [];
    // 当前最优值
    let bestv = 0;
    // 当前放入背包的物品的总价值
    let cv = 0;
    // 当前放入背包的物品的总重量
    let cw = 0;
    // 背包的总容量
    let W = 40;
    // 节点的层次
    let n = 6;
    // 计算价值上界
    function bound(i) {
      let rp = 0;
      while (i < n) {
        rp += value[i];
        i++;
      }
      return rp;
    }
    //回溯法,t为层次
    function backtrack(t) {
    //到达叶子
      if (t >= n) {
        for (let j = 0; j < n; j++) {
        //记录最优解
          bestx[j] = x[j];
        }
         //记录最优值
        bestv = cv;
        return;
      }
      //如果满足约束条件,则搜索左子树
      if (cw + weight[t] <= W) { 
        x[t] = 1;
        cw += weight[t];
        cv += value[t];
        backtrack(t + 1);
        //还原现场 
        cw -= weight[t];
        cv -= value[t];
      }
      //如果满足限界条件,则搜索右子树
      if (bound(t + 1) > bestv) {
        x[t] = 0;
        backtrack(t + 1);
      }
    }
    
    backtrack(0);
    console.log(bestx);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
  • 相关阅读:
    机器人流程自动化(RPA)如何提升用户体验?
    c++实现观察者模式
    gRPC服务的定义和服务的种类
    Springboot毕设项目基于SpringBoot的演唱会购票系统z2673(java+VUE+Mybatis+Maven+Mysql)
    【微服务保护】Sentinel 流控规则 —— 深入探索 Sentinel 的流控模式、流控效果以及对热点参数进行限流
    【Cocos新手进阶】通过cocos实现可控制的动态加载更新的日志界面效果
    AcWing 数据结构
    【LeetCode刷题】146. LRU 缓存
    2023年第四届MathorCup大数据竞赛(A题)|坑洼道路检测和识别|数学建模完整代码+建模过程全解全析
    Rhodamine/Cy3/Cy3.5/Cy5/FITC荧光素标记羧甲基纤维素CMC/羧甲基壳聚糖/羧甲基凝胶多糖
  • 原文地址:https://blog.csdn.net/qq_40850839/article/details/127457271