title: VRP算法学习
author: Chen Yanbo
mathjax: true
date: 2019-04-13 14:41:48
tags:
列生成
介绍
列生成算法是求解大规模整数规划问题的优化算法,其理论基础由Danzig 等于1960 年提出,1995年Desrochers等将列生成算法实际应用到驾驶员调度及VRP问题中。目前,列生成已经被成功应用于多个领域列生成求解过程中,将整数规划问题线性松弛后成为 主问题MP(Master Problem)。鉴于变量规模较大,初始时只考虑小部分变量,构造 限制主问题RMP(Restricted Master Problem),通过求解受限主问题的最优解,获得线性规划的对偶变量,并在构造网络中寻找可以使目标函数优化的新变量,并将之加入到受限主问题中再次进行求解,如此迭代,直到无法寻找到可使目标函数优化的变量,得到松弛问题的最优解。如果解为整数,则为原问题的最优解,如果存在非整数解,则需要进行分支定界寻找整数解。
算法
(1)主问题与初始可行解
\begin{align}
&\min \sum_{j \in J} c_j \lambda_j\
s.t \quad &\sum_{j \in J} a_j \lambda_j\geq b \
& \lambda\geq 0,j \in J
\end{align}
这是一个通用的线性规划模型,其中集合J代表所有的列(column)。MP的对偶变量用非负向量来表示,根据对偶理论,我们希望找到一个能够使得的值最小。
(2)受限主问题求解及对偶变量
当的值很大时,这种直接定价(pricing)的方法运算成本很高。所以考虑取一个合理的子集来操作,用 间接枚举(implicit enumeration)的方法来计算 检验成本(reduced cost),得到限制主问题。假设和分别是当前RMP的原始最优解和对偶最优解,给定一个集合A,它由列(column)组成,目标函数的成本系数可以通过关于的函数式计算得到,由此得到子问题的检验成本
\begin{align}
c^=\min {c(a)-\pi^T a|a\in A}
\end{align}
(3)问题求解,生成新列
对于上面的检验成本,如果 ,且不存在负的 那么就说明限制主问题的解 就是主问题的最优解。若 向RMP添加来自子问题的最优解,并且不断对RMP进行重新优化(re-optimizing)。当处理有限集合时,列生成算法是精确的(即现实问题都是精确的)。有限集合A 时,列生成算法是精确的(即现实问题都是精确的)。
分枝定界法
介绍
对于 整数规划间题(IP),当直接求解它比较困难时,可以采用“分而治之"(divide and conquer)的策略,先将可行域分割成一些小的集合,然后,在较小的集合上求解相应目标函数的最优值,并将结果集成在一起生成原问题的最优解。值得指出的是,在求解较小集合对应的子问题时,还可以利用分而治之的策略进行分析此外,可以采取多种措施对子问题进行分析,例如可以估计子问题最优值的某个界,将它与已经知道的原间题的可行目标值进行比较,如果能够断定子问题无法获得更好的可行目标值,那么就不需要对子问题进行精确地求解。这就是 分枝定界法(branch and bound method)的基本思想。
算法
(1)初始化
令整数规划子问题表示为最优值的上界,下界。
(2)最优性检验
若,则当时,可行域; 当时,满足的点是(IP)的最优解,算法停止。
(3)分枝与松弛
从C中取出一个子问题(IP;),并求解它的松弛形式(RP')若松弛问题(RP;)存在最优解,则记其最优解为,对应的最优值为
剪枝
(4.1)若,则转(2)。(有时,并不需要真正求出松弛间题的最优值,在对偶间题得到的对偶目标值接近或者小于时即可判断该条件是否满足)
(4.2)若,则转(5)。
(4.3)若,并且,则置,并且从C中删除所有的上界的分枝,转(5)。
(5)分割
生成的一个分割增加到C中,并且置,转(2)。
运用列生成和分支定界法求解VRP问题
模型
基于集划分(Set Partitioning,SP)或 集覆盖(Set Covering,SC)的模型广泛运用于CVRP问题中。这个公式最初是由Balinski和Quandt提出的。为了便于求解,这部分的VRP 问题假设为此种模型。设G=(N,R) 的所有路径节点的集合,对应于可行的路径,每条路径都有一个相关的成本,令表示顾客i经过路径r的次数。CVRP的扩展模型为:
\begin{align}
&\min \sum_{r \in \Omega } c_r \lambda_r\
s.t \quad &\sum_{r \in \Omega } a_{ir} \lambda_r=1 \
& \sum_{r \in \Omega}\lambda_r=|K|\
& \lambda_r \in {0,1}
\end{align}
限制主问题
对于上面的模型,对公式(3.4)进行线性松弛。根据列生成的理论,可以得到限制主问题的模型:
\begin{align}
&\min \sum_{r \in R' } c_r \lambda_r\
s.t \quad &\sum_{r \in R' } a_{ir} \lambda_r=1 \
& \sum_{r \in R'}\lambda_r=|K|\
& 0\leq \lambda_r\leq 1,\forall r \in R'
\end{align}
其中,,仅包含已经计算的路径。
问题求解,生成新列
限制主问题的初始解选定为只包含一个顾客的路径,即depot-i-depot。求解这个限制主问题,得到限制主问题的最优解,最优解的目标函数值作为新的检验成本(reduced cost),如果检验成本小于零,说明非最优解,则将这个限制主问题的解作为一列加入到限制主问题中,重新求解新的限制主问题。如此循环直至检验成本非负。
若存在非整数解,则进行分枝定界
通过反复迭代,若不再有检验成本的路径产生,则表明主问题已经达到最优解,如果解为整数,则为原问题的最优解;如果解为小数,则应为原规划问题的下界,需要应用分枝定界法,寻找原问题的最优解.通过对边的0-1分枝重新构造其所对应的有向网络,并应用列生成进行求解,直到找到最优整数解为止。
(1)设置变量
(2)任意选定边,执行,并对边进行分枝:
(3),构造网络,删掉边,应用列生成进行求解。若解为整数,且目标函数值,则更新;若解为非整数,且,则舍弃此分枝并返回(2);若解为非整数,且,则返回(2)继续分枝。
(4),构造网络,删掉边(i,z),其中,应用列生成法进行求解.若解为整数,且目标值,则更新为;若解为非整数,且,则舍弃此分枝并返回(2);若解为非整数,且,则返回(2)继续分枝。
算法求解流程
整个求解的流程如下:首先建立一个Set Partitioning的CVRP模型,对约束条件进行线性松弛,得到主问题的限制主问题。对限制主问题进行求解后,更新新的检验成本,若检验成本大于零,说明该解有提升的空间,则将这个限制主问题的解作为一列加入限制主问题中更新得到新的问题,重新求解,直到检验成本为负。若此时得到的最优解不是整数,则该最优解为问题的下界,通过分枝定界法继续进行求解,得到一个最优的整数解。算法的流程图如下:
[图片上传失败...(image-6dc698-1555141349024)]