OUTLINE

  • 前言
  • VRPTW description
  • column generation
  • Illustration
  • code
  • reference

00 前言

此前向大家介绍了列生成算法的详细过程,以及下料问题的代码。相信各位小伙伴对column generation已经有了一个透彻的了解了。今天我们在来一点干货,用column generation求解vehicle routing problems。

01 VRPTW description

关于VRPTW问题的描述,以及建模方式,可以参照此文干货|十分钟快速掌握CPLEX求解VRPTW数学模型(附JAVA代码及CPLEX安装流程)。不过今天给大家带来的是VRPTW的另外一个建模方式,它是在传统的模型上利用了Dantzig-Wolfe decomposition分解算法得到的。

关于Dantzig-Wolfe decomposition分解算法,可以参照文章:

Formulation:[1]

  • $\Omega $ :the set of feasible vehicle routes, i.e., the set of paths in G issued from the
    depot, going to the depot, satisfying capacity and time window constraints and visiting
    at most once each customer.
  • \(c_k\) :the cost of route \(r_k \in \Omega\).
  • $ a_{ik}$ := 1 if route\(r_k\)visits customer\(v_i\) and = 0 otherwise.
  • $ b_{ijk}$ := 1 if route\(r_k\)uses arc\((v_i,v_j)\)and = 0 otherwise.

The VRPTW can be described with the following set covering model:

where \(θ_k\) indicates whether route \(r_k\) is selected (\(θ_k\) = 1) or not (\(θ_k\) = 0) in the solution.其中\(v_0\)是depot点。

其中:

  • 约束1保证了每个Customer都至少被服务一次。
  • 约束2限制了车辆的使用数量。
  • $\theta_k \(定义为整数,但显然当\)\theta_k > 1$时解都不是最优的。这样做的目的是为了后续使用column generation时获得一个更好的线性松弛。

02 column generation

从上面的模型中,先来讨论一个点,用\(S(\Omega)\)表示集合\(\Omega\)里面的路径数量,n表示Customer的点数,那么
\(S(\Omega)\)和n的关系可以看下表:

\(S(\Omega)\) n
10 \((A_{10}^2+A_{10}^3+A_{10}^4+...+A_{10}^{10})/2\)
20 \((A_{20}^2+A_{20}^3+A_{20}^4+...+A_{20}^{20})/2\)
... ...
100 \((A_{100}^2+A_{100}^3+A_{100}^4+...+A_{100}^{100})/2\)

可以看出,变量\(\theta\)的数目随着问题规模n的增长会爆炸式的增长。这时候,显然branch and bound这类的算法已经无能为力了,因为变量数目太多太多,搜索树会有多少个分支想都不敢想。

所以,我们上一节课讲的column generation就派上用场辣。如果相关概念还不清楚的就赶紧回去翻一翻上一次课的内容吧。

2.1 Master Problem(MP)

我们知道,column generation是求解linear program的,因为上面的model是一个整数规划模型,还不能直接挪过来当Master Problem。

在此之前,我们需要将\(\theta_k \in N\)给线性松弛一下变成\(\theta_k >= 0\)。这下\(\theta_k\)就从整数变量松弛为线性变量了。由此我们可以得出问题的Master Problem如下:

2.2 Restricted Master Problem(RMP)

在上述模型中,约束5中的列直观表现为一条可行的路径\(r_k\),现在要Restricted一下我们的Master Problem,直接Restricted Master Problem中的 \(\Omega\)即可。我们设\(\Omega_1 \subset \Omega\),那么Restricted Master Problem可以表示为:

然后我们再顺便把RMP的对偶model也写出来,便于后续对偶变量的求解:

在对偶模型中:

  • \(\lambda_i\)是非负的对偶变量,对应着约束(9)。
  • \(\lambda_0\)是非负的对偶变量,对应着约束(10)。

2.3 Subproblem

子问题要做的就是找一条路\(r_k \in \Omega \setminus \Omega_1\)使得,

其中,\(r_k\)受到的约束:

  • 从depot出发,最终回到depot。
  • 满足容量和时间窗的约束。

03 Illustration

在这一节我们将会给大家带来一个简单的VRPTW实例,详细演示一下column generation求解VRPTW的过程。大家可以再次熟悉一下column generation的原理。

假如我们有以下的一个very simple的VRPTW问题:

其中:

  • 边上数字表示路径的距离。
  • 点上的区间表示时间窗。
  • 为了更加简化问题,我们假设车的容量足够大(总是能容量约束),车的数量足够多(总是能满足数量约束)。

Start

一开始我们很容易找到一个初始的路径集合$\Omega_1 = {(v_0,v_1,v_0),(v_0,v_2,v_0),(v_0,v_3,v_0) } $。
服务所有的Customer。所以得到的Restricted Master Problem和Dual programs如下:

Iteration 1

RMP ( $\Omega_1 = {(v_0,v_1,v_0),(v_0,v_2,v_0),(v_0,v_3,v_0) } $ ):

很容易求得上述模型的最优解为\(\theta = (1,1,1), \lambda = (2,2.8,2)\)。

现在假如subproblem通过启发式或者什么方法找到了一条路径$ r_4 = (v_0,v_1,v_2,v_0)\(,路径\)r_4\(的reduce cost 为3.4-2-2.8 = -1.4 < 0。现在将\)r_4\(加入到\)\Omega_1 $中,开始下一轮迭代。

Iteration 2

RMP ( $\Omega_1 = {(v_0,v_1,v_0),(v_0,v_2,v_0),(v_0,v_3,v_0), (v_0,v_1,v_2,v_0)} $ ):

Again,很容易求得上述模型的最优解为\(\theta = (0,0,1,1), \lambda = (2,1.4,2)\)。

subproblem找到了一条路径$ r_5 = (v_0,v_1,v_2,v_3,v_0)\(,路径\)r_5\(的reduce cost 为4-2-1.4-2 = -1.4 < 0。现在将\)r_5\(加入到\)\Omega_1 $中,开始下一轮迭代。

Iteration 3

RMP( $\Omega_1 = {(v_0,v_1,v_0),(v_0,v_2,v_0),(v_0,v_3,v_0), (v_0,v_1,v_2,v_0),(v_0,v_1,v_2,v_3,v_0)} $ ):

求解得到最优解为\(\theta = (0,0,0,0,1), \lambda = (2,1.4,0.6)\)。

现在我们可以easily发现,还剩下两条route不在\(\Omega_1\)之中了。而这两条route的reduce cost都非负,列生成算法停止。并且在这个例子中,linear relaxation的解是integer optimal solution。

至此,列生成算法求解VRPTW的过程结束,相信这么详细的过程大家已经看懂了。

04 code

关于列生成算法求解VRPTW的算法将会在下一期呈现,大家可以先把这两期的内容好好消化了先。请关注我们的公众号以获取最新的消息,在第一时间获取代码:

可以关注我们的公众号哦!获取更多精彩消息!

05 reference

-[1]A tutorial on column generation and branch-and-price for vehicle routing problems, Dominique Feillet

干货 | 10分钟教你用column generation求解vehicle routing problems的更多相关文章

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

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

  2. 10分钟 教你学会Linux/Unix下的vi文本编辑器

    10分钟 教你学会Linux/Unix下的vi文本编辑器 vi编辑器是Unix/Linux系统管理员必须学会使用的编辑器.看了不少关于vi的资料,终于得到这个总结.不敢独享,和你们共享. 首先,记住v ...

  3. 【python】10分钟教你用python打造贪吃蛇超详细教程

    10分钟教你用python打造贪吃蛇超详细教程 在家闲着没妹子约, 刚好最近又学了一下python,听说pygame挺好玩的.今天就在家研究一下, 弄了个贪吃蛇出来.希望大家喜欢. 先看程序效果: 0 ...

  4. 10分钟教你用Python打造天气机器人+关键字自动回复+定时发送

    01 前言 Hello,各位小伙伴.自上次我们介绍了Python实现天气预报的功能以后,那个小程序还有诸多不完善的地方,今天,我们再次来完善一下我们的小程序.比如我们想给机器人发“天气”等关键字,它就 ...

  5. 10分钟教你用Python打造微信天气预报机器人

    01 前言 最近武汉的天气越来越恶劣了.动不动就下雨,所以,拥有一款好的天气预报工具,对于我们大学生来说,还真是挺重要的了.好了,自己动手,丰衣足食,我们来用Python打造一个天气预报的微信机器人吧 ...

  6. 10分钟教你用Python玩转微信之好友性别比例统计分析

    01 前言+效果展示 想必,微信对于大家来说,是再熟悉不过的了.那么,大家想不想探索一下微信上的各种奥秘呢?今天,我们一起来简单分析一下微信上的好友性别比例吧~废话不多说,开始干活. 结果如下: 02 ...

  7. 10分钟教你用Python玩转微信之抓取好友个性签名制作词云

    01 前言+展示 各位小伙伴我又来啦.今天带大家玩点好玩的东西,用Python抓取我们的微信好友个性签名,然后制作词云.怎样,有趣吧~好了,下面开始干活.我知道你们还是想先看看效果的. 后台登录: 词 ...

  8. 10分钟教你用VS2017将代码上传到GitHub

    前言 关于微软的Visual Studio系列,真可谓是宇宙最强IDE了.不过,像小编这样的菜鸟级别也用不到几个功能.今天给大家介绍一个比较实用的功能吧,把Visual Studio 2017里面写好 ...

  9. 【C/C++】10分钟教你用C++写一个贪吃蛇附带AI功能(附源代码详解和下载)

    C++编写贪吃蛇小游戏快速入门 刚学完C++.一时兴起,就花几天时间手动做了个贪吃蛇,后来觉得不过瘾,于是又加入了AI功能.希望大家Enjoy It. 效果图示 AI模式演示 imageimage 整 ...

随机推荐

  1. 深度剖析java中JDK动态代理机制

    https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...

  2. ELK +Nlog 分布式日志系统的搭建 For Windows

    前言 我们为啥需要全文搜索 首先,我们来列举一下关系型数据库中的几种模糊查询 MySql : 一般情况下LIKE 模糊查询  SELECT * FROM `LhzxUsers` WHERE UserN ...

  3. React 语法

    1.JavaScript XML JSX = JavaScript XML,是一个看起来很像 XML 的 JavaScript 语法扩展.JSX 不是模板,是JS语法本身,有更多的扩展.JSX 组件一 ...

  4. in __init__ self._traceback = tf_stack.extract_stack()的一个原因

    这样就会出错,原因在于函数返回为三个变量,若直接向写入函数那样运用sess.run()得到,就会导致错误. sess=tf.Session() sess.run(tf.initialize_all_v ...

  5. 【Java基础】- Java学习路线图

    Java的学习路线图,整理以备自己学习和温习. 1.Java基础 具体内容: 1. 编程基础(开发环境配置.基础语法.基本数据类型.流程控制.常用工具类) 2. 面向对象(继承.封装.多态.抽象类.接 ...

  6. 浅谈JS中 var let const 变量声明

    浅谈JS中 var let const 变量声明 用var来声明变量会出现的问题: 1. 允许重复的变量声明:导致数据被覆盖 2. 变量提升:怪异的数据访问.闭包问题 3. 全局变量挂载到全局对象:全 ...

  7. vue侦听器 基础4

    侦听器 使用方式:设置需要侦听的data里的属性名就可以了 new Vue({ el:"#app", data:{ count:0 }, watchers:{ count(){ / ...

  8. 金融finaunce单词finaunce财经

    金融(FINANCE或FINAUNCE)就是对现有资源进行重新整合之后,实现价值和利润的等效流通.(专业的说法是:实行从储蓄到投资的过程,狭义的可以理解为金融是动态的货币经济学.) 金融是人们在不确定 ...

  9. SparkSQL之dataframe写入mysql报错

    一.异常情况及解决方案 在使用Spark SQL的dataframe数据写入到相应的MySQL表中时,报错,错误信息如下: 代码的基本形式为: df.write.jdbc(url, result_ta ...

  10. 分布式数据库中间件、产品——sharding-jdbc、mycat、drds

    一般对于业务记录类随时间会不断增加的数据,当数据量增加到一定量(一般认为整型值为主的表达到千万级,字符串为主的表达到五百万)的时候,性能将遇到瓶颈,同时调整表结构也会变得非常困难.为了避免生产遇到这样 ...