• 算法: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
  • 相关阅读:
    牵手时代少年团,来伊份讲了一个“新鲜”故事
    南大通用数据库-Gbase-8a-学习-19-Gbase8a从Kafka订阅Topic消费数据
    Dubbo 2.6.1升级
    ATmega128定时器设计的音乐门铃(标签-算法|关键词-工作模式)
    Unity多人同时在线海量玩家角色的架构与设计
    科技型中小企业认定条件
    七千字带你了解封装等机制
    6.2.3 【MySQL】InnoDB的B+树索引的注意事项
    kubectl使用及源码阅读
    开发Chrome插件,实现网站自动登录
  • 原文地址:https://blog.csdn.net/qq_40850839/article/details/127457271