有趣的回溯法寻求最优解

回溯法

回溯法(深度优先搜索)作为最基本的搜索算法,其采用了一种"一只向下走,走不通就掉头"的思想(体会"回溯"二字),相当于采用了先根遍历的方法来构造搜索树。

题目

设某一机器由n个部件组成,每一个部件都可以从m个不同的供应商处购得。供应商j供应的部件i具有重量wij和价格cij。设计一个算法,求解总价格不超过上限cc的最小重量的机器组成

解答思路(来源于题目答案)

首先定义解空间。

解空间由长度为n的向量组成,其中每个分量取值来自集合{1,2,...,m),将解空间用树形结构表示。

接着从根结点开始,以深度优先的方式搜索整个解空间。
从根结点开始,根结点成为活结点,同时也成为当前的扩展结点。向纵深方向考虑第一个部件从第一个供应商处购买,得到一个新结点。判断当前的机器价格(c11)是否超过上限(cc),重量(w11)是否比当前已知的解(最小重量)大,若是,应回溯至最近的一个活结点;若否,则该新结点成为活结点,同时也成为当前的扩展结点,根结点不再是扩展结点。
继续向纵深方向考虑第二个部件从第一个供应商处购买,得到一个新结点。同样判断当前的机器价格(c11+c21)是否超过上限(cc),重量(w11+w21)是否比当前已知的解(最小重量)大。若是,应回溯至最近的一个活结点;若否,则该新结点成为活结点,同时也成为当前的扩展结点,原来的结点不再是扩展结点。
以这种方式递归地在解空间中搜索,直到找到所要求的解或者解空间中已无活结点为止。

代码

n:机器的部件数

m:供应商数

cc:价格上限

w\[\]\[\]:二维数组,wij表示第j个供应商供应的第i个部件的重量

c\[\]\[\]:二维数组,ciD.表示第j个供应商供应的第i个部件的价格

bestW:满足价格上限约束条件的最小机器重量

bestC:最小重量机器的价格

bestX\[\]:最优解,一维数组,bestXi表示第i个部件来自哪个供应商

cw:搜索过程中机器的重量

cp:搜索过程中机器的价格

x\[\]:搜索过程中产生的解,xi表示第i个部件来自哪个供应商

i:当前考虑的部件,从0到n-1

j:循环变量

c 复制代码
	int n=3;
    int m=3;
    int cc=4;
    int w[3][3]={{1,2,3},{3,2,1},{2,2,2}};
    int c[3][3]={{1,2,3},{3,2,1},{2,2,2}};
    int bestW=8;
    int bestC=0;
    int bestX[3]={0,0,0};
    int cw=0;
    int cp=0;
    int x[3]={0,0,0};
    
    int backtrack (int i){
    int j=0;
    int found=0;
    if(i>n-1){  /*得到问题解*/
        bestW=cw;
        bestC=cp;
        for(j=0; j<n;  j++){
          bestX[j]=x[j];
        }
  		return 1;
    }
    if (cp <=cc)(/*有解*/
        found=1;
    }
    for(j=0;  j<m ; j++){
    /*第i个部件从第j个供应商购买*/
      x[i]=j  ;
        cw=cw+w[i] [j];
        cp=cp+c[i] [j];
    if (cp<=cc && cw<= bestW ){/*深度搜索,扩展当前结点*/
        if (backtrack(i+1)){    found =1;   }
    }
    /*回溯*/
    cw=cw - w[i] [j];
    cp=cp-c[i][j] ;
    }
      return found;
  }

个人分析

回溯算法最大的魅力在于使用一个函数实现了纵向和横向的组合对比,实现最终的最优解。

先看 for(j=0; j<m ; j++),m是供应商,那么这里是部件遍历供应商,然后继续看backtrack(i+1),这里就是实现了递归算法计算下一个部件,那么下一个部件也会遍历所有供应商,而剩余的代码就是处理递归结束,最优计算和回溯方面的事情。

这里还有一个很有趣的地方在于cw和cp这种暂存,bestW和bestC是最终结果,只有当所有部件统计结束的时候进行一次修改,也就是递归结束的地方,cw和cp在每次递归出来后,会对当前添加的值进行回溯,从而实现了当前部件的统计进入下一个供应商的遍历,但是这个时候并不会影响到其他部件的统计值,这里的设计非常有趣。

相关推荐
依然鸣9 小时前
PTA团体程序设计天梯赛L2真题讲解L2-001-004
经验分享·学习·算法·深度优先·pat考试
杨航 AI11 小时前
** AI 面试算法 50 题清单**,不是单纯的 LeetCode 题号列表,而是按照“**考察概率 × 面试价值 × 你当前准备方向**”排序
算法·leetcode·面试
m0_7202450117 小时前
1543.统计好三元组(简单)
开发语言·算法
To_OC18 小时前
LC 560 和为 K 的子数组:前缀和配哈希表,这对组合我是真的服了
javascript·算法·程序员
hans汉斯19 小时前
《软件工程与应用》期刊推荐&10月版面征稿中
图像处理·人工智能·深度学习·算法·音视频·软件工程
叠层归一研究院19 小时前
AGI 系统(八):符号范畴嵌入函子 — SymCat ↪ C_M107 严格化
c语言·开发语言·人工智能·算法·transformer·agi
其美杰布-富贵-李20 小时前
08 进阶评估指标与算法特定指标
人工智能·算法
.道阻且长.20 小时前
5.LeetCode算法习题讲解--双指针--有效三角形的个数
算法·leetcode·职场和发展
我是海飞21 小时前
杰理JL703N SSD1306 OLED(128x64) 点阵屏移植说明
单片机·算法·嵌入式·音频·杰理
wabs66621 小时前
关于图论【最短路径之Bellman_ford 算法(单源有限最短路)|卡码网96.城市间货物运输III的思考】
数据结构·算法·图论·卡码网·bellman_ford·单源有限最短路