MIP精确算法的关键——确定界 篇一

2023-10-03 15:18
文章标签 算法 精确 mip 关键 确定

本文主要是介绍MIP精确算法的关键——确定界 篇一,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1.界是什么?

2. 如何更新上下界

2.1 以分支定界为框架的一系列算法

 2.2 benders分解


MIP精确算法包含,分支定界、分支切割、分支定价还有benders分解等等。前者是以分支定界为框架的一类算法;后者是以分解为框架的一类算法。甚至还包括拉格朗日松弛等等,我觉得除了算法细则需要搞清楚外,更关键的是弄懂界。

因为拉格朗日算法目前不熟,所以下面我具体总结分支定界的一类算法和benders分解算法界的确定原则。

本篇以min问题为例。

1.界是什么?

界包含上界UB,和下界LB。

我们做启发式算法的时候,有时候会被审稿专家提一个问题,就是你这个算法质量没有保证,所以一般我们会提供一个下界作为参考。比如:调度问题中,不相关并行机问题,我们松弛为相同的机器,以工件j在所有机器的最小加工时间min_{i\in I}\left \{ p_{ij} \right \}为工件的加工时间\bar{p},然后叠加就可以得到一个总完工时间,这个就可以作为原问题的下界。

在精确算法中,我们会得到一个UB,和一个LB,不断提升LB,降低UB。当UB=LB的时候,我们就得到了最优解。

(1)UB是整数可行解,但我们降低UB的时候,就是找到更好可行解更新。

(2)LB是松弛解,像以分支定界为框架的一系列算法中,主要采用的是线性松弛解,因为约束减少,因此解的质量至少不差于(好于)原问题的解,原问题是min,不差于(好于)就是更小,即LB。

而拉格朗日松弛,采用的是不同于线性松弛的松弛方法,得到的LB更好,通常拉格朗日松弛的解≥线性松弛的解。

2. 如何更新上下界

当我们了解UB和LB了之后,下一个问题是:

(1)用什么来更新?以及

(2)更新的过程怎么保证不丢失信息,确保更新UB和LB之后得到的是精确最优解呢?

2.1 以分支定界为框架的一系列算法

先来说以分支定界为框架的一系列算法:

它的本质是隐枚举,通过剪支的操作来避免全枚举。剪支分为:不可行剪支(线性松弛后可行域变大了还不可行,那可行域是子集的原问题必定也不可行)、最优性剪支(已经是整数解了,没必要分支了)、和定界剪支(因为线性松弛后解更小,当线性松弛后解超过了UB,那肯定不松弛解更超过UB,也就是不会产生更好的解了)。

可以看到定界剪支与界(准确的说是LB)相关,以及我们在求解过程中需要不断更新,和比较UB和LB,因此界很重要。

编程的时候怎么实现呢?

我们需要定义一系列的界,包含全局UB&LB(上面说的都是这个);以及当前节点的UB&LB(为了比较和替换,也是为了更清晰的展示每个点的上下界信息);以及储存在每次迭代过程中UB&LB(比如我们想查看上下界怎么变化,就需要用到它,智能算法中显示全局解随迭代次数变化的迭代曲线一样的意思)。

总结一下,需要用到global_UB,global_LB;node.local_LB,node.local_UB,以及Global_UB_change,Global_LB_change。

后续我们需要对以上变量进行更新,具体的做法是:

(1)首先肯定是要预定义:

global_UB=正无穷,global_LB=原问题线性松弛的解;

node.local_LB=global_LB,node.local_UB=正无穷;

Global_UB_change=[],Global_LB_change = [].

(2)求解每一个叶子节点current_node,会得到它的解current_node.model.ObjVal。

(3)假如是整数解,且该解比之前可行解都好,即current_node.model.ObjVal<global_UB,那么用current_node.model.ObjVal替换global_UB;

假如不是整数解,即小数解,不需要进行任何操作。

# update the LB and UB
if (is_integer == True):feasible_sol_cnt += 1  # 整数可行解的计数# For integer solution node, update the LB and UBcurrent_node.is_integer = Truecurrent_node.local_LB = current_node.model.ObjValcurrent_node.local_UB = current_node.model.ObjVal# if the solution is integer, update the UB of global and update the incumbentif (current_node.local_UB < global_UB):  # 整数可行解更优,更min,则更新上界,同时更新当前最好的整数可行解incumbent_nodeglobal_UB = current_node.local_UBincumbent_node = Node.deepcopy_node(current_node)if (is_integer == False):# For integer solution node, update the LB and UB alsocurrent_node.is_integer = Falsecurrent_node.local_UB = global_UBcurrent_node.local_LB = current_node.model.ObjVal

(可以看到每个点current_node的下上界信息也进行了更新,是为了展示各个节点的上下界情况。整数节点,上下界相等,都为current_node.model.ObjVal;非整数节点,上界为global_UB,下界为本身(因为是松弛解))。

(4)因为我们在分支的时候,把所有的子节点(一系列模型)放在队列Queue中 ,因此我们探测这些叶子节点的信息,来更新全局下界(是所有叶子节点解的最小值)>>>>(是保证不缺失信息的关键)。

注意:上界UB可以用更好的可行解信息来代替,但是下界LB不能,下界LB要全部探测所有节点方可确定。

# update the global LB, explore all the leaf nodes
temp_global_LB = np.inf
for node in Queue:node.model.optimize()if (node.model.status == 2):if (node.model.ObjVal <= temp_global_LB and node.model.ObjVal <= global_UB):temp_global_LB = node.model.ObjVal  # 下界是剩余节点集合Q中节点对应的LP中obj的最小值

(5)更新全局LB和UB,更新界的迭代信息列表Global_UB_change,Global_LB_change

global_LB = temp_global_LB
Global_UB_change.append(global_UB)
Global_LB_change.append(global_LB)

可以看到,全局UB直接更新(出现好的就更新,类似于我们说的贪婪更新),而下界LB是探测所有。 然后把每次迭代过程中的全局UB和LB放在界的迭代列表Global_UB_change,Global_LB_change中,因为我们在先前已经比较过了,因此LB一定是增大(因为我们不断添加界,相当于可行域变小,所以即使探测所有节点,解一定是变大的,不会出现更小的情况),UB一定是减小的。

(6)当所有节点都探测完毕,别忘了再更新下全局上下界和界的迭代信息列表。

# all the nodes are explored, update the LB and UB
incumbent_node.model.optimize()
global_UB = incumbent_node.model.ObjVal
global_LB = global_UB
Gap = round(100 * (global_UB - global_LB) / global_LB, 2)
Global_UB_change.append(global_UB)
Global_LB_change.append(global_LB)

我们知道分支切割,和分支定价是在分支定界的基础上进行的,界的更新过程差不多。区别是分支数的样子。

 2.2 benders分解

这篇关于MIP精确算法的关键——确定界 篇一的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/499

相关文章

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时

如何通过Golang的container/list实现LRU缓存算法

《如何通过Golang的container/list实现LRU缓存算法》文章介绍了Go语言中container/list包实现的双向链表,并探讨了如何使用链表实现LRU缓存,LRU缓存通过维护一个双向... 目录力扣:146. LRU 缓存主要结构 List 和 Element常用方法1. 初始化链表2.

golang字符串匹配算法解读

《golang字符串匹配算法解读》文章介绍了字符串匹配算法的原理,特别是Knuth-Morris-Pratt(KMP)算法,该算法通过构建模式串的前缀表来减少匹配时的不必要的字符比较,从而提高效率,在... 目录简介KMP实现代码总结简介字符串匹配算法主要用于在一个较长的文本串中查找一个较短的字符串(称为

通俗易懂的Java常见限流算法具体实现

《通俗易懂的Java常见限流算法具体实现》:本文主要介绍Java常见限流算法具体实现的相关资料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的实现原理和具体步骤,并比较了它们的... 目录一、漏桶算法1.漏桶算法的思想和原理2.具体实现二、令牌桶算法1.令牌桶算法流程:2.具体实现2.1

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖