- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第6章 分支限界法 6.1 分支限界法的基本思想 分支限界法与回溯法 (1)求解目标:回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。 (2)搜索方式的不同:回溯法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间树。 分支限界法的搜索策略 在扩展结点处,先生成其所有的儿子结点(分支),然后再从当前的活结点表中选择下一个扩展结点。 为了有效的选择下一扩展结点,以加速搜索的进程,在每一活结点处,计算一个函数值,并根据这些已计算出的函数值,从当前活结点表中选择一个最有利的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解 6.1 分支限界法的基本思想 分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。 常见的两种分支限界法 队列式(FIFO)分支限界法 按照队列先进先出(FIFO)原则选取下一个节点为扩展节点。 优先队列式分支限界法 按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。 例:考虑n =3 时0-1背包问题的一个实例如下:w =[16,15,15], p= [45, 25,25],c = 30。其子集树 用队列式分支限界法解此问题 队列式分支限界法搜索解空间树的方式与解空间树的广度优先遍历算法极为相似,唯一的不同之处是队列式分支限界法不搜索以不可行结点为根的子树。 队列式 用优先队列式分支限界法解此问题 也是从根结点A开始搜索解空间树,用一个极大堆来表示活结点表的优先队列,该优先队列的优先级定义为活结点所获得的价值。初始时堆为空 优先队列中规定的结点优先级常用一个与该结点相关的数值p来表示,结点优先级的高低与p值的大小相关,最大优先队列规定p值较大的结点优先级较高,用大堆来实现。 小优先队列规定p值较小的结点优先级较高,用小堆来实现。 当寻求问题的一个最优解时,可以用剪枝函数来加速搜索,该函数给出每一个可行结点相应的子树可能获得的最大价值的上界。如果这个上界不会比当前最优值更大,则说明相应的子树中不含问题的最优解,因而可以剪去, 另一方面,我们也可以将上界函数确定的每个结点的上界值作为优先级,以该优先级的非增序抽取当前扩展结点,这种策略有时可以更迅速地找到最优解。 6.2装载问题 2. 队列式分支限界法 该算法包含两个函数 MaxLoading函数具体实施对解空间的分支限界搜索。 EnQueue用于将活结点加入到活结点队列中,该函数首先检查i是否等于n,如果i=n,则表示当前活结点为一个叶结点,由于叶结点不会被进一步扩展,因此不必加入到活结点,如果该叶结点表示的可行解优于当前最优解,更新最优解。当in时,当前活结点是一个内部结点,加入到活结点队列中。 templateclass T T MaxLoading(T w[], T c, int n) { // 返回最优装载值 // 为层次1 初始化 QueueT Q; // 活结点队列 Q.Add(-1); //标记本层的尾部 int i = 1; // 当前扩展结点的层 T Ew = 0, // 当前扩展结点的权值 bestw = 0; // 目前的最优值 templateclass T void EnQueue( QueueT Q, T wt, T bestw, int i, int n) //该函数负责加入活结点 { // 如果不是叶结点,则将结点权值w t加入队列Q if (i == n) { // 叶子 if (wt bestw) bestw = wt;} else Q.Add(wt); // 不是叶子 } 使用定界函数进行改进 T MaxLoading( T w[ ], T c, int n ) { QueueT Q; // 活节点队列 Q.Add (-1) ; //标记本层的尾部 int i = 1; // 当前扩展节点的层 T Ew = 0, //当前扩展节点的重量 bestw = 0; // 目前的最优值 r = 0; // 当前扩展节点中余下的重量 for (int j = 2; j = n; j++) r + = w[i]; while (true) { // 检查扩展结点的左孩子 T wt = Ew + w[i];
文档评论(0)