分支限界法

1. 基本思想

分支是使用广度优先策略,依次生成扩展结点的所有分支
限界是在结点扩展过程中,计算结点的上界,搜索的同时剪掉某些分支
分支限界法就是把问题的可行解展开,再由各个分支寻找最佳解。
与回溯法类似,分支限界法也是在解空间中搜索得到解;
不同的是,分支限界法会生成所有扩展结点,并舍弃不可能通向最优解的结点,然后根据广度优先/最小耗费优先,从活结点中选择一个作为扩展结点,使搜索向解空间上有最优解的分支推进。

2. 搜索策略

分支限界法首先生成当前扩展结点的所有分支,然后再从所有活结点中选择一个作为扩展结点。每一个活结点都要计算限界,根据限界情况判断是否剪枝,或选择最有利的结点。
分支限界法有两种不同的搜索空间树方式,分别为广度优先最小耗费优先,它们对应两种不同的方法:

  1. 队列式分支限界法(FIFO)
    常规的广度优先策略。按照先进先出的原则选取下一个扩展结点,以队列储存活结点。
  2. 优先队列式分支限界法/最小耗费优先分支限界法(LC)
    按照优先队列中指定的优先级,选取优先级最高的结点作为下一个扩展结点,以优先队列储存。

分支限界法的具体搜索策略如下:

  1. 根结点入队;
  2. 根据使用的方法(FIFO或LC),令一个活结点出队,作为扩展结点
  3. 对扩展结点,生成所有的分支;使用约束条件舍弃不可行的结点/不可能为最优解的结点,剩余的结点入队;
  4. 重复2和3,直到找到要求的解队列为空
方法 搜索策略 存储结点常用结构 结点存储特性 应用问题
回溯法 深度优先 结点可以多次成为扩展结点,所有可行子结点都遍历后才弹出 找出满足条件的所有解
分支限界法 广度/LC优先 队列/优先队列 结点只能成为一次扩展结点,剪枝或扩展后立刻出队 找出条件下的某个/最优解

3. 分支结点选择

所有界限满足上界/下界的结点都可以作为扩展结点。因此,必须有一个分支选择策略,FIFO法和LC法对应两种策略:
● 按顺序选择结点作为下一次的扩展结点。优点是节省空间,缺点是需要计算的分支数较多,时间花费大;
● 每次计算完限界后,找出限界最优的结点,作为下一次的扩展结点。优点是计算的分支数少,缺点是需要额外空间。

4. 限界函数

限界函数很大程度上决定了算法的效率。同一问题可以设计不同的限界函数。
FIFO分支限界法中,常以约束条件作为限界函数,满足约束条件才可入队,不满足约束条件的舍弃。
LC分支限界法中,还可以设计一个启发函数作为限界函数。
对于有约束的问题,FIFO法和LC法均可以求解;对于无约束问题, 宜使用LC法。

例题:单源最短路径

1. 问题描述

给定带权有向图G,每边的权值是一个正实数,表示点到点的路径距离。给定图中的一个源点V,求图G中所有点到源点V的最短路径。

2. 问题分析

除了用Dijkstra算法(贪心)解决该问题外,也可以使用分支限界法。由于要求的是最短的路径,我们考虑使用优先队列式分支限界法,以减少计算的分支数。显然,我们的限界就是源到目的点的路径长度:若源到同一个顶点有多条路径,将长路径的分支全部舍弃,而保存更短路径的分支。并且由于题目的贪心选择性质,每次从优先队列中取最短路径,最终得到的解也必然是最优的。

为了避免出队列可能造成的异常,并能更有规律地处理优先队列,我们为最小堆构造一个长度等同于顶点个数的结点数组。数组元素的下标对应顶点的编号;数组元素的编号为-1时,代表该结点被删除(出队列)。

3. 算法设计

  1. 生成根节点的所有分支,全部入队列并记录路径;
  2. 在队列中选择路径最短的分支作为扩展结点
  3. 逐个生成分支,并判断分支的路径是否小于记录的最短路径;
  4. 若不小于,舍弃该分支;
  5. 若小于,该分支入队列;
  6. 生成所有分支后,回到2;
  7. 当队列为空时,算法结束。

4. 算法实现

//单源最短路径class Graph{ //带权有向图
private:int n;          //顶点个数int **c;      //邻接矩阵int *dist;        //记录路径
public:void shortestPaths(int);Graph();         //根据情况构造图
};class MinHeapNode{        //最小堆的结点friend Graph;
private:int i;              //结点对应的顶点编号int length;          //结点记录的最短路径
public:int getI(){ return i; }void setI(int i){ this->i = i; }int getLength(){ return length; }void setLength(int length){ this->length = length; }
};class MinHeap{        //最小堆(虽然叫堆,但其实并不是用堆实现的)friend Graph;
private:int length;         //最小堆的长度,等同于顶点个数MinHeapNode *nodes;      //结点数组
public:MinHeap(int n){this->length = n;nodes = new MinHeapNode[n];}void deleteMin(MinHeapNode&);   //令当前节点出队列,并给出下一个扩展结点void insertNode(MinHeapNode N)      //结点入队列,将原结点的内容替换即可{nodes[N.getI()].setI(N.getI());nodes[N.getI()].setLength(N.getLength());}bool outOfBounds()      //检查队列为空{for(int i = 0;i < length;i++)if(nodes[i].getI() != -1)return false;return true;}
};void MinHeap::deleteMin(MinHeapNode &E)
{int j = E.getI();nodes[j].setI(-1);nodes[j].setLength(-1);        //标记为出队列int tmp = INT_MAX;for(int i = 0;i < length;i++){     //给出路径最短的结点作为扩展结点if(nodes[i].getI() != -1 && nodes[i].getLength() < tmp){E.setI(i);E.setLength(nodes[i].getLength());tmp = nodes[i].getLength();}}
}void Graph::shortestPaths(int start)
{MinHeap heap = MinHeap(n);    MinHeapNode E = MinHeapNode();     //别问,一开始还加了new,太久不写C++了E.i = start;    E.length = 0;dist[start] = 0; //初始为源点V,对应编号startwhile(true){for(int j = 0;j < n;j++){   //检查所有邻接顶点if(c[E.i][j] != 0){      //是否邻接if(E.length + c[E.i][j] < dist[j]){       //是否满足限界,当前路径小于记录的最短路径dist[j] = E.length + c[E.i][j];      //更新if(/*填入判断表达式*/){          //没有邻接顶点的点不入队,按情况调整,没有也可以,但会造成无效开销MinHeapNode N = MinHeapNode();    //创建一个新的结点,并令其入队列N.i = j;N.length = dist[j];heap.insertNode(N);}}}}if(heap.outOfBounds())  //队列为空,结束break;heap.deleteMin(E);    //该结点已经生成全部分支,出队列并取得下一扩展结点}
}

为使队列为空,while循环总共需要取n个结点;每个结点要对所有结点都进行检查。因此算法的时间复杂度为O(n2)

分支限界法的套路单一,就只写一道例题了,怎么可能是因为这两天沉迷骑砍呢

算法分析与设计:分支限界法相关推荐

  1. 算法分析与设计期末总结

    这是我的算法分析与设计课程自己总结的一些知识点,应该不太全,记录一下 算法的特征: 输入,输出,确定性,有穷性,可行性 基本数据结构: 线性,树结构,图结构,集合   递归与分治 1.递归法 使用递归 ...

  2. 南邮《算法分析与设计A》2018-2019学年第一学期期末考试回忆

    2019.1.8 13:30-15:20 <算法分析与设计A>考试 刚考完,回忆一下题目. 先总结一下:感觉难度完全不是自己想象的那样,没时间检查,好多不确定不会做.主要还是自己复习的不好 ...

  3. NJUPT算法分析与设计期末考试202.12.1

    NJUPT算法分析与设计期末考试2021.11.24 判断 简答 1.算法是什么?算法的时间复杂度是什么?衡量的原则,标准,工具 2.分支限界法扩展活节点的方式有哪两种,有什么差别? 3.回溯法搜索子 ...

  4. 国防科大计算机考博大纲,2020年国防科技大学算法分析与设计考博大纲

    国防科技大学2020年博士研究生入学考试自命题科目考试大纲 3A03<算法分析与设计>考试大纲 一.参考书目 1.<算法设计与分析基础>,Anany Levitin著,潘彦 译 ...

  5. 《算法分析与设计》学习心得

    在学习了<算法分析与设计>这门课后,我对常见的算法有了一个基本的了解.本书主要从算法概述.递归与分治策略.动态规划.贪心算法.回溯法.分支限界法.随机化算法.线性规划与网络流.NP完全性理 ...

  6. 程振波 算法设计与分析_算法分析与设计之动态规划

    动态规划同样是一种将问题分解为求解子问题的方法,不过与分治不同的是,动态规划算法的子问题不是相互独立的,而是有公共的部分,即有重叠子问题,这个时候使用分治算法,将会重复计算公共的子问题,效率很低!而用 ...

  7. 一本好的教辅,可以少走很多弯路:算法分析和设计 王晓东

    算法分析和设计 王晓东 我觉得第三版JAVA版本最好,第4版是C++版本,删减了几章. 可以配合北大屈婉玲教授的视频课程一起看 自己走了一些弯路,希望后续的可以避免以下 下载地址如下,也可以淘宝买本二 ...

  8. 非计算机专业教学改革,非计算机专业算法分析与设计教学改革论文

    非计算机专业算法分析与设计教学改革论文 [摘要]算法分析与设计不仅是计算机专业的核心课程,同时也是与计算机有关的非计算机专业的专业课.本人针对非计算机专业学生在学习过程中存在的若干问题,就教学内容.教 ...

  9. 《算法分析与设计》课程任务

    <算法分析与设计>课程任务 内容包括以下8个部分,建议将任务按以下方式分解:其中1-6的每个部分的简介.适用条件.基本思想.基本步骤.复杂度分析等由1人讲解,实例分析由1人讲解(注:至少一 ...

  10. 用c语言验证装载问题 回溯法,《算法分析与设计》期末考试复习题纲(完整版)...

    <算法分析与设计>期末复习题 一.选择题 1. 算法必须具备输入.输出和( D )等4个特性. A.可行性和安全 性 B .确定性和易读性 C.有穷性和安全 性 D .有穷性和确定性 2. ...

最新文章

  1. 帝国cms微信商城小程序之多规格颜色尺寸长度等sku弹出层模块封装调用
  2. python操作手机app_【Python】[技术博客] 一些使用Python编写获取手机App日志的操作...
  3. mysql增删改查 dao_MYSQL 之 JDBC(七):增删改查(五) DAO设计模式
  4. v 3437 powered by ipb_奔驰V系改装订制版 目前最安全的商务车_凤凰网汽车
  5. 用border画三角形
  6. 虚拟货币公有链项目集体爆发,AE超过历史最高点
  7. 微软9月补丁星期二值得关注的0day、终于落幕的 PrintNightmare及其它
  8. 在WINCE中的一些VB.NET2005通用方法
  9. 建立 CLR Stored Procedure/Function 的小範例
  10. elasticsearch 匹配发音相同单词的方案
  11. NXP S32G2开发
  12. 虚拟机安装CentOS系统教程(详细)
  13. 8.2 一些代数知识(群、循环群和子群)
  14. 计算机添加本地安全组用户名和密码错误,u租号总是密码错误-共享用户名和密码正确总提示错误...
  15. 网站外链建设:论坛签名外链还值得做吗?
  16. Ubuntu 修改用户名
  17. 教资必备的5大证件,丢失后该如何补办?
  18. 【linux】血泪经验,在安装Linux上一定要创建/data 分区,将数据盘和系统盘分开,方便重新安装系统,随时恢复Linux系统,其实特别简单,还有7个常用技巧
  19. APP攻防——微信小程序解包反编译数据抓包APK资源提取
  20. 政务大数据解决方案之大快DKhadoop

热门文章

  1. MySQL中IF函数的使用方法
  2. windows python 运行不起来_windows不兼容,还在用双系统运行以前的老游戏?教你一招简单的...
  3. 中华民族究竟经历了怎样的一段历史(转帖)
  4. 【深度学习】关于深度学习,金融交易的切入点是什么?
  5. Tensorflow训练神经网络保存*.pb模型及载入*.pb模型
  6. linux禁用网络连接wifi,禁用IPv6,解决Debian8系统无线网络掉线问题
  7. Google 架构之学习 ZT 原文:Google Architecture
  8. 区块链读书笔记02 - 区块链进阶
  9. 由华晨宇怼李袁杰谈谈什么是「职业素养」
  10. 如何将图片中文字转为WORD文档可编辑