浅谈分支限界算法

1. 定义:

分支限界算法是按照广度优先的方式对解空间树(状态空间树)进行搜索,从而求得最优解的算法。在搜索的过程中,采用限界函数(bound function)估算所有子节点的目标函数的可能取值,从而选择使目标函数取极值(极大值或者极小值)的节点作为扩展结点(如果限界值没有超过目前的最优解,则剪枝)进行下一步搜索(重复 BFS -> 计算所有子节点限界 -> 选择最优子节点作为扩展结点的过程),从而不断调整搜索的方向,尽快找到问题的最优解。

(ps:回溯算法求出满足约束的所有可行解,分支限界求出满足约束的解中使得目标函数达到极值的最优解)

分支限界的思想类似于:图的广度优先搜索,树的层序遍历。

2. 分支限界算法和回溯算法的不同点:

(1)分支限界算法与回溯算法在子结点的扩展方式上不同:

回溯一般采用轮流遍历子节点的方式扩展结点。

分支限界则采用活结点的方式,一次性对所有的可行子节点进行扩展,估算子节点目标函数的可能值,如果该子节点的目标函数值差于当前最优解,则丢弃;否则将其加入活叶子表,依次从表中选取使目标函数取极值的节点作为当前的扩展结点。重复这一过程,直到找到最优解。

(2)分支限界算法与回溯算法在解空间树的搜索方式上不同:

回溯采用深度优先搜索的方式去搜索解空间树。搜索过程中,对所有的子节点轮流进行深度优先搜索,一旦发现有不满足约束的子节点,则对该子节点为根的子树进行剪枝;否则就从该子节点深度优先搜索,直到搜索到一个满足约束条件的叶子节点,即求得一个可行解。

分支限界采用广度优先搜索的方式去搜索解空间树。搜索过程中,先生成所有的子节点(分支),然后对所有分支计算一个函数值(限界),并根据这些函数值(计算出的上界或者下界),从中选择一个使目标函数最优(限界最优)的子节点作为扩展结点,使得搜索朝着最优解的方向快速推进,从而很快求得一个最优解。(ps:我的理解是每次从所有子节点中找出一个最有潜力的,作为扩展结点进行下一次的BFS

3. 分支限界算法的一般步骤:

(1)将问题的解空间转化为图或者树的结构表示,维护一张活叶子表(可以是优先队列)。

(2)初始将根节点计算一个限界后加入活叶子表。

(3)当活叶子表不为空时,从活叶子表中取出一个限界最优的结点作为扩展结点,并将该节点去除出表。当活结点表为空时,算法结束。

(4)判断当前的扩展结点是否可以满足所有约束,并且得到一个可行解(该扩展结点是叶子节点)。

如果是,判断优于当前最优解后,记录并更新最优解,随后将当前最优解与所有活叶子节点的限界做比较,对于限界差于最优解的活叶子结点,去除出活叶子表,并返回(3)。

如果不是,则进入(5)。

(5)计算扩展结点的所有子节点是否满足约束条件,对于不满足约束条件的子节点,将以该节点为根的子树剪枝(丢弃)。

(6)根据限界函数,计算该节点满足约束的所有子节点的限界。对于限界差于当前最优解的子节点(ps:废了,没潜力),将以该子节点为根的子树丢弃对于限界优于当前最优解的子节点(ps:还有潜力),将这些潜力节点作为活叶子结点添加到活叶子表,并返回(3)

(ps:对于上述步骤的推导,参考了《算法分析与设计基础》12.2 分支限界法 )

4. 分支限界算法应用的难点:

(1)解空间的构造,即状态空间树的构造方法(节点的生成顺序)

(2)剪枝函数的确定,即约束规则的确定

(3)限界函数的确定,边界的评估方法

原文地址:https://www.cnblogs.com/ladawn/p/8496338.html

时间: 2024-10-09 19:16:52

浅谈分支限界算法的相关文章

hdu1875浅谈prim算法的朴素实现

阅读原题 题目大意 给你几个(<=100)小岛的坐标,然后你把所有的岛都修上桥连接起来,求最小花费,还有个附加的限制:只有岛之间的距离大于等于10,或小于等于1000时才能修桥. 大概是因为十米以内不用建桥,千米以上无法建桥.哈哈,说着玩的. 很明显这是一道MST(最小生成树)的题目,貌似也有人用并查集AC过. 最小生成树算法 概述 最小生成树的常用算法有两个kruskal和prim算法.两者都是不停地执行归并操作,然而一言以蔽之,两者的不同之处在于:kruskal----归并边:prim---

浅谈分词算法(2)基于词典的分词方法

[TOC] 前言 在浅谈分词算法(1)分词中的基本问题中我们探讨了分词中的基本问题,也提到了基于词典的分词方法.基于词典的分词方法是一种比较传统的方式,这类分词方法有很多,如:正向最大匹配(forward maximum matching method, FMM).逆向最大匹配(backward maximum matching method,BMM).双向扫描法.逐词遍历法.N-最短路径方法以及基于词的n-gram语法模型的分词方法等等.对于这类方法,词典的整理选择在其中占到了很重要的作用,本

浅谈分词算法(1)分词中的基本问题

[TOC] 前言 分词或说切词是自然语言处理中一个经典且基础的问题,在平时的工作中也反复的接触到分词问题,用到了不同的模型,不同的方法应用在各个领域中,所以想对分词问题做一个系统的梳理.大多数分词问题主要是针对类似汉语.韩语.日语等,词语之间并没有天然的分割,而像英语等,句子中是带有天然的分割的.但是英语也会涉及到分词问题,比如实体识别.词性标注等内容.而本系列文章更多的是讨论汉语中的分词问题,首先我们从分词问题的基本出发,之后从传统的词典分词到将分词转为序列标注问题的分词,以及最新的结合深度学

浅谈欧洲算法——模拟退火

初听说退火这个名词感觉就很(zhuang)帅(A__CDEFG...) 直到学了退火之后,我才发现: 退火不只是帅,而且非常万能 甚至比 D (大) F (法) S (师)还要万能 简直就是骗(de)分神器啊 简介 作为一个计算机算法,它竟然在百度上有物理词条! 当时我看了就懵了,你说计算机一个算法,跟冶炼金属有什么关系啊? 后来我看了算法的词条... 是不是更懵了... 方便大家理解(变得更懵),我搬了百度上的定义: Simulate Anneal Arithmetic (SAA,模拟退火算法

浅谈Manacher算法与扩展KMP之间的联系

首先,在谈到Manacher算法之前,我们先来看一个小问题:给定一个字符串S,求该字符串的最长回文子串的长度.对于该问题的求解,网上解法颇多,时间复杂度也不尽相同,这里列述几种常见的解法. 解法一 通过枚举S的子串,然后判断该子串是否为回文,由于S的子串个数大约为,加上每次判断需要的时间,所以总的时间复杂度为,空间复杂度为. bool check(string &S, int left, int right) { while (left < right && S[left]

浅谈聚类算法(K-means)

聚类算法(K-means)目的是将n个对象根据它们各自属性分成k个不同的簇,使得簇内各个对象的相似度尽可能高,而各簇之间的相似度尽量小. 而如何评测相似度呢,采用的准则函数是误差平方和(因此也叫K-均值算法): 其中,E是数据集中所有对象的平方误差和,P是空间中的点,表示给定对象,mi为簇Ci的均值.其实E所代表的就是所有对象到其所在聚类中心的距离之和.对于不同的聚类,E的大小肯定是不一样的,因此,使E最小的聚类是误差平方和准则下的最优结果. 选取代表点用如下几个办法: (1)凭经验.根据问题性

浅谈KMP算法及其next[]数组

KMP算法是众多优秀的模式串匹配算法中较早诞生的一个,也是相对最为人所知的一个. 算法实现简单,运行效率高,时间复杂度为O(n+m)(n和m分别为目标串和模式串的长度),比蛮力算法的O(nm)快了许多. 理解KMP算法,关键是理解其中的精髓——next[]数组. (统一起见,下文将目标字符串记作obj,将模式字符串记作pattern,这与后面的程序代码是一致的) 我们给一个字符串S定义一个next值,记作next(S),next(S)=n表示: (1)S的前n个字符构成的前缀,和后n个字符的后缀

浅谈Tarjan算法及思想

在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量.Tarjan算法有点类似于基于后序的深度遍历搜

从数组循环左移问题中浅谈考研算法设计的规范代码

问题:设将n(n>1)个整数存放到一维数组R中.设计一个算法,将R中的序列循环左移p(0<p<n)个位置,即将R中的数据由{X0,X1,...,Xn-1}变换为{Xp,Xp+1,...,Xn-1,X0,X1,...,Xp-1}.要求:写出本题的算法描述. 分析: 本题不难,要实现R中序列循环左移p个位置,只需先将R中前p个元素逆置,再将剩下的元素逆置,最后整体逆置操作即可.本题算法描述如下: 1 #include <iostream> 2 using namespace st