用DOcplex建立线性规划模型
模型建立基本步骤
建立一个数学规划模型,需要三个步骤:
- 定义决策变量
- 生成约束条件(关于变量的关系表达式)
- 定义目标函数
定义决策变量
模型中的决策变量可以通过Model
类中的内置方法定义,定义时可以一次生成一个决策变量、决策变量列表或决策变量字典。下表列出了常用的决策变量定义方法:
Function | Creates |
---|---|
binary_var() |
单个二进制变量 |
binary_var_list() |
二进制变量列表 |
binary_var_dict() |
二进制变量字典 |
binary_var_matrix() |
二进制变量矩阵 |
integer_var() |
单个整数变量 |
integer_var_list() |
整数变量列表 |
integer_var_dict() |
整数变量字典 |
integer_var_matrix() |
整数变量矩阵 |
continuous_var() |
单个连续变量 |
continuous_var_list() |
连续变量列表 |
continuous_var_dict() |
连续变量字典 |
continuous_var_matrix() |
连续变量矩阵 |
详细函数的使用方法请参考docplex.MP参考手册。
目标函数
可以通过modle.minimize()
和model.maximize()
定义模型的目标函数,其参数为决策变量的线性表达式。譬如:
1 | model.minimize(model.total_inside_cost + mdl.total_outside_cost) |
生成约束条件
线性规划模型中的约束条件是决策变量的线性表达式。Python中的算数运算符(+,-,*,/
)和关系运算符(==,<=,>=
)可以直接使用,譬如:如果x,y,z
是决策变量,3*x + 5*y + 7*z
就是一个合法的线性表达式,3*x + 5*y + 7*z <= 1
就是一个约束条件。
更多情况下,线性规划模型中约束条件为聚合表达式,譬如\(\sum_{i \in N} x_{i} \leq
1\)。DOcplex.MP可以通过Model.sum
方法生成类似约束,model.sum(x[i] for i in N) <= 1
下表给出了常用添加约束的方法:
Function | Add |
---|---|
add_constraint(ct, ctname=None) |
添加一个线性约束 |
add_constraints(cts, names=None) |
批量添加线性约束 |
模型建立后,可以将模型输出为LP格式,以进行检验,仿真出现错误。导出为LP格式的方法为:model.export_as_lp()
。
模型求解
可以通过模型的parameters属性设置模型求解参数,譬如,设置线性整数规划的MIP
Gap可以这样操作:model.parameters.mip.tolerances.mip_gap=0.05
。设置完成后可以直接通过solve()
函数求解。
模型的求解结果以类SolveSolution形式返回,其中包含了:
- 全部模型信息,譬如求解状态、目标函数值,以及
- 每个变量的值
模型无解时,solve()
返回None
,因此可以直接基于返回结果判断求解结果。对于每个变量对象,可以通过solution[vname]
的形式获取变量的值。
下面以运输问题为例,说明用DOcplex建立线性规划模型的过程。
运输问题模型
问题描述
已知有6个供给点、8个需求点,各供给点的供给量为\(S=\{60, 55, 51, 43, 41, 52\}\),各需求点的需求量为\(D=\{35, 37, 22, 32, 41, 32, 43, 38\}\),各供给点和需求点之间的单位运输成本为 $$ \[\begin{equation} c = \left[ \begin{matrix} 6 & 2 & 6 & 7 & 4 & 2 & 9 & 5\\ 4 & 9 & 5 & 3 & 8 & 5 & 8 & 2\\ 5 & 2 & 1 & 9 & 7 & 4 & 3 & 3\\ 7 & 6 & 7 & 3 & 9 & 2 & 7 & 1\\ 2 & 3 & 9 & 5 & 7 & 2 & 6 & 5\\ 5 & 5 & 2 & 2 & 8 & 1 & 4 & 8 \end{matrix} \right] \nonumber \end{equation}\] $$
设该问题的决策变量\(x_{ij}\)表示从供给点\(i \in I\)到需求点\(j \in J\)的供给量,模型的目标函数为 \[ \begin{equation} \min \sum_{i \in I} \sum_{j \in J} C_{ij} x_{ij} \end{equation} \] 约束条件 \[ \begin{equation} \sum_{i} x_{ij} = d_{j} \qquad \forall j \in J \end{equation} \]
\[ \begin{equation} \sum_{j \in J} x_{ij} \leq s_{i} \qquad \forall i \in I \end{equation} \]
\[ \begin{equation} x_{ij} \geq 0 \qquad i \in I, j \in J \end{equation} \]
DoCplex模型
下面是上述运输问题模型在DoCplex中实现代码。
1 | # 导入模型库 |
上述代码完整版,可以在我的Github中找到,下载地址。