运筹规划(七)-求解器

这篇文章主要介绍当我们面对一个运筹问题的时候,如何求解一个问题。先来介绍一个基于python的集成框架pyomo,通过pyomo下面可以调用一系列的求解器,最终实现求解的过程。

先给一个demo

from pyomo.environ import *
# 创建一个模型
model = ConcreteModel()
# 定义变量
model.x = Var(within=Reals)
model.y = Var(within=Reals)
# 定义目标函数
model.obj = Objective(expr=(model.x-10)**2 + (model.y-20)**2,sense=maximize)
# 定义约束
model.con1 = Constraint(expr=model.x**2 + model.y**2 <= 224)
model.con2 = Constraint(expr=model.x - 2*model.y >= 0)
# 求解器设置
solver = SolverFactory('scip',executable='path/bin/scip')
# solver = SolverFactory('gurobi')
solver.options['tol'] = 1e-10
solver.options['max_iter'] = 1000
# solver.options['linear_solver']='MA86'
# solver.options['penalty_method']='exact'
solver.options['print_level'] = 5
# solver.options['NonConvex'] = 2
# 求解问题
results = solver.solve(model, tee=True)
# 打印结果
print(f"Objective value: {model.obj():.2f}")
print(f"x = {int(model.x())}")
print(f"y = {int(model.y())}")

我们发现求解这个运筹方程十分简单,只需要填写好自己的目标和约束就能完成一个运筹模型的求解。

环境搭建

我其实想和大家说的是这一套环境的搭建往往是最耗时的。我们一般使用conda来管理这些软件是比较方便的。先在centos上安装conda

sudo yum install conda
conda config --add channels conda-forge # 添加软件源
conda install -c conda-forge ipopt
conda install -c conda-forge coincbc
conda install -c conda-forge coinbonmin
conda install -c conda-forge scip

通过上面的安装基本上就能保证你的环境具备一些求解器的能力,当然你可以选择开源代码的安装,哎,我是没有成功,忒复杂啦。

冲冲场面

线性求解器

接下来咱们一起看看这运筹求解器到底有个啥特点,分别适合什么场景的建模。

OR-Tools

OR-Tools是Google开发的求解器,主要应用于离散优化问题,例如车辆路径规划、工厂排程等。它支持多种算法和模型类型,包括整数规划、约束编程和约束满足问题等。
它的优点是速度快、易于安装和使用。
缺点是不支持非线性优化和全局优化。

CBC

CBC是一个用于解决线性规划、整数规划和混合整数规划问题的求解器,它的优点是速度较快、易于安装和使用,缺点是可扩展性较弱、不支持非线性规划问题。

GLPK

GLPK是一个用于解决线性规划和整数规划问题的求解器,它的优点是开源、易于使用、支持多种输入格式、可用于商业和非商业用途。缺点是速度较慢、不支持非线性规划问题、可扩展性较弱。

我们发现上面介绍这集中求解器都是针对线性规划问题的求解,那么他们这些求解器的区别又是什么呢?

CBC(Coin-or branch and cut)是一种混合整数规划(MIP)求解器,使用分支定界算法和割平面算法求解MIP问题。它对线性规划、整数规划和混合整数规划都有很好的支持,特别是在处理大规模混合整数规划问题时表现突出。

混合整数规划:混合整数规划指部分决策变量限制为整数的整数规划问题。

GLPK(GNU Linear Programming Kit)是一个线性规划求解器,使用单纯形法、内点法等算法求解线性规划问题。它支持整数规划和混合整数规划,但在处理大规模混合整数规划问题时效率可能不如CBC。
OR-Tools优势在于支持多种编程语言和平台,并提供了丰富的算法和模型库,方便用户使用和扩展。

非线性求解器

这里有个小tips,上面一顿装X又是非线性呀又是全局解, 那到底非线性长啥样呀,为啥会有些方法求的不是全局优化呢?

全局优化

所谓的全局优化就是整个求解空间内最优的那个解,咱们知道如果解是整数类型,那么求解空间还是可以枚举的,但是一但说是连续类型,那么理论上是有无限的求解方案和空间的。所以例如 OR-Tools这种离散最优化的工具能做全局搜索最优解的,好吧,你说的都对。

非线性规划

非线性规划(Nonlinear Programming,NLP)是指在约束条件下优化非线性目标函数的数学优化问题。

以下是一个简单的非线性规划问题的例子:

min f(x,y)=(x2)2+(y1)2s.t.g(x,y)=x2y0h(x,y)=y34x10min\ f(x,y) = (x-2)^2 + (y-1)^2 \\ s.t. g(x,y) = x^2 - y \geq 0 \\ h(x,y) = y - \frac{3}{4}x - 1 \geq 0

其中,x,yx,y是决策变量。
上面的例子就是一个简单的非线性优化问题。 不仅目标,就连约束也是有非线性部分的。那么对于这么难的问题有哪些开源(穷)的求解器可以使用呢?

IPOPT

IPOPT是一个非线性优化求解器,它可以求解包括凸和非凸问题在内的各种非线性问题。它的优点是求解速度快、可扩展性强、支持约束条件和灵活的算法选择等。
缺点是对初始值敏感、可能出现数值稳定性问题。

IPOPT求解速度快

  • IPOPT 采用的是内点法(interior-point method),这种方法在求解大规模非线性规划问题时速度较快,尤其是对于凸优化问题。
  • IPOPT 还采用了多种优化技巧,如启发式初始化、二次模型预测、线性化等,这些技巧可以帮助加速求解过程。
  • IPOPT 采用了自适应步长策略,这种策略可以自动调整求解的步长,从而提高求解的速度。

IPOPT对初始值敏感

解释一下对于非凸的问题,是有可能存在若干个极小值点的。在这种情况下,初始值对于求解结果的影响非常重要,因为初始值不同可能会导致算法最终收敛到不同的局部极小值点。是不是很熟悉的话术,其实深度学习优化非凸目标函数的时候也会面对这个问题。
所以,IPOPT 的初始值设定不合适可能会导致算法收敛困难、迭代次数增加等问题,因此初始值的设定需要慎重考虑。

IPOPT使用的条件

IPOPT通常在非线性约束较少,特别是在存在二次约束的情况下表现良好,但在存在非凸性质的问题中表现可能较差。其对非凸的问题性能较差的原因是IPOPT基于一阶优化方法,而一阶优化方法通常只能保证找到局部最优解。对于非凸性质的问题,可能存在多个局部最优解和一个全局最优解。在这种情况下,IPOPT可能会陷入一个局部最优解,而无法找到全局最优解。

SCIP

SCIP是一款用于解决混合整数线性和非线性规划问题的求解器,它的优点是速度快、可扩展性强、支持并行计算和分布式计算等。相比其他求解器,它的缺点是使用难度较大,需要一定的数学建模和编程知识。

与 IPOPT不同的是,SCIP解决具有非凸二次约束和/或大量离散变量的优化问题,对于这类问题具有很好的表现。

那么SCIP为啥能解决非凸的优化问题呢?
主要原因是SCIP支持 McCormick relaxation 和 convex envelope relaxation 这两种非凸问题处理方法。

McCormick relaxation 通过替换非凸项为其凸包的上界和下界之间的线性插值,将问题转化为一个凸优化问题。

我们提到了两种解决非凸问题的方法,这里就来详细McCormick Relaxation。

McCormick relaxation

McCormick Relaxation 是一种数学优化技术,用于处理非凸问题的松弛和近似。它将一个非凸问题松弛为一个可以更容易求解的凸问题。以下是一个简单的例子来说明 McCormick Relaxation 的应用。接下来就看看McCormick relaxation是如何解决非凸问题的。

demo

看下面这个非凸优化问题。

min f(x,y)=x2+y2s.t.g(x,y)=xy10min\ f(x, y) = x^2 + y^2 \\ s.t. \\ g(x, y) = x \cdot y - 1 \geq 0

这是一个非凸问题,因为目标函数 f(x,y)f(x, y) 是二次的,而约束 g(x,y)g(x, y) 是二次项的乘积,导致整个问题非凸。
McCormick Relaxation 的思想是将乘积 xyx \cdot y 松弛为一个凸包围。这可以通过引入新的变量 z1z_1z2z_2 来实现,使得:

z1=xyz2=xyz_1 = x \cdot y \\ z_2 = -x \cdot y

这两个变量引入了两个额外的约束,即:

z1z2=xy(xy)=2xy0z_1 - z_2 = x \cdot y - (-x \cdot y) = 2x \cdot y \geq 0

现在,原始问题可以被松弛为一个包含这两个额外变量 z1z_1z2z_2 的凸优化问题,那么原问题表示如下:

f(x,y)=x2+y2s.t.z1z20f(x, y) = x^2 + y^2 \\ s.t. \\ z_1 - z_2 \geq 0

这个问题就变成了一个二次凸优化问题,可以使用标准的凸优化方法来求解。在实际应用中,McCormick Relaxation 可以用于处理非凸约束,例如在混合整数规划(MIP)中,它可以用于将非凸约束松弛为线性或凸约束,从而更容易求解整个问题。

总而言之

其实咱们已经把乞丐版的方案调研了个差不多了,下面就是根据实际问题赶紧模型选型起来呀。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×