Column generation

1 起源

列生成广泛应用于大规模整数规划问题的求解中,尤其在装箱和切割问题、并行机调度问题、车辆路线问题的相关研究中。另外列生成算法也被用于乘务员调度、通信网络中的信道分配、多商品流等问题的研究中。(Gilmore and Gomory,1961年)首次将列生成技术用于求解一维切割问题(Cutting Stock Problem);(Desrosiers et al,1984)将列生成与分支定界结合以求解带时间窗的车辆路径问题;事实上,列生成得以广泛应用在于其求解(混合)整数规划问题所表现的卓越性能。

2 列生成算法基本思路

考虑下面的线性规划问题,称为主问题(Master problem,MP):

MP中有|J|=n个变量和m个约束条件,若n>>m,则想要直接求解是不可能的。相反的,考虑一个限制主问题(Restricted master problem,RMP),其变量为子集 J ′ J' J′ ⊆ \subseteq ⊆ J J J,令为 λ ∗ λ^{*} λ∗是RMP问题的一个最优解(并不一定是MP问题的最优解)。在单纯形法的每一次迭代中,需要找一个检验数为负的非基变量入基,在列生成算法中则是通过一个定价子问题(Pricing problem,PP)实现的。
P P : m i n { c j − π ∗ a j ∣ j ∈ J } PP: min \{c_j-\pi^*a_j|j∈J \} PP:min{cj​−π∗aj​∣j∈J}
若 P P < 0 PP<0 PP<0,则将对应的变量 λ i \lambda_i λi​和其系数列 ( c j , a j ) (c_j,a_j) (cj​,aj​)加入到RMP中,然后求解新的RMP得到新的最优对偶变量值,重复这个过程直至找不到新的入基变量。此时, λ ∗ \lambda^* λ∗也是主问题MP的最优解了。列生成的优势在于无需考虑所有候选变量的迭代,而是通过其他的隐式搜索(implicit search)来寻找负消减成本(negative reduced cost,对应于单纯形法迭代中的额检验数)的列作为候选的入基变量。

Cutting Stock Problem

数学模型

列生成算法的一个经典例子是一维切割问题:给定宽度为 W W W的原料,需要切割 d i d_i di​个宽度为 w i w_i wi​的坯料,如何切割才能使用料最省?
MP:

RMP:

PP:

Java代码

分为3个类:Data类存放已知数据;CuttingStockProblem 算法类;Test程序运行。

package colgen_csp;//class Data {//    static double _rollWidth = 17;// 木材长度
//    static double[] _size = new double[] { 3, 5, 9 };;// 木材需求尺寸
//    static double[] _amount = new double[] { 25, 20, 15 };;// 需求量
//}
class Data {// 木材长度static double _rollWidth = 5600;// 木材需求尺寸static double[] _size = new double[]{1380, 1520, 1560, 1710, 1820, 1880, 1930, 2000, 2050, 2100, 2140, 2150, 2200};// 需求量static double[] _amount = new double[]{22, 25, 12, 14, 18, 18, 20, 10, 12, 14, 16, 18, 20};
}
package colgen_csp;import ilog.concert.*;
import ilog.cplex.*;import static net.mindview.util.Print.*;public class CuttingStockProblem {static double _width;static double[] _size;static double[] _amount;static void init() {_width = Data._rollWidth;_size = Data._size;_amount = Data._amount;print("width of the roll: " + _width);print("demand width:");for (double size : _size)printnb(size + " ");print();print("demand amount:");for (double amount : _amount)printnb(amount + " ");}static class IloNumVarArray {int _num = 0;IloNumVar[] _array = new IloNumVar[32];void add(IloNumVar ivar) {if (_num >= _array.length) {IloNumVar[] array = new IloNumVar[_array.length * 2];System.arraycopy(_array, 0, array, 0, _num);_array = array;}_array[_num++] = ivar;}IloNumVar getElement(int index) {return _array[index];}int getSize() {return _num;}}static void writeAnsRMP(IloCplex RMP, IloNumVarArray vars, IloRange[] Fill) throws IloException {print();print("using" + RMP.getObjValue() + " rolls");print();for (int i = 0; i < vars.getSize(); i++) {System.out.format("using pattern" + i + "=" + RMP.getValue(vars.getElement(i)) + "times");}print();for (int i = 0; i < Fill.length; i++) {print("Duals" + i + "=" + RMP.getDual(Fill[i]));}print();}static void writeAnsPP(IloCplex PP, IloNumVar[] Use) throws IloException {print();print("reduced cost = " + PP.getObjValue());print();/*PP.getObjValue() <= -RC_EPS*/if (PP.getObjValue() < 0) {for (int i = 0; i < Use.length; i++)System.out.println("  Use" + i + " = " + PP.getValue(Use[i]));// 输出新的切法System.out.println();}}static void writeAns(IloCplex RMP, IloNumVarArray vars) throws IloException {print();print("Best solution uses " + RMP.getObjValue() + "rolls");for (int i = 0; i < vars.getSize(); i++) {print(RMP.getValue(vars.getElement(i)));}}public static void solution() {init();try { 限制主问题 //// 建立Cplex参数IloCplex RMP = new IloCplex();RMP.setOut(null);// 最小值问题IloObjective RMP_Obj = RMP.addMinimize();// 建立cplex需求量约束数组,添加约束IloRange[] Fill = new IloRange[_amount.length];for (int i = 0; i < _amount.length; i++) {Fill[i] = RMP.addRange(_amount[i], Double.MAX_VALUE);}IloNumVarArray vars = new IloNumVarArray();int len = _size.length;for (int j = 0; j < len; j++) {IloColumn col = RMP.column(RMP_Obj, 1.0).and(RMP.column(Fill[j], (int) (_width / _size[j])));vars.add(RMP.numVar(col, 0.0, Double.MAX_VALUE));}//选择控制器RMP.setParam(IloCplex.Param.RootAlgorithm, IloCplex.Algorithm.Primal); 定价子问题 //IloCplex PP = new IloCplex();PP.setOut(null);IloObjective ReducedCost = PP.addMinimize();//定义决策变量取值范围IloNumVar[] Use = PP.numVarArray(len, 0, Double.MAX_VALUE, IloNumVarType.Int);PP.addRange(-Double.MAX_VALUE, PP.scalProd(_size, Use), _width); 列生成 //double[] newPatt;for (; ; ) { 限制主问题 //RMP.solve();writeAnsRMP(RMP, vars, Fill);double[] price = RMP.getDuals(Fill); 定价子问题 //ReducedCost.setExpr(PP.diff(1., PP.scalProd(Use, price)));PP.solve();writeAnsPP(PP, Use);if (PP.getObjValue() >= 0)// PP.getObjValue() > -RC_EPSbreak;newPatt = PP.getValues(Use);IloColumn column = RMP.column(RMP_Obj, 1.);for (int i = 0; i < newPatt.length; i++) {column = column.and(RMP.column(Fill[i], newPatt[i]));}vars.add(RMP.numVar(column, 0., Double.MAX_VALUE));}for (int i = 0; i < vars.getSize(); i++) {RMP.add(RMP.conversion(vars.getElement(i), IloNumVarType.Int));}RMP.solve();// 输出最优切法所需木材数以及每种切法所需木材数writeAns(RMP, vars);System.out.println("Solution status: " + RMP.getStatus());RMP.end();PP.end();} catch (IloException e) {e.printStackTrace();}}
}
package colgen_csp;public class Test {public static void main(String[] args) {CuttingStockProblem csp = new CuttingStockProblem();csp.solution();}
}

Reference

  • Carvalho, J.M.V., 1998. Exact Solution of Cutting Stock Problems Using Column Generation and Branch-and-Bound. Int Trans Operational Res 5, 35–44.
  • https://blog.csdn.net/u014090505/article/details/89019327

Column generation相关推荐

  1. 【Column Generation思考-02】|从对偶的角度理解Cutting Stock Problem【更新版本】

    [Column Generation思考-01]|从对偶的角度理解 Cutting Stock Problem简介 Cutting Stock Problem的Column generation re ...

  2. 列生成算法column generation求解思路总结篇2——CW分解

    目录 1.CW的思路 2.CW重写模型 3.DW分解算法步骤 列生成是通过重写模型为P2,然后松弛主问题(只考虑m个变量),再通过对偶理论的思路构造子问题,即寻找最大改进主问题的非基变量进入松弛主问题 ...

  3. 4列的计算机代码,干货 | 10分钟带你彻底了解column generation(列生成)算法的原理附java代码...

    OUTLINE 前言 预备知识预警 什么是column generation 相关概念科普 Cutting Stock Problem CG求解Cutting Stock Problem 列生成代码 ...

  4. 运筹系列79:使用Julia进行column generation求解

    1. 案例建模 我们对cutting stock问题进行建模.rolls的尺寸为W,每个型号的需求量和尺寸分别为d和w,如下: struct Piecew::Float64d::Int endstru ...

  5. A column generation-based heuristic for aircraft recovery problem with airport capacity constraints

    A column generation-based heuristic for aircraft recovery problem with airport capacity constraints ...

  6. 大数据哈希学习: 现状与趋势

    大数据哈希学习: 现状与趋势 李武军①②*, 周志华①②* ① 南京大学计算机软件新技术国家重点实验室, 南京210023; ② 软件新技术与产业化协同创新中心, 南京210023 * 联系人, E- ...

  7. 割平面法只能求解纯整数规划吗_离散规划 解法

    有限离散规划 可列离散规划 枚举法 Hahaha 图搜索枚举 2color 树搜索枚举 深度优先 广度优先 最大最小 蒙特卡洛 分支定界 剪枝 (混合)整数线性规划 MILP 三维整数规划 MILP ...

  8. 【NIPS2018】Spotlight及Oral论文汇总

    nips2018 spotlight (168篇)和Oral(30篇)是会议中较为出色的论文,(点击论文可以查看对应摘要和链接) 1.Oral [神经元容量]On Neuronal Capacity ...

  9. [索引]引用Balancing bike sharing systems with constraint programming的文章

    文章目录 1. Dynamic container drayage with uncertain request arrival times and service time windows 2. P ...

最新文章

  1. 你见过最狠的SCI评论是什么?
  2. 实战NFS服务搭建与配置
  3. mysql min怎么用_MySQL中MIN()函数的使用教程
  4. resharper license server
  5. easyui-tabs
  6. 带你自学Python系列(十七):Python中类的用法(三)
  7. gdb+zbacktrace找到cpu过高php代码
  8. 删除一行下方单元格上移_Excel小技巧——局部单元格的添加与删除
  9. linux高级的脚本,【2018.07.23学习笔记】【linux高级知识 Shell脚本编程练习】
  10. 让0基础纯小白也能上手写Python,干货分享(二)
  11. linux shell locate,shell学习之locate和find命令
  12. Linux中如何恢复rm命令误删除的文件之extundelete编译安装及使用
  13. ICLR 2022 论文列表公布,接收率高达 32%
  14. Linux_无法运行可执行文件
  15. SqList *L 和 SqList * L的区别
  16. 节奏大师小游戏制作流程
  17. Hark的数据结构与算法练习之归并排序
  18. discuz X程序目录和文件列表 详细中文说明
  19. [渝粤教育] 广东-国家-开放大学 21秋期末考试马克思主义基本原理概论(A)10882k1
  20. CSS 3之文字样式

热门文章

  1. 新一配:区块链的应用【转载】
  2. 中国的博客论坛都有那些
  3. ShellCode_Loader - MsfCobaltStrike免杀ShellCode加载器加密工具
  4. 我的第一个C++课程设计--通讯录
  5. delphi xe FMX里的窗口如何像处理像VCL里的消息又一示例
  6. 变废为宝,打造人文油画后期效果
  7. iPhone 6和iPhone 6S相机总结
  8. 跨平台开发技术年终盘点
  9. 激活函数(sigmoid、tanh、ReLU、softmax)
  10. yum [Errno 256] No more mirrors to try