注:中文非直接翻译英文,而是理解加工后的笔记,记录英文仅为学其专业表述。
Mixed-Integer Programming
变量部分(非全部)为整数的问题,可以用混合整数规划来解决Mixed Integer Programming (MIP)。MIP也可称为混合整数线性规划问题,Mixed Integer Linear Programming (MILP)。
MIP solvers
OR-Tools 提供多种MIP求解器,默认是开源求解器 Coin-or branch and cut (CBC)。如果从源码安装,可以使用其他第三方求解器如:
- SCIP
- GLPK
- Gurobi
步骤:
- 导入求解器
- 声明求解器
- 调用求解器
eg:
- 目标: maximize(x + 10y)
- 约束:
- x + 7 y ≤ 17.5
- x ≤ 3.5
- x ≥ 0
- y ≥ 0
- x, y 都是整数
from ortools.linear_solver import pywraplp
def main():
# Create the mip solver with the CBC backend.
solver = pywraplp.Solver('simple_mip_program',
pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
infinity = solver.infinity()
# x and y are integer non-negative variables.
x = solver.IntVar(0.0, infinity, 'x')
y = solver.IntVar(0.0, infinity, 'y')
print('Number of variables =', solver.NumVariables())
# x + 7 * y <= 17.5.
solver.Add(x + 7 * y <= 17.5)
# x <= 3.5.
solver.Add(x <= 3.5)
print('Number of constraints =', solver.NumConstraints())
# Maximize x + 10 * y.
solver.Maximize(x + 10 * y)
result_status = solver.Solve()
# The problem has an optimal solution.
assert result_status == pywraplp.Solver.OPTIMAL
# The solution looks legit (when using solvers others than
# GLOP_LINEAR_PROGRAMMING, verifying the solution is highly recommended!).
assert solver.VerifySolution(1e-7, True)
print('Solution:')
print('Objective value =', solver.Objective().Value())
print('x =', x.solution_value())
print('y =', y.solution_value())
print('\nAdvanced usage:')
print('Problem solved in %f milliseconds' % solver.wall_time())
print('Problem solved in %d iterations' % solver.iterations())
print('Problem solved in %d branch-and-bound nodes' % solver.nodes())
if __name__ == '__main__':
main()
运行得
solver.NumVar
实数变量solver.IntVar
整数变量
对比线性和整数规划
猜测整数规划的解也许接近线性规划,但情况并非如此。
You might guess that the solution to the integer problem would be the integer point in the feasible region closest to the linear solution — namely, the point x = 0, y = 2. But as you will see next, this is not the case.
替换约束条件为
infinity = solver.infinity()
x = solver.NumVar(0, infinity, 'x')
y = solver.NumVar(0, infinity, 'y')
print('Number of variables =', solver.NumVariables())
CP Approach to Integer Optimization
约束优化(CP)不同于传统优化理论,它更关注约束和变量,而不是目标函数。有些问题,CP可以比MIP求解器更快地找到最优解。
对于标准整数规划问题,可行点必须满足所有约束,MIP求解速度更快。在这种情况下,可行集是凸的:对于集合中的任意两点,连接它们的线段完全位于集合中。
对于具有高度非凸可行集的问题,CP-SAT解算器通常比MIP解算器更快。当可行集由多个“或”连接的约束定义时,意味着一个点只需要满足其中一个约束即可。
eg: 转换非整数约束
为了提高计算速度,CP-SAT解算器和原始CP解算器都对整数进行运算。
To solve a problem in which some of the constraints have non-integer terms, you must first transform those constraints by multiplying them by a sufficiently large integer.
eg:
- 目标: maximize(2x + 2y + 3z)
- 约束:
\begin{align} x+\frac{7}{2}y+\frac{3}{2}z\leq25 \end{align} \begin{align} 3x - 5y + 7z \leq 45 \end{align} \begin{align} 5x + 2y - 6z \leq 37 \end{align} \begin{align} x, y, z \geq 0 \end{align} \begin{align} x, y, z integers \end{align}