算法介绍

分支界限法:

分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,导致不可行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩展过程。这个过程一直持续到找到所需的解或活结点表为空时为止。

与回溯法的区别:

(1)求解目标:回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。
(2)搜索方式的不同:回溯法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树。

常见的两种分支限界法:

(1)队列式(FIFO)分支限界法
  按照队列先进先出(FIFO)原则选取下一个结点为扩展结点。
(2)优先队列式分支限界法
  按照优先队列中规定的优先级选取优先级最高的结点成为当前扩展结点。

问题实例

问题描述:

题目:
请用队列式分支限界法求解装载问题,设7个集装箱的重量分别为:
90 80 40 30 20 12 10
船的重量限制为:152

问题分析:

题目要求使用队列分支界限法求解该题目,首先我们需要找到向队列中放的元素是什么,在本题中我们以比较轮船装入的集装箱重量是否超出载重量为判断依据,所以选择轮船当前的载重量为队列中的元素。
当装入该集装箱符合边界条件时,生成新的结点加入队列,并用一个特定的字符记录层数(即逐步判断7个集装箱)。当从队列中取出该字符时进入下一层,并再将新的特定字符加入队列,以便再次进入下一层。

伪代码:
①先将特定字符 NULL 加入队列,通过构建二叉树求解最优装载,设一个根节点,无装载量,代表此时轮船为空。
②判断第一个集装箱能否装的下,如果装的下,生成一个新的结点,该结点的重量为此时轮船的载重量,并通过指针让新结点的父亲指针指向根节点,记录此时装入,记为1。
③如果装不下,判断此时未放该集装箱的轮船重量加上剩余的集装箱重量是否大于此时的最优载重量。若大于,则有可能存在不放该集装箱仍能达到最优载重,生成新的结点,加入队列并记录此时不装入,记为0;若小于,则这条路行不通,修剪。
④完成第一个集装箱的判断后,从队首取第一个元素,如果第一个元素为 NULL ,则进入下一层(再取队首元素)进行下一个集装箱的判断(此时使用 Java 的 queue.remove 方法,取出队首元素时,该元素已出队列),并向队列中再加入 NULL 以便再进入下一层。
⑤循环步骤④,直到队列为空。
⑥利用构建的最优装载二叉树,输出每个节点记录的选择结果,对应输出选择的集装箱。
如下:

代码:

package 分支限界法;import java.util.LinkedList;
import java.util.Queue;public class Zhuangzai {private class Node {Node father; //父亲结点Boolean fathersleftchild; // 父亲结点的左子树,1 代表选择,0代表不选择int weight; // 达到该结点的重量public Node(Node father,int weight,Boolean fathersleftchild) {this.father = father;this.weight = weight;this.fathersleftchild = fathersleftchild;}}int n;int w[];int c;//输入集装箱个数和重量以及轮船1最大载重量public Zhuangzai (int n, int w[], int c){this.n=n;this.c=c;this.w=w;this.bestx=new int[n+1];}Node bestE=null; //最优叶子结点的父亲结点int bestW=0;  //最优载重量int wt=0;   //当前的载重量int bestx[];//最优解// 创建队列Queue<Node> queue= new LinkedList();// 构建解空间(树)private void EnQueue (int i,Node father,int weight,Boolean fathersleftchild){//如果达到叶子节点if(i==n){//如果此时达到最优载重量if(weight==bestW){bestE = father;bestx[n]=(fathersleftchild)?1:0;}}else{//创建新的结点Node b = new Node(father, weight, fathersleftchild);//加入队列queue.add(b);}}// 判断是否装入private void forQueue (){int i=1;Node A = new Node(null, 0, true);Node e = A;bestE = A;queue.add(null);int remainder =0;for (int j=2;j<=n;j++){remainder=remainder+w[j];}int ew = 0;// 当前重量while(true){wt = ew + w[i];// 判断是否加入左子树if(wt<=c){if(wt>bestW){bestW=wt;}// 扩展结点EnQueue(i, e, wt, true);}//判断是否进入右子树if(ew+remainder>bestW){EnQueue(i, e, ew, false);}//取队列的第一个结点并出队列e = queue.poll();if(e==null){if(queue.isEmpty())break;queue.add(null);//取第一个结点并出队列 进入下一层e = queue.remove();i++;remainder=remainder-w[i];}ew = e.weight; }for(int j=n-1;j >0; j--){bestx[j] = (bestE.fathersleftchild)?1:0;bestE = bestE.father;}}public static void main(String[] args) {int n=7;int c=152;//船1承载重量int[] w= {0,90 ,80 ,40 ,30 ,20 ,12 ,10};//集中箱i的重量Zhuangzai fifoLoading=new Zhuangzai(n,w,c);fifoLoading.forQueue();System.out.println("轮船1的最大载重量为:"+fifoLoading.bestW);System.out.println("装载的集装箱重量为:");for(int i=1;i<=n;i++){if(fifoLoading.bestx[i]==1){System.out.print(w[i]+" ");}}}}

结果:

解决该问题的关键是设计一个特定的字符,以此来判断是否可以进入下一层,在每次从队首提取出该特定字符时,再将其加入队列中,这样就解决了逐个判断集装箱是否可以装入轮船问题。

记录整理一些学习中的问题,如果有不恰当和错误的地方,欢迎批评指正~

算法设计-分支界限法——装载问题相关推荐

  1. 算法分析与设计第二版(李春葆)第六章分支界限法

    分支界限法类似于回溯法,一般回溯法目标是找出所有解,二分支界限法是找出满足条件的一个解或者最优解 算法 解空间树搜索方式 存储结点的常用数据结构 结点存储特性 常用应用 回溯法 深度优先搜索 栈 活结 ...

  2. 五大常用算法——分治法,动态规划,回溯法,分支界限法,贪心算法

    (1) 分治法 将一个难以直接解决的大问题,分割成一些规模较小的相同问题 快速排序 快排也是分治的一个实例,快排每一趟会选定一个数,将比这个数小的放左面,比这个数大的放右面, 然后递归分治求解两个子区 ...

  3. 算法分析课设(十一)博物馆守卫问题、世界名画陈列馆问题(分支界限法)

    免责声明 不想打字了.. 题目 在某博物馆中摆放了非常重要的文物,为了节省人力,该博物馆专门购买了警卫机器人来看管这些文物.该博物馆的房间排列整齐,房间的大小相同.每个警卫机器人能够巡查的范围除本身所 ...

  4. 从0-1背包问题学习回溯法、分支界限法、动态规划

    一.0-1背包问题的描述 下面将使用回溯法.分支界限法.动态规划法来分析和解决此问题. 二.回溯法 (1)算法步骤 (2)代码如下(没有裁剪函数): 用i和n来判断结束与否,是因为解空间结构是完全二叉 ...

  5. 最大团问题-分支界限法

    最大团问题-分支界限法 遍历所有点构造二叉树: 广度遍历树,遍历过程中判断当前结点的点数据时,是否构成完全子图,如果不能则只将右结点加入队列,每次选取队列中完全子图最大的结点作为活结点,无子结点时到达 ...

  6. 0x08算法设计与分析复习(二):算法设计策略-回溯法2

    参考书籍:算法设计与分析--C++语言描述(第二版) 算法设计策略-回溯法 子集和数 问题描述 已知n个不同的正数wi(0≤i≤n−1)的集合,求该集合的所有满足条件的子集,使得每个子集中的正数之和等 ...

  7. 单源路径分支界限java_单源最短路径-分支界限法

    单源最短路径-分支界限法-优先队列式.这里使用无回路的有向图,便于构建树.构建好树后,从根结点作为起始源,加入结点队列,然后判断获取队列中最短的路径结点做为活结点,将活结点的所有子结点加入队列,移除活 ...

  8. 旅行售货员问题 java_旅行售货员问题-分支界限法

    旅行售货员问题分支界限法 package test; import java.util.ArrayList; import java.util.Collections; import java.uti ...

  9. python算法设计 - 埃拉托色尼筛选法

    python算法设计源码:https://github.com/MakerChen66/Python3Algorithm 版权声明:原创不易,本文禁止抄袭.转载,侵权必究! 目录 一.埃拉托色尼筛选法 ...

最新文章

  1. DPKG命令与软件安装、APT
  2. 3.爱跑步的蜗壳人动态(下同)
  3. tensorflow随笔-collection收集器
  4. Swift之深入解析如何在Swift中实现状态机
  5. hibernate实体的几种状态:
  6. TX2下编译qt程序步骤
  7. 论文浅尝 - EMNLP2020 | 基于规则引导的协作 agent 知识图谱推理学习
  8. 无法获取未定义或 null 引用的属性“text”_【CSS】是时候开始用 CSS 自定义属性了...
  9. java程序员编程过程中的基本问题
  10. python重新安装_重新安装python
  11. https://127.0.0.1:8080/test?param={%22..报错
  12. Spring Cloud Alibaba Sentinel之流控规则篇
  13. DIP 电源跌落瞬时中断(Voltage dips)
  14. weblogic 部署应用步骤
  15. 【CRM】开源CRM
  16. 网站被挂马的解决方案
  17. 可搜索加密简要介绍与相关概念
  18. 【如何从外观上区分网线的五类线、超五类线和六类线?】
  19. 仿京东商城商品分类搜索功能
  20. Cannot overwrite File XXX/xxx/xx/x/x/x.xxx:Permission denied

热门文章

  1. 【数据分析】利用机器学习算法进行预测分析(五):Prophet
  2. [小说]魔王冢(尾声)
  3. ogg登陆数据库用户密码加密
  4. html实现好看的个人介绍,个人主页模板4(附源码)
  5. 5min搭建SSM项目
  6. 教你如何用家里闲置的Windows电脑搭建GPU服务器炼丹(无公网IP)
  7. 玻璃钢风机的性能介绍
  8. addEventListener() 方法
  9. 【Android 学习】实现仿360悬浮窗
  10. 目标检测算法实现(八)——YOLOV5学习笔记