首页 > 其他分享 >运筹学习笔记之列生成

运筹学习笔记之列生成

时间:2023-08-26 10:06:27浏览次数:41  
标签:geq 0y 求解 运筹 0.5 笔记 生成 问题 alpha

列生成算法介绍

1. 什么是列生成

列生成算法是一种用于解决大规模线性规划问题的高效算法,它基于单纯形法的思想,通过求解子问题来找到可以进基的非基变量。在列生成算法中,每个变量都代表一列,因此称为列生成算法。该算法的优点在于其高效的计算性能和较好的收敛性,适用于处理大规模、复杂的线性规划问题。

在列生成算法的迭代过程中,因为会不断有变量入基,所以会导致限制主问题的列不断增加,所以叫做列生成算法。

2. 列生成的应用范围

列生成被广泛应用于调度问题、切割问题、车辆路径问题、选址问题等。 该算法的优点在于其高效的计算性能和较好的收敛性,适用于处理大规模、复杂的线性规划问题。对于变量数目很多的线性优化问题,单纯形法速度很慢,可以用到列生成方法来加快求解速度。

3. 列生成的原理

基本思路如下:

1、先把原问题限制到一个规模更小的限制主问题,在限制主问题的基础上用单纯形法求解,但此时的解并不是主问题的最优解。

2、通过一个子问题去检查那些未被考虑的变量中是否有使得reduced cost小于0的?如果有,就把这个变量的相关系数列加入到限制主问题的系数矩阵中,回到第一步。

经过反复迭代,知道子问题的reduced cost rate大于等于0,那么主问题就求到了最优解。

4. 基本概念

受限主问题

$$ min(y_1+y_2+\cdots+y_k) $$

$s.t.$ $$ R_1: a_{11}y_1+\cdots+a_{1k}y_k \geq b_1\ R_2: a_{21}y_1+\cdots+a_{2k}y_k \geq b_2\ \cdots\ R_m:a_{m1}y_1+\cdots+a_{mk}y_k \geq b_m $$ 就是从主问题中选取k个变量构成的松弛问题。

子问题

通过求解RMP问题或者RMP对偶问题后,得到了想要的$c_BB^{-1}$以后,子问题就是通过$\sigma_j = c_j - c_BB^{-1}a_j$

这条公式,在$y_{k+1}、y_m$中寻找检验数为负且最小的变量,将变量对应的那一列添加到RMP中。

列生成算法实现

1. 案例求解

问题描述

cutting stock problem是采用列生成算法求解的经典案例。该问题如下:有一些纸筒,每个纸筒长度为16m。顾客需要25个3m,20个6m,15个7m的纸筒。要求在满足顾客需求的情况下,裁剪的纸筒数最小。

建立模型

可以采用启发式算法求解到一个初始解如下:

5个纸筒采用切割方案1:3,3,3,3,3;

10个纸筒采用切割方案2:6,6;

8个纸筒采用切割方案3:7,7;

总计23个纸筒。可以看出,采用23个纸筒是一定可以满足要求的,这是问题的一个上界(upper bound)。

该问题可行的切割方案很多,我们可以采用P表示所有可行裁剪方案的集合,里面的方案总数为n(这里的n并不需要知道其确切取值,一般来说n是一个很大的数)。$a_{ij}$表示第$j$种方案里类别$i$的个数,$y_j$表示第$j$种方案的选择个数。建立数学模型如下: $$ min \quad y_1+y_2+\cdots+y_n $$ $s.t.$ $$ R1:a_{11}y_1 + \cdots + a_{1n}y_n \geq 25\ R2:a_{21}y_1 + \cdots + a_{2n}y_n \geq 20\ R3:a_{31}y_1 + \cdots + a_{3n}y_n \geq 15\ $$ 约束中的每一列对应的是一种切割方案,前三种方案已知,就是我们前面采用启发式算法求解的三种方案。其它的$n-3$种切割方案未知。

问题求解

第一轮循环

首先从上述模型中选出一些列,构成问题的限制主问题,这里我们选取前3列。则限制主问题如下 $$ min \quad y_1 + y_2 + y_3 \ 5y_1 + 0 y_2 + 0y_3 \geq 25\ 0y_1 + 2 y_2 + 0y_3 \geq 20\ 0y_1 + 0 y_2 + 2y_3 \geq 15\ $$ 使用python+gurobi求解上述线性规划问题

import gurobipy as gp
# 实例化模型
m = gp.Model('column generation')
y = m.addVars(3,vtype = gp.GRB.CONTINUOUS,name='y',lb=0)
m.addConstr(5*y[0] >= 25)
m.addConstr(2*y[1] >= 20)
m.addConstr(2*y[2] >= 15)
m.setObjective(y[0]+y[1]+y[2],gp.GRB.MINIMIZE)
m.setParam('OutputFlag',0)
m.optimize()
m.getAttr(gp.GRB.Attr.Pi)

可以求解出对偶变量的取值为$c_BB^{-1}=[0.2,0.5,0.5]$。现在要找一列加入RMP,但是并不知道其取值,我们将其记作$\alpha_4 = [a_{14},a_{24},a_{34}]^T$。得到非基变量的检验数为$\sigma_4 = c_4 - c_BB^{-1}\alpha_4 = 1-0.2\alpha_{14} - 0.5\alpha_{24} - 0.5\alpha_{34}$

从而构造子问题如下: $$ min(1-0.2a_{14} - 0.5a_{24} - 0.5a_{34}) $$ $s.t.$ $$ 3a_{14}+6a_{24}+7a_{34} \leq 16\ a_{ij} \in Z $$ 同样采用python+gurobi求解上述问题

import gurobipy as gp
m1 = gp.Model('subproblem')
a = m1.addVars(3,vtype=gp.GRB.INTEGER,lb=0,name='a')
m1.setObjective(1-0.2*a[0]-0.5*a[1]-0.5*a[2])
m1.addConstr(3*a[0]+6*a[1]+7*a[2] <= 16)  # 列生成规则
m1.setParam('OutputFlag',0)
m1.optimize()
print(a[0].x,a[1].x,a[2].x)

求解出$\alpha_4 = [1,2,0]^T$,检验数为$\sigma_4 = c_4 - c_BB^{-1}\alpha_4 = 1-0.2\times1 - 0.5\times2 - 0.5\times0 = -0.2 < 0$,因为检验数小于0,所以需要将$y_4$入基,添加到主问题中,开始第二轮迭代。

第二轮循环

加入$y_4$后,限制主问题变为 $$ min \quad y_1 + y_2 + y_3 + y_4 \ 5y_1 + 0 y_2 + 0y_3 + 1y_4\geq 25\ 0y_1 + 2 y_2 + 0y_3 + 2y_4 \geq 20\ 0y_1 + 0 y_2 + 2y_3 + 0y_4 \geq 15\ $$ 限制主问题与之前相比,多了一列,所以被称为列生成算法。求解该限制主问题,其对偶变量取值为$c_BB^{-1}=[0.2,0.4,0.5]$,下一个需要入基的变量记为$\alpha_5 = [a_{15},a_{25},a_{35}]^T$,构造子问题如下 $$ min(1-0.2a_{15} - 0.4a_{25} - 0.5a_{35}) $$ $s.t.$ $$ 3a_{15}+6a_{25}+7a_{35} \leq 16\ a_{ij} \in Z $$ 采用同样方法求解该子问题,得到结果$\alpha_5 = [3,0,1]^T$,检验数为$\sigma_5 = c_5 - c_BB^{-1}\alpha_5 = 1-0.2\times3 - 0.4\times0 - 0.5\times1 = -0.1 < 0$,因为检验数小于0,所以需要将$y_5$入基,添加到主问题中,开始下一轮迭代。

第三轮循环

加入$y_5$后,限制主问题变为 $$ min \quad y_1 + y_2 + y_3 + y_4 + y_5 \ 5y_1 + 0 y_2 + 0y_3 + 1y_4 + 3y_5\geq 25\ 0y_1 + 2 y_2 + 0y_3 + 2y_4 + 0y_5 \geq 20\ 0y_1 + 0 y_2 + 2y_3 + 0y_4 + 1y_5 \geq 15\ $$ 还是求解限制主问题,其对偶变量取值为$c_BB^{-1}=[0.1667,0.4167,0.5]$,下一个需要入基的变量记为$\alpha_6 = [a_{16},a_{26},a_{36}]^T$,构造子问题如下 $$ min(1-0.1667a_{16} - 0.4167a_{26} - 0.5a_{36}) $$ $s.t.$ $$ 3a_{16}+6a_{26}+7a_{36} \leq 16\ a_{ij} \in Z $$ 求得结果$\alpha_5 = [1,1,1]^T$,检验数$\sigma_6= c_6 - c_BB^{-1}\alpha_6 = 1-0.1667\times1- 0.4167\times1 - 0.5\times1 = -0.08333 < 0$,所以将$y_6$代入

第四轮循环

加入$y_6$后,限制主问题变为 $$ min \quad y_1 + y_2 + y_3 + y_4 + y_5 + y_6 \ 5y_1 + 0 y_2 + 0y_3 + 1y_4 + 3y_5 + y_6\geq 25\ 0y_1 + 2 y_2 + 0y_3 + 2y_4 + 0y_5 + y_6 \geq 20\ 0y_1 + 0 y_2 + 2y_3 + 0y_4 + 1y_5 + y_6 \geq 15\ $$ 还是求解限制主问题,其对偶变量取值为$c_BB^{-1}=[0.2,0.4,0.4]$,下一个需要入基的变量记为$\alpha_7 = [a_{17},a_{27},a_{37}]^T$,构造子问题如下 $$ min(1-0.2a_{17} - 0.4a_{27} - 0.4a_{37}) $$ $s.t.$ $$ 3a_{17}+6a_{27}+7a_{37} \leq 16\ a_{ij} \in Z $$ 求得结果$\alpha_5 = [5,0,0]^T$,检验数$\sigma_6= c_6 - c_BB^{-1}\alpha_6 = 1-0.2\times5- 0.4\times0 - 0.4\times0 = 0$,结束迭代,此时列生成算法结束。

此时,我们将$y_7$代入模型,此时求解结果就是最优解。

求解出最优解为$y=[1,0,0,3,1,14,0]$,此时目标函数值为19。

所以我们得到的最终切割方案为

方案 该方案的数量
3,3,3,3,3,3 1
3,6,6 3
3,3,3,7 1
3,6,7 14

标签:geq,0y,求解,运筹,0.5,笔记,生成,问题,alpha
From: https://blog.51cto.com/u_16237769/7240060

相关文章

  • openGauss学习笔记-51 openGauss 高级特性-列存储
    openGauss学习笔记-51openGauss高级特性-列存储openGauss支持行列混合存储。行存储是指将表按行存储到硬盘分区上,列存储是指将表按列存储到硬盘分区上。行、列存储模型各有优劣,建议根据实际情况选择。通常openGauss用于OLTP(联机事务处理)场景的数据库,默认使用行存储,仅对执行复杂......
  • csapp学习笔记——第二章信息的表示和处理
    csapp学习笔记——第二章信息的表示和处理本章主要讲了计算机系统中的数据的表示方法以及在为什么会出现相关的转化问题(floatintdouble等互相转换)。计算机系统中的数字表示方法在现实世界中我们使用的是十进制的表示方法,而在计算机系统中我们则使用的是2进制的表示方法(构造储......
  • 线段树+动态开点权值线段树+主席树学习笔记
    线段树一般用于维护符合结合律的信息。可以用于求区间最大值区间和区间最小值最大子段和甚至于最大负数最小正数之类的信息。事实上线段树只有你想不到,很少有做不到的,算是相当常用的数据结构。下面将结合个人理解和具体题目来讲一讲线段树。[https://www.luogu.com.cn/proble......
  • Makefile学习笔记
    规则:每条规则由三个部分组成分别是目标(target),依赖(depend)和命令(command)。#示例#规则1app:a.ob.oc.ogcca.ob.oc.o-oapp#规则2a.o:a.cgcc-ca.c#规则3b.o:b.cgcc-cb.c#规则4c.o:c.cgcc-cc.c makefile有自动推导功能,有时漏......
  • 《算法笔记》树与二叉树专题练习
    1、复原二叉树(由前序和中序求后序)题目描述小明在做数据结构的作业,其中一题是给你一棵二叉树的前序遍历和中序遍历结果,要求你写出这棵二叉树的后序遍历结果。输入输入包含多组测试数据。每组输入包含两个字符串,分别表示二叉树的前序遍历和中序遍历结果。每个字符串由不重复的大写......
  • 【学习笔记】二维偏序
    看着名字挺高级的就来学一下awa二维偏序是解决这样子的问题:有\(n\)个点,每一个点都有两个属性\(a,b\),且满足\[\left\{\begin{aligned}&i<j\\&a_i\lea_j\\&b_i\leb_j\end{aligned}\right.\]然后去求一些奇奇怪怪的问题解法是离散化后排序然后用两个树状数组来维护......
  • .net6 下 SqlSugar迁移创建表以及生成实体类
    一、下载安装包 二、创建类  三、链接数据库 四创建MyContext类   五、创建控制器,写创建表的方法   六、运行后,返回true就OK了   ......
  • 杂题笔记
    CF11DASimpleTask题意给定一个\(n\)个点\(m\)条边的简单无向图,询问里面有多少个简单环。\(n\leq19\)解法对于每一个环,用唯一确定的方法去标记他。(寻找另一种更容易统计的对象,让这种对象可以唯一对应一个环)我们可以找到这个环里面编号最小的点,分别从这个点的左侧和......
  • 03.前后端分离中台框架 zhontai 项目代码生成器的使用
    合集-zhontai(3) 1.01.前后端分离中台框架后端Admin.Core学习-介绍与配置说明08-202.2.前后端分离中台框架前端admin.ui.plus学习-介绍与简单使用08-213.03.前后端分离中台框架zhontai项目代码生成器的使用08-22收起 zhontai项目基于.Net7.x+Vue等......
  • openGauss学习笔记-50 openGauss 高级特性-DB4AI
    openGauss学习笔记-50openGauss高级特性-DB4AIopenGauss当前版本支持了原生DB4AI能力,通过引入原生AI算子,简化操作流程,充分利用数据库优化器、执行器的优化与执行能力,获得高性能的数据库内模型训练能力。更简化的模型训练与预测流程、更高的性能表现,让开发者在更短时间内能更专注......