求解整数规划问题的割平面法和分支定界法

宇宙微尘
2025-01-27 11:34:53
运筹优化
技术教程


整数规划


整数规划问题是优化变量必须取整数值的线性或非线性规划问题,不过,在大多数情况下,整数规划问题指的是整数线性规划问题。


其数学模型为



特别地,如果I={0,1},上述模型也被称为0-1规划问题。


相比线性规划问题,整数规划问题其实就是多了组整数约束。


鉴于两者如此紧密的关系,如下所示的线性规划问题被称为整数规划问题的松弛问题。



虽然看起来只是优化变量多了组整数条件的约束,但是在理论上,整数规划问题的求解已经不再是多项式复杂度了。


目前最常用的整数规划问题求解算法有两个:割平面法和分支定界法。 不用被名字吓到,它们的本质都只是在单纯形法之外再额外增加一些算法逻辑,从而保证可以取到整数解。 而这些算法逻辑,更像是算法框架,通过简单的实例就能描述清楚其背后的设计思想。


割平面法


本节通过求解如下的一个整数规划问题,来说明割平面法的算法原理。



首先计算其对应的松弛问题,得到最优解为



下图中,A点即为最优解。显然,该解并不满足优化变量为整数的约束。



此时,割平面法的思路是:先把A点附近的非整数区域从可行域中切掉,然后再重新计算最优解。“切”的数学描述可以表达为:给松弛问题增加一个约束。本实例中,约束的表达式为



增加约束后,可行域如下图所示,重新求解得到最优解为



该解虽然是求解松弛问题得到的最优解,但由于也满足整数条件的约束,所以也自然是原整数规划的最优解。



现在唯一的问题就只有:如何得到新增的约束表达式? 接下来详细阐述。


切割前,最优解对应的单纯形表如下所示。 单纯形表是基于单纯形法得来的,这篇文章给予了详细说明。 本文不单开章节描述单纯形表的创建和迭代过程,主要是因为在实际应用时并不需要这些。



从单纯形表的x2那一行,可知



将系数的整数部分和小数部分拆开,可得



合并整数和小数部分



等式左边第一项为整数部分,而等式右边为的[0,1]小数,所以等式左边第二项的小数部分必然大于等于右边的值,即



该式即刚刚我们要添加的约束。


当然了,从图上可以看出,横纵坐标是x1,x2,但是约束条件是关于x3,x4,所以要做可视化的话,还需要转换一下



然后代入新添加的约束,变为



这样就可以画出如上所示的图了。


至于为什么要选择x2那一行来构造新的约束,这主要是因为,有经验表明,使用小数部分最大的那一行来构造约束,收敛会更快。


分支定界法


相比割平面法,分枝定界法的思路更容易理解。


以如下的实例为例:



(1) 定义P为原整数规划问题,P0为其对应的松弛问题,最优解为



由于x0不满足整数约束,所以该解并不是P的最优解。 但是P的最优解f*肯定不会低于P0的最优解,所以f0可以作为P的下界



此外,我们很容易发现,x=(0,0)是P的一个可行解,此时f=0,P的最优解f*不会高于该值,所以P的上界是



(2) 在P0的最优解中,由于x1=5.6,引入两个互斥的约束条件:



将这两个约束分别加入P中,得到子问题P1和P2。 显然,P的最优解和P1、P2最优解的更小者相同。


求解P1对应的松弛问题,最优解为



由于x1为整数解,所以也是P1的最优解,上界fub可以修改为



由于P1已经得到整数最优解,所以P1不需要再继续被分支。


求解P2对应的松弛问题,最优解为



x2不满足整数条件,因此不是P2的最优解,但是f*不会低于f2,所以可以更新下界



(3) 在P2的最优解中,由于x2=3.75,继续引入两个互斥的约束条件



将这两个约束分别加入P2中,得到子问题P3和P4。


先求解P4对应的松弛问题,无可行解,所以可以停止分枝。


再求解P3对应的松弛问题,最优解为



x3不满足整数条件,因此不是P3的最优解,但是f*不会低于f3,所以可以继续更新下界



(4) 在P3的最优解中,由于x1=7.2,继续引入两个互斥的约束条件



将这两个约束分别加入P3中,得到子问题P5和P6。


求解P5对应的松弛问题,最优解为



由于x5为整数解,所以也是P5的最优解,上界fub可以修改为



此时,P5不需要再继续被分支。


求解P6对应的松弛问题,最优解为



x6不满足整数条件,但是f6并不小于当前上界fub,所以该分支是“枯枝”,需要剪枝。


结合P5和P6,下界可以更新为



此时,我们发现



所以该问题的最优解为



对应的目标函数值为



分支定界的全过程可以参考下图。



总的来说,割平面法和分支定界法都是先计算原问题对应的松弛问题,然后判断松弛问题的最优解是否也满足整数约束,如果满足,那么皆大欢喜;反之,割平面法会通过增加约束的方式来改进松弛问题的可行域,以期达到松弛问题最优解亦为原问题最优解的目标;而分支定界法则利用分解技术,将原问题分解为若干个子问题并分别计算,然后基于子问题的求解结果持续更新原问题的上下界,直至两者相等。


代码实现


虽然割平面法和分支定界法的步骤看起来挺多的,但好在,求解器已经帮我们做好了集成的工作,所以我们可以直接调用现成的求解器来求解所遇到的整数规划问题。


基于Python调用ortools求解整数规划问题的代码,和此前介绍的线性规划代码的唯一不同点在于:整数规划中优化变量的定义是solver.IntVar,而线性规划中的定义方式是solver.NumVar。


以下是上一节整数规划问题的求解代码。


from ortools.linear_solver import pywraplp


if __name__ == '__main__':
    # 声明ortools求解器,使用SCIP算法
    solver = pywraplp.Solver.CreateSolver('SCIP')

    # 优化变量
    x1 = solver.IntVar(0, 8, 'x1')
    x2 = solver.IntVar(0, 4., 'x2')

    # 目标函数
    solver.Minimize(-10 * x1 - 20 * x2)

    # 约束条件
    solver.Add(5 * x1 + 8 * x2 <= 60)

    # 模型求解
    status = solver.Solve()

    # 模型求解成功, 打印结果
    if status == pywraplp.Solver.OPTIMAL:
        # 变量最优解
        print('x1: {}, x2: {}'.format(x1.solution_value(), x2.solution_value()))

        # 最优目标函数值
        print('best_f =', solver.Objective().Value())

    else:
        print('not converge.')

运行代码后,可以得到最优解如下。显然,该解和上一节推演的结果是一致的。


x1: 5.0, x2: 4.0
best_f = -129.99999999999997



本文转载自微信公众号:我在开水团做运筹

1212
0
0
0
关于作者
相关文章
  • 量子计算赋能能源材料革命:从分子模拟到材料设计,开启高效研发 ...
    国际团队在《ACS Energy Letters》发表《Harnessing Quantum Computing for Energy Materials: O ...
    了解详情 
  • 量子力学百年之际的 MLIP:化学精度、效率与通用泛化的演进与展 ...
    随着量子力学在2025年迎来其百年纪念,机器学习原子间势(MLIP)已逐渐发展为分子建模领域的变革性 ...
    了解详情 
  • 具身智能再迎突破!俄罗斯团队用量子退火技术破解机器人运动控制 ...
    内容提要一项由俄罗斯多家科研机构联合完成的最新研究表明,量子退火(Quantum Annealing)技术 ...
    了解详情 
  • Transformer 的尽头是 Ising 机
    华人学者闪耀2026元旦,前有DeepSeek mHC:一次将 Transformer 残差流拉回重整化轨道的重大升级 ...
    了解详情 
  • 机器学习赋能靶向蛋白降解药物设计:PROTACs与分子胶的技术综述 ...
    靶向蛋白降解(TPD)通过利用泛素–蛋白酶体系统(UPS)实现对致病相关蛋白的催化性去除。蛋白 ...
    了解详情 
领取成功
本月5个550bit真机配额已发放给您,配额将在2个月后到期,请及时使用哦~
活动中心
联系我们
二维码
返回顶部
返回
活动中心

完成任务,轻松获取真机配额

×
每日必做
新手任务
长期任务
其他任务
快速回复 返回顶部 返回列表
玻色有奖小调研
填写问卷,将免费赠送您1个1000bit真机配额
(单选) 您是从哪个渠道得知我们的?*
您是从哪个社交媒体得知我们的?*
您是通过哪个学校的校园宣讲得知我们的呢?
取消

提交成功

真机配额已发放到您的账户,可前往【云平台】查看

量子AI开发者认证

考核目标

开发者能够成功搭建Kaiwu-PyTorch-Plugin项目基础环境,并成功运行示例代码,根据示例提示,输出指定的值并填写至相应的输入框中。

通过奖励

5个一年效期的1000量子比特真机配额

专属「量子AI开发者」社区认证标识

开发者权益

每月固定权益:5个550量子比特真机配额
前往考核

第一步

按照README提示成功安装Kaiwu-PyTorch-Plugin库环境依赖
前往GitHub

第二步

运行 community-assessment 分支下的 run_rbm.py 代码示例

第三步

理解示例代码,手动打印并填写如下数值:

正相采样的状态

负相采样的状态

正相的能量值

负相的能量值

*

提交答案

开发者权益

每月固定权益:5个550量子比特的真机配额

恭喜您完成考核

您将获得量子AI开发者认证标识及考核奖励

1000 bit*5

配额

Quantum AI Developer Certification

Assessment Objectives

Developers should successfully set up the basic environment for the Kaiwu-PyTorch-Plugin project, run the QBM-VAE sample code, and calculate the correct FID value based on the random seed value provided by the system.

Pass Rewards

10 quotas for 550-qubit real quantum machines with a one-year validity period

Exclusive "Quantum AI Developer" Community Certification Badge

Developer Benefits

Fixed Monthly Benefits: 5 quotas for 550-qubit real quantum machines
Proceed to Assessment

Step 1

Install the environment dependencies for the Kaiwu-PyTorch-Plugin library according to the README instructions
Go to GitHub

Step 2

Replace the Seed Value

Your seed value is

Step 3

Enter the FID Value You Calculated

*

Submit Answer

Developer Benefits

Fixed Monthly Benefits: 5 quotas of 550-qubit real machines

Congratulations on Completing the Assessment

You will receive the Quantum AI Developer Certification Badge and Assessment Rewards

550bit*10

Quotas