程序员都会的五大算法之五(分支限界法),恶补恶补恶补!!!
前言
点击查看算法介绍
五大算法
- 分治算法
- 动态规划
- 贪心算法
- 回溯算法
- 分支限界算法
WX搜素"Java长征记"对这些算法也有详细介绍。
分支限界算法
一、算法概述
分支限界法其实类似于回溯法,也是一种在解空间树中搜索解的算法,区别在于
分支限界算法是搜索满足约束条件的一个解,或是在满足约束条件的解中找出使某一
目标函数值达到极大或极小的解,即在某种意义下的最优解。
界:
对于极大化问题即为当前得到可行解的最大值(极小化问题相反),极大化问题界的初值为 0 (极小化问题为对应最大值)。 得到更好的可行解时界也要随之进行更新。
代价函数(限界函数):
即就是确定问题上下界的一个函数,在搜索每个节点的时候都要进行一次界的确定,对于极大化问题是以该节点为根的子树所有可行解的值的上界 ( 极小化问题则为下界)
【对极大化问题父节点代价值不小于子节点的代价值 (极小化问题相反)】
停止分支回溯父节点的依据
- 不满足约束条件
- 对于极大化问题,代价函数值小于当前界(对于极小化问题是大于界)
界的更新
对于极大化问题,若一个新的可行解的值大于 (极小化问题为小于) 当前的界,则把界更新为该可行解的值
二、分支限界算法思想
- 求解目标:找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。
- 搜索方式:分支限界法一般采用广度优先遍历去进行搜索。
- 组织活节点表:在分支限界法中,每个活节点只有一次机会成为扩展结点。活节点一旦成为扩展节点,就一次性产生其所有儿子节点。在这些儿子节点中,导致不可行解或导致非最优解的儿子节点被舍弃(即就是剪枝过程),其余儿子节点被加入活节点表中。之后又从活节点表中取出下一扩展节点,重复进行扩展,直至找到所需解活活节点表为空。
四、常用扩展节点方法
队列式(FIFO)分支限界法
队列式分支限界法将活节点表组织成一个队列,并将队列的先进先出原则选取下一个节点为当前扩展节点。
优先队列式分支限界法
将活节点表组织成为一个优先队列,按照优先队列中规定的节点优先级选取优先级最高的节点成为当前扩展节点。
五、分支限界法VS回溯法
六、分支限界算法的实例
一一最大团问题
最大团问题
问题介绍
无向图G=<V,E>, 求G的最大团.例:给定无向图 G = < V, E >, 其中顶点集
V = { 1, 2, … , n },边集为 E . 求 G 中的最大团.
解释:
- G的子图:G’= <V ‘,E’>, 其中V '⊆V, E’⊆E
- G的补图:=<V, E’>, E’是E关于完全图边集的补集G
- G中的团:G 的完全子图
- G的最大团:顶点数最多的团
问题分析
代价函数:
目前的团可能扩张为极大团的顶点数上界F = Cn+ n − k其中 Cn 为目前团的顶点数(初始为0)k 为结点层数
实例
实例图解分析
解释:
- a: 极大团 {1,2,4},顶点数为 3, 界 B=3;
- b:代价函数值 F=3, 回溯;
- c: 极大团 {1,3,4,5}, 顶点数为 4,修改界 B=4;
- d: F=3,不必搜索; e: F=4, 不必搜索.
程序:
//最大团问题
package com.company;import java.util.*;
public class BiggestGroup {private static int v[][]={{0,1,1,1,1},{1,0,0,1,0},{1,0,0,1,1},{1,1,1,0,1},{1,0,1,1,0}};private static ArrayList<Integer> a=new ArrayList<>();//记录已选团中顶点private static ArrayList<Integer> bestA=new ArrayList<>();//记录最大团的顶点private static int n=v[1].length;//顶点个数private static int best,f,b;//best为上届,f为代价函数值,b为已选顶点数private static int x[]=new int [n];//记录顶点状态(不选-0 or 选-1)public static void main(String[] args){backTrace(0);System.out.println("最大团顶点个数为:"+best);output(bestA);}/*输出链表*/private static void output(ArrayList<? extends Integer> a) {Iterator<Integer> p= (Iterator<Integer>) a.iterator();while(p.hasNext()){System.out.print(p.next()+" ");}}/*广度优先遍历*/public static void backTrace(int t){/*到达叶节点*/if(t>=n){/*更新最优解*/if(b>best) {best = b;//更新界bestA.clear();//清空之前的解for(int i=0;i<a.size();i++)bestA.add(a.get(i));}return;}f=b+n-t;//代价函数/*进左子树*/if(f>best && isOk(t)){x[t]=1;a.add(t+1);b++;backTrace(t+1);b--;//回溯a.remove(b);}f=b+n-t;/*进右子树*/if(f>best){x[t]=0;backTrace(t+1);}}/*是否符合约束条件*/public static boolean isOk(int t){if(a==null || a.size()==0)return true;for(int i=0;i<a.size();i++){if(v[t][a.get(i)-1]==0)return false;}return true;}
}
时间复杂度
最坏时间复杂度为O(n2^n)
分支限界和回溯法的时间复杂度:W(n) = ( p(n) f(n) ) 其中 p(n) 为每个节点的
工作量f(n)为节点个数,最坏时间复杂度相对都比较大,但是平均复杂度因为剪枝过
程肯定降低了很多,优于蛮力算法。而且空间代价也较小。
干货分享
想学习更多的关于Java基础、算法、数据结构等编程知识的WX搜索"Java长征记"。上面的这些在里面也有详细介绍。
程序员都会的五大算法之五(分支限界法),恶补恶补恶补!!!相关推荐
- 程序员都会的五大算法之四(回溯算法),恶补恶补恶补!!!
前言 点击查看算法介绍 五大算法 分治算法 动态规划 贪心算法 回溯算法 分支限界算法 WX搜素"Java长征记"对这些算法也有详细介绍. 回溯算法 一.算法概述 回溯算法是一种择 ...
- 程序员都会的五大算法之三(贪心算法),恶补恶补恶补!!!
前言 点击查看算法介绍 五大算法 分治算法 动态规划 贪心算法 回溯算法 分支限界算法 WX搜素"Java长征记"对这些算法也有详细介绍. 贪心算法 一.算法概述 贪心算法也叫贪婪 ...
- 程序员都会的五大算法之一(分治算法),恶补恶补恶补!!!
前言 点击查看算法介绍 五大算法 分治算法 动态规划 贪心算法 回溯算法 分支限界算法 WX搜素"Java长征记"对这些算法也有详细介绍. 分治算法 一.算法概述 简单来说,分治算 ...
- 专访张俊林:十年程序员的感悟与算法之路
专访张俊林:十年程序员的感悟与算法之路 发表于2015-10-29 02:23| 3654次阅读| 来源CSDN| 2 条评论| 作者钱曙光 社区之星专访张俊林算法机器学习 width="2 ...
- 程序员编程艺术(算法卷):第一章、左旋转字符串
第一章.左旋转字符串 作者:July,yansha. 时间:二零一一年四月十四日. 说明:(狂想曲,有三层意思:1.思绪纷飞,行文杂乱无章,想到什么,记下什么.2.简单问题深入化,复杂问题精细化,不惧 ...
- 人工智能时代,程序员要不要精通算法?
1.如何入门算法?需要学习哪些基础知识,请分享你的经验与建议. 入门算法其实很简单,拿生活中的很多现实问题来解决就可以了.比如商场打折问题(是打折划算还是满减划算),百钱买百鸡.猴子分桃.鸡兔同笼等有 ...
- 程序员是否必须会算法
本章的标题既然是"程序员与算法",就必然要涉及一个基本问题,那就是"程序员是否必须会算法".这是一个充满争议的问题,虽然并不像"生存还是毁灭" ...
- php学数据结构,PHP 程序员学数据结构与算法之《栈》
介绍 "要成高手,必练此功". 要成为优秀的程序员,数据结构和算法是必修的内容.而现在的Web程序员使用传统算法和数据结构都比较少,因为很多算法都是包装好的,不用我们去操心具体的实 ...
- 程序员考核的五大死因
程序员考核的五大死因(上) 程序员作为企业开发力量的最核心资产,无疑得到公司从上至下的一致关注.开发是个智力密集型产业,程序开发的特点是,付出相同时间的情况下,两个开发者之间的产能会相差十几甚至几十倍 ...
最新文章
- 记一次网络共享打印机故障
- python使用pandas计算dataframe中每个分组的极差、分组数据的极差(range)、使用groupby函数和agg函数计算分组的最大值和最小值
- SESSION 回收机制
- 解决耳机插入电脑没声音问题
- 最实用的计算机系统清理加速,最实用的win7电脑清理垃圾方法分享
- 【hiho一下_week256】Diligent Robots
- 词根词缀sinu/sist/soci/sol/somn等词根衍生单词
- Tableau技巧(一)如何做分页预览
- Python编程从入门到实践(第三、四章的列表和元祖)
- [精华] [转贴]Curses函数说明(SCO)
- 华为交换机关机方法_取消华为交换机Console配置密码S2700\3700\5700\6700系列
- OpenCV中parallel_for 和 parallel_for_学习笔记
- 基于Node+Vue+Express开发实现商城系统
- 航海王燃烧意志如何修改服务器,航海王燃烧意志借号-航海王燃烧意志怎么改密码?ios版本手机账号...
- LeetCode 1488. Avoid Flood in The City - Java - 优先队列
- 随想录Day9--28. 实现 strStr() , 459.重复的子字符串
- 25岁员工突然离世:熬得起下半夜的人,却熬不起下半生!
- 蓝底白色 html,新交通标志讲解
- 49 简单句+并列句+复合句+状语从句的省略
- PLC和单片机有什么区别?什么是单片机?PLC又是什么意思?