在MATLAB基于问题的优化中使用Gurobi#

从R2017b版本开始,MATLAB优化工具箱提供了一种新的方式来表述优化问题,称为“基于问题的优化”。在本节中,我们将解释如何将这种建模技术与Gurobi求解器结合使用。

基于问题的建模方法使用面向对象的范式来表示优化问题的组成部分;优化问题本身、决策变量和线性约束都由对象表示。它们的创建和修改通过方法实现。基于问题的优化的完整文档是优化工具箱的一部分;我们只会通过一个简单的示例进行讲解。为此,重要的是您的MATLAB路径包含Gurobi的示例目录,可以按如下方式设置:

addpath(fullfile(<path_to_Gurobi>, <architecture>, 'examples', 'matlab'));

第一步是创建一个优化问题:

prob = optimproblem('ObjectiveSense','maximize');

变量 prob 现在引用了一个优化问题对象,我们已将其指定为最大化问题。接下来我们创建三个非负优化变量:xyz

x = optimvar('x', 'LowerBound', 0);
y = optimvar('y', 'LowerBound', 0);
z = optimvar('z', 'LowerBound', 0);

有了这些变量,我们现在构建线性表达式,以便设置目标函数,并向prob添加两个线性约束:

prob.Objective = x + 2 * y + 3 * z;
prob.Constraints.cons1 = x + y <= 1;
prob.Constraints.cons2 = y + z <= 1;

最后,我们创建一个选项对象,该对象将prob的求解方法引导到线性规划求解函数linprog,并调用solve方法。

options = optimoptions('linprog');
sol = solve(prob, options);

由于Gurobi安装的examples目录已在上述第一步添加到路径中,此时会发生一些神奇的事情:该目录包含一个文件linprog.m,因此调用solve方法最终会调用此函数,而不是MATLAB优化工具箱中的内置函数linprog。Gurobi的以下输出将显示在控制台上:

Gurobi Optimizer version 11.0.1 build v11.0.1rc0 ()

Optimize a model with 2 rows, 3 columns and 4 nonzeros
Model fingerprint: 0x3a4c68c2
Coefficient statistics:
  Matrix range     [1e+00, 1e+00]
  Objective range  [1e+00, 3e+00]
  Bounds range     [0e+00, 0e+00]
  RHS range        [1e+00, 1e+00]
Presolve removed 2 rows and 3 columns
Presolve time: 0.03s
Presolve: All rows and columns removed
Iteration    Objective       Primal Inf.    Dual Inf.      Time
       0   -4.0000000e+00   0.000000e+00   0.000000e+00      0s

Solved in 0 iterations and 0.05 seconds
Optimal objective -4.000000000e+00

我们刚刚讨论的示例可以在examples目录中的文件opttoolbox_lp.m中找到。示例opttoolbox_mip1.m展示了一个使用整数变量的类似问题公式,它使用了函数intlinprog.m,该函数也可以在Gurobi示例目录中找到,作为MATLAB内置函数的替代。

优化工具箱提供的建模结构并未涵盖Gurobi的所有功能,例如SOS、半连续变量和一般约束等。此外,并非所有Gurobi参数在linprogintlinprog的选项对象中都有等效的对应项。为了使用这些功能,应使用Gurobi自己的Matlab API。