列生成算法原理及实现
列生成算法(Column Generation)是一种用于高效求解大规模线性优化问题的算法,其理论基础是由Danzig等于1960年提出。本质上而言,列生成算法是单纯形算法的一种形式。列生成算法被应用于求解以下著名的NP-hard优化问题:人员调度问题、切割问题、车辆路径问题等。
线性规划模型
单纯形法
对于标准线性规划问题而言, \[ \max z = \sum^{n}_{j=1} c_{j} x_{j} \] subject to \[ \sum^{n}_{j=1} a_{ij}x_{j} = b_{i} \qquad i=1,2, \cdots, m \]
\[ x_{j} \geq 0 \qquad j=1,2, \cdots, n \]
采用单纯形法求解过程时,变量\(x_{j}\)的检验数为 \[ \sigma_{j} = c_{j} - \sum_{i=1}^{m} c_{i} a_{ij} \] \(\sigma_{j} > 0\)表示非基变量\(x_{j}\)变为基变量会引起目标函数的增加,因此通常选 择\(\sigma_{j}\)最大的非基变量作为进基变量。对于最小化问题,\(\sigma_{j} < 0\)表示非基变量\(x_{j}\)变为基变量会引起目标函数的减小。
单纯形的矩阵表示为:
单纯形计算时,总是选取\(I\)为初始基,对应的基变量为\(X_s\)。迭代若干步后,基变量为 \(X_B\),\(X_B\)在初始单纯形表中的系数矩阵为\(B\)。将\(B\)在初始单纯形中单独列出,而 \(A\)中去掉\(B\)的若干列后剩下的列组成矩阵\(N\),这样的初始单纯形表可以列成如下形式 :
非基变量 | 基变量 | ||||
---|---|---|---|---|---|
\(C_B\) | 基 | \(b\) | \(X_{B}\) | \(X_N\) | \(X_S\) |
0 | \(X_S\) | \(b\) | \(B\) | \(N\) | \(I\) |
\(c_{j} - z_{j}\) | \(C_{B}\) | \(C_{N}\) | 0 |
迭代若干步后,基变量变为\(X_{B}\)时,该步的单纯形表中由\(X_{B}\)系数组成的矩阵为 \(I\)。此时,新的单纯形表具有如下形式:
基变量 | 非基变量 | ||||
---|---|---|---|---|---|
\(C_B\) | 基 | \(b\) | \(X_{B}\) | \(X_N\) | \(X_S\) |
\(C_B\) | \(X_s\) | \(B^{-1}b\) | \(I\) | \(B^{-1}N\) | \(B^{-1}\) |
\(c_{j} - z_{j}\) | 0 | \(C_{N}-C_{B}B^{-1}N\) | \(-C_{B}B^{-1}\) |
变量的 检验数的向量表示为 \[ \sigma_{j} = c_{j} - C_{B} B^{-1}P_{j} \] 其中,\(B\)为基变量;\(C_{B}\)为基变量在目标函数中系数组成的向量;\(P_{j}\)为系数矩阵中的第\(j\)列。
对偶问题
原问题的对偶问题为 \[ \min w = \sum_{i=1}^{m} b_{i} y_{i} \] subject to \[ \sum_{i=1}^{n} a_{ij}y_{i} \geq c_{j} \qquad j=1,2,\cdots, n \]
\[ y_{i} \geq 0 \qquad i=1,2, \cdots, m \]
根据原问题和对偶问题的关系,检验数\(\sigma_{j}\)可以写为 \[ \sigma_{j} = c_{j} - C_{B} B^{-1} P_{j} = c_{j} - \sum_{i=1}^{m} a_{ij}y_{i} \]
检验数的经济含义为reduced cost,他表示将该变量由非基变量变为基变量带来的目标函数的改进。对于最大化问题,如果所有变量的reduced cost<= 0,则表示已经无法通过换入换出基变量使目标函数变大;相反对于最小化问题,如果所有变量的reduced cost >=0,则表示已经无法通过换入换出基变量使目标函数值更小。
Cutting Stock Problem
有一堆固定长度为16m的原纸卷,顾客们分别需要25个3m长,20个6m长和18个7m长的纸卷。问怎样切割才能使得浪费最小?
分析:顾客总共需要3种类别,用\(j\)对类别进行索引。原纸卷长度16m,可以切割为5个3m 长的,也可以切割为2个6m长,甚至更多种且法方法。我们将这些不同的切割方法称为 切割方案,即一张16m的原纸卷要切割成几张3m、几张6m和几张7m的,用\(i\)对方案进行 索引。在切割方案\(i\)中类别\(j\)的数量记为\(a_{ij}\)。
定义决策变量\(x_{i}\)为采用第\(i\)种切割方案的原纸卷数,可以建立如下数学规划模型: \[ \min \sum_{i} x_{j} \] subject to \[ \sum_{i} a_{ij} x_{i} \geq d_{j} \qquad \forall j \]
\[ x_{i} \geq 0 \]
我们将此问题称为主问题(Master Problem)。 很难直接对上述模型进行求解,因为无论是目标函数还是约束条件都需要知道所有的切割 方案。按照单纯形法,在列出所有切割方案的情况下,我们才能计算每种切割方案(变量 \(x_{j}\))的reduced cost。
如果我们能够找到一个初始基,而要对这个解进行改进就是要找出一个进基变量,其 reduced cost应该是最大的。
很明显, \[ \begin{bmatrix} 5 & 0 & 0\\ 0 & 2 & 0\\ 0 & 0 & 2\\ \end{bmatrix} \] 可以是一个初始基,基于初始可行基可将模型写为: \[ \min f = x_1 + x_2 + x_3 \] subject to \[ 5 x_{1} \geq 25 \]
\[ 2 x_{2} \geq 20 \]
\[ 2 x_{3} \geq 18 \]
将基于初始可行基构建的模型称为RMP模型(Restricted Master Problem) 该模型的对偶问题为: \[ \max w = 25 y_1 + 20 y_2 + 18 y3 \] subject to \[ 5 y_1 \leq 1 \]
\[ 2 y_2 \leq 1 \]
\[ 2 y_3 \leq 1 \]
将该模型称为DMP(Dural Master Problem)。 求解此对偶问题,可以得到\(y^{*}\),此时寻找检验数最小的换入变量可以通过求解规划 问题: \[ \min c_{j} - \sum_{i} a_{ij}y_{i} = 1 - \sum_{i} a_{ij} y^{*}_{i} \] subject to \[ 3 a_{1j} + 6 a_{2j} + 7 a_{3j} \leq 16 \]
此模型称为Pricing Prolbem,求解此模型可以得到一种新的切割模式(\(a_{ij}\)),因此增加新的决策变量\(x_{j}\),这也是列生成算法名称的由来。将新生成的变量加入到RMP中,并不断循环直至无法得到新的变量,即求解的最优解。
列生成算法的主要框架如下:
CPLEX实现
借助于CPLEX的docplex可以快速实现列生成算法求解切割问题,代码如下:
1 | #! /usr/bin/env python |