预处理是许多MIP求解器在正是求解前会进行的一个步骤,通过一些简单的策略来节省最终模型整体求解的规模,以提高模型的求解效率。
例如,Gurobi 求解器在求解过程之前会先对模型的约束和变量进行预处理,以下面的整数规划为例:
min ? ? 2 x ? y ? 3 x ? 5 y ≤ 0 3 x + 5 y ≤ 15 x ≥ 0 , y ≥ 0 x , y ∈ Z \begin{aligned}{} \min\quad & -2x-y \quad \\\\\ & 3x-5y \leq 0 \\\\ & 3x+5y \leq 15 \\\\ & x \geq 0,y\geq 0 \\\\ & x,y \in Z \quad \end{aligned} min???2x?y3x?5y≤03x+5y≤15x≥0,y≥0x,y∈Z?
import gurobipy as grb
# 建立框架
model = grb.Model()
# 定义整数变量
x = model.addVar(vtype=grb.GRB.INTEGER, name='x')
y = model.addVar(vtype=grb.GRB.INTEGER, name='y')
# 添加约束
model.addConstr(3 * x - 5 * y <= 0)
model.addConstr(3 * x + 5 * y <= 15)
model.addConstr(x >= 0)
model.addConstr(y >= 0)
# 定义目标函数
model.setObjective(-2 * x - y, sense=grb.GRB.MINIMIZE)
# 求解
model.optimize()
# 读取信息
print("目标函数值:", model.objVal)
for v in model.getVars():
print('参数', v.VarName, '=', v.x)
在返回的求解日志当中,可以看到 Gurobi 对模型的预求解中缩减的约束及变量,日志内容如下:
...
Presolve removed 2 rows and 0 columns
Presolve time: 0.00s
Presolved: 2 rows, 2 columns, 4 nonzeros
Variable types: 0 continuous, 2 integer (0 binary)
...
有一些预处理的简单策略,能够通过极低的计算开销,带来整体模型求解效率的提升(尽管在一些特殊情况下,这些预处理策略不一定有效),这些策略包括: