本文主要讲述使用MindOpt工具优化仓储物流调度问题
视频讲解👈👈👈👈👈👈👈👈👈
一、 案例场景
物流运输是供应链管理的关键,往往涉及到运输、仓储、装卸、配送等。如何合理安排运输方案提高货物运输的效率和可靠性,降低物流成本,一般考虑以下几点因素:第一,供需匹配,根据各地仓库的需求和工厂的产能,合理安排产成品的供应和配送,满足各地仓库的需求。
第二,运输时间和距离,考虑不同地区的仓库的距离和运输时间,合理安排配送车辆的行程和路线。
第三,车辆容量和装载率,考虑配送车辆的数量、类型、容量等因素。
第四,仓库的容量和储存能力,合理的安排产成品的分配和储存。
第五,时间窗口和优先级,根据仓库的营业时间、订单需求以及优先级要求,合理安排产成品的配送时间和顺序。
第六,货物特性和包装要求,考虑产成品的特性和包装要求,合理安排运输车辆和仓库的设施。
二、 数学规划
仓储物流调度问题也可使用数学规划的方法。
数学规划是一种数学优化方法,主要是寻找变量的取值,在特定的约束情况下,使决策目标得到最大或者最小的决策。数学规划的方法有线性规划、混合整数线性规划以及非线性规划。需要确定问题目标,约束变量取值范围,将其建立成一个数学模型,将数学模型转化为代码进行求解,得出的结果就是最优决策。求解过程中,需要使用优化求解器,可以帮我们求解大规模数据的数学规划问题。
三、 网络流问题
仓储物流调度问题在数学规划中属于网络流问题的一个类型。网络流问题是指一类基于网络模型的流量分配问题,目标是在网络中分配资源,使得网络的流量满足一定的限制条件,并使某些目标函数最小或者最大化。网络流问题通常涉及到这么一个项图,图中每个节点表示一个资源,每条边表示资源之间的关系,边上的容值表示该边上最多可以流动的资源数量。流量从原节点开始流出,经过一系列的中间节点,最终到达汇集点。在这个过程中,需要遵守一定的流量守恒和容量限制的条件。
具体而言,网络流问题可以分为最大流和最小隔两类。仓储物流调度问题属于最小格问题,是寻找一组格,将网络分为两个部分,并将这些格的容量之和最小化,如在下面相图中,使每条边的流量不超过容量约束,同时达到路径长度最小或者花费最小等目标函数的优化问题。
五、 问题描述
我们看一下这个例题的问题描述。某企业需将工厂生产的产品配送至配送中心,再由配送中心发往各个仓库,每个产品搬往不同仓库所需要费用不同,而且每条运输路线运输均有上限。
如何安排运输,使配送成本最低?
这个问题要考虑以下两点因素:一是供需匹配,需要满足各个仓库的产品需求。二是成本控制,在满足供需匹配的同时,尽可能降低运输成本。
六、代码解析
在案例中,我们对这个问题进行数学建模和代码转化,用到MindOpt云上建模求解平台(一个页面版的线上开发环境,可在线的开发调试代码)、以及达摩院研发的建模语言MindOpt APL,与学公式非常贴近。
工具:
- MindOpt Studio 云建模平台,在线开发调试,免下载
- MindOpt APL(MAPL)建模语言编程,代数建模语言,语法与数学公式相近
- MindOpt优化求解器:帮我们求解大规模数据的数学规划问题。
声明集合
set CITIES := {"HN", "NE", "SE", "LN", "JL", "HLJ", "JS", "ZJ"} ;
定义城市集CITIES
,包含了 8 个城市。set LINKS := {<"HN", "NE">, <"HN", "SE">, ..., <"SE", "ZJ">};
定义连接不同城市的链接集LINKS
,表示城市之间的运输线路。
声明参数
param supply[CITIES] := <"HN"> 450 default 0;
定义每个城市的供应量supply
,默认为 0,这里只有"HN"
有供应量 450。param demand[CITIES] := <"JS"> 90, <"ZJ"> 70, <"JL"> 120, <"LN"> 120, <"HLJ"> 50 default 0;
定义每个城市的需求数量demand
,默认为 0。set C := {"cost", "capacity"};
定义成本和容量的属性集C
。param data[LINKS * C] := ... ;
定义每条线路的成本和容量数据data
。
检查数据
forall {<i> in CITIES } check supply[i] >= 0;
验证每个城市的供应量是非负的。forall {<i> in CITIES } check demand[i] >= 0;
验证每个城市的需求数量是非负的。check sum {<i> in CITIES } supply[i] >= sum {<j> in CITIES} demand[j];
验证总供应量大于等于总需求量。
声明变量
var Ship[<i, j> in LINKS] >= 0 <= data[i, j, "capacity"];
定义运输变量Ship
,表示每条线路的运输量,其值必须在 0 和该线路的容量之间。
声明目标
minimize Total_Cost: sum {<i, j> in LINKS } data[i, j, "cost"] * Ship[i, j];
最小化总运输成本。
声明约束
- 对于每个城市
k
,该城市的供应量supply[k]
加上进入该城市的运输量sum {<i, k> in LINKS} Ship[i, k]
必须大于等于该城市的需求数量demand[k]
加上离开该城市的运输量sum {<k, j> in LINKS} Ship[k,j]
。
示例: 假设我们要检查 "JS"
城市的平衡约束,那么有:
supply["JS"]
:"JS"
城市的供应量。demand["JS"]
:"JS"
城市的需求数量。Ship[i, "JS"]
: 进入"JS"
城市的运输量。Ship["JS", j]
: 离开"JS"
城市的运输量。
站点提供的商品数量+发往配送中心的商品数量,至少需要等于配送中心需要的商品数量以及从配送中心发往仓库的商品数量之和,也是满足流量守恒的定义。
结果解析
求解得到了决策目标,最小化成本是2123。我们从河南发往第一个配送中心的商品数量是250,第二个配送中心是200。由第一个配送中心发往其他三个仓库,分别是100、100和50。在决策变量值上可以看出从第二个配送中心发往其他仓库的商品数量之和也等于200,代表变量的取值也满足约束条件。
七、 内容回顾
本期主要讲述的是网络流问题——仓储物流调度的问题。在满足各个仓库的供货需求的情况下尽量减少运输成本。使用到的工具是MindOpt求解平台,以及建模语言MindOpt APL。
获取源代码
网络流问题:交通调度、仓储运输-MindOpt Studio