网络流问题
网络最大流问题
研究网络通过的流量也是生产管理中经常遇到的问题
例如:交通干线车辆最大通行能力、生产流水线产品最大加工能力、供水网络中最大水流量等。这类网络的弧有确定的容量,虽然常用
c
i
j
c_{ij}
cij表示从节点
i
i
i到节点
j
j
j的弧的最大流量,但实际上通过该弧的流量不一定能达到最大流量,因此常用
f
i
j
f_{ij}
fij,表示通过弧的实际流量。
对于网络最大流研究,主要是下面两个问题
- 从网络的起点出发到网络终点所能达到的最大流量;
- 当求解网络最大流量后,分析限制网络流量最大化的关键弧,通过某些方法增加该弧的容量,使网络最大化流量增加更多。
通过对网络流的分析,网络最大流有以下三个基本特点:
- 起点的流出量和终点的流入量相等,
- 每个节点的流入量和流出量相等;
- 每条弧的实际流量不能超过最大容量
网络最大流问题的线性规划模型
根据网络最大流的三个基本特点,很容易建立起网络最大流的线
性规划模型。
m
a
x
V
=
∑
i
=
1
n
f
s
i
=
∑
i
=
1
n
f
i
t
max\ V=\sum_{i=1}^{n}f_{si}=\sum_{i=1}^{n}f_{it}
max V=i=1∑nfsi=i=1∑nfit
s
.
t
.
{
∑
v
f
i
v
=
∑
v
′
f
v
′
i
,
i
≠
s
,
e
0
≤
f
i
j
≤
c
i
j
,
1
≤
i
,
j
≤
n
s.t.\quad\left\{\begin{matrix} \sum_{v}f_{iv}=\sum_{v'}f_{v'i},\ i\ne s,e \\ 0\le f_{ij}\le c_{ij},\quad 1\le i,j\le n \end{matrix}\right.
s.t.{∑vfiv=∑v′fv′i, i=s,e0≤fij≤cij,1≤i,j≤n
其中,s表示起点编号,e表示终点编号
f
i
j
f_{ij}
fij表示弧
i
j
ij
ij的流量,
c
i
j
c_{ij}
cij表示弧
i
j
ij
ij的最大容量
根据容量网络的拓扑结构,每个弧的最大容量,起点和终点,我们通过求解线性规划就可以得到从网络的起点出发到网络终点所能达到的最大流量。
网络最大流问题的Matlab求解
%计算从起点1到终点6的最大流量
s = [1 1 1 2 3 3 4 4 5];
t = [2 3 4 6 4 5 5 6 6];
weights = [70 100 90 80 40 70 40 100 90];
G = digraph(s, t, weights);
H = plot(G, 'EdgeLabel', G.Edges.Weight);
[mf, GF] = maxflow(G, 1, 6);
H.EdgeLabel = {};
highlight(H, GF, 'EdgeColor', 'r', 'Line Width', 2);
st = GF.Edges.EndNodes;
labeledge(H, st(:, 1), st(:, 2), GF.Edges.Weight);
formatSpec= '从起点1到终点6的网络最犬流量为:%4.0f\n'; fprintf(formatSpec, mf);
路径规划问题
路径规划问题
首先,我们简单了解下运动规划问题:在给定的位置A与位置B之间为机器人找到一条符合约束条件的路径。这种问题常出现在机器人、汽车导航等工业应用中。而路径规划则是运动规划里的重要研究内容。
所谓路径规划,就是指在一张已知的地图上,规划出一条位置A到位置B的路径。而运动规划里也有很多不知地图的情形,需要机器人自主去构建地图、自主摸索规划路径
而对于游戏程序的运动规划问题,更多(甚至绝大部分)都是路径规划问题因为游戏地图几乎总是已知的。用Dijkstra算法求解单源最短路问题,但类似的算法思想在二维坐标中代价过高,通常用A* 算法来求解路径规划问题
路径规划寻路计算
下面分析A*
算法如何规划路径:
- A是起点,将A放入closeList;
- 与A相邻的八个节点都不是障碍物,可达,放入openList,把A设为它们的父节点;
- 从openList选一个与A相邻的节点,选最小f值的节点:
f ( n ) = g ( n ) + h ( n ) f(n)=g(n)+h(n) f(n)=g(n)+h(n)
f ( n ) f(n) f(n)是节点n的综合优先级; g ( n ) g(n) g(n)是节点n距离起点A的代价(距离); h ( n ) h(n) h(n)是节点n距离终点B的预估代价(距离); - 下一步路径的产生:反复遍历openList,选f值最小的节点。
g
(
n
)
g(n)
g(n)可以直接计算;
h
(
n
)
h(n)
h(n)的计算:
本问题只能上下左右对角线八个方向移动,选择曼哈顿距离;如果能向任意方向移动,可以用欧式距离;计算h(n)时忽略障碍物,不考虑对角线距离,这是对剩余距离的估计值,不是实际值。
检查
n
22
n_{22}
n22周围节点,忽略障碍物节点,将可达节点加入到openList中,并将
n
22
n_{22}
n22设置为这些新增节点的父节点,重新计算各个节点的f值。
通过观察,发现节点的路径1 A→
n
32
n_{32}
n32比路径2 A→
n
22
n_{22}
n22→
n
32
n_{32}
n32的f值更优,此时路径可变更为A→
n
32
n_{32}
n32。因为A→
n
12
n_{12}
n12与A→
n
32
n_{32}
n32的f值是相同的,在编程过程中一般选最后加入openList的节点。
接下来
n
32
n_{32}
n32加入closeList,检查
n
32
n_{32}
n32周围节点,忽略障碍物节点,将可达节点加入到openList中,并将
n
32
n_{32}
n32设置为这些新增节点的父节点,重新计算各个节点的 f值。选择最小的
n
43
n_{43}
n43加入到closeList。
重复上面的过程,直至把终点B加入openList。
从终点开始,根据箭头方向向父节点移动,回到起点,就获得了最终的路径。
车辆路径问题(VRP问题)
车辆路径问题
VRP(VehicleRoutingProblem,车辆路径问题)是TSP问题的扩展,是交通运输、物流供应链领域的研究热点。
例如,某配送中心对一定区域内的客户(需求点)进行货物配送服务,每个客户的货物配送量小于车辆的最大装载量,且每个客户距离配送中心,以及各个客户之间的距离是已知的,通常不存在只需要一辆车跑一趟就满足全部客户的配送需求(如果存在这种情况,VRP退化到TSP)。
一般来说,需要多辆车或一辆车跑多趟才能满足全部客户的配送需求。此时要解决的问题是:
- 哪些客户的货物应该分配到同一辆车上
- 每辆车对客户的服务次序是什么。
车辆路径问题建模
问题:设某配送中心有m辆车,需要对k个客户(节点)进行货物配送服务
- 每个客户的货物需求量是 d i ( i = 1 , 2 , … , k ) d_{i}(i=1,2,\dots,k) di(i=1,2,…,k);
- 每辆配送车的最大装载量是Q;
- c i j c_{ij} cij表示客户 i i i到客户 j j j的运输成本(时间、路程、花费等);
- 配送中心编号为0,客户编号为
i
(
i
=
1
,
2
,
…
,
k
)
i(i=1,2,\dots,k)
i(i=1,2,…,k)。
设下面两组0-1决策变量
x i j s = { 1 , 车 s 从 i 行驶到 j 0 , 否则 x_{ijs}=\left\{\begin{matrix} 1,\ 车s从i行驶到j \\ 0,\ 否则 \end{matrix}\right. xijs={1, 车s从i行驶到j0, 否则
y i s = { 1 , 客户 i 的货物由车 s 完成 0 , 否则 y_{is}=\left\{\begin{matrix} 1,\ 客户i的货物由车s完成 \\ 0,\ 否则 \end{matrix}\right. yis={1, 客户i的货物由车s完成0, 否则
由此建立如下的数学模型
目标函数
m i n Z = ∑ i = 0 k ∑ j = 0 k ∑ s = 0 k c i j x i j s min\ Z=\sum_{i=0}^{k}\sum_{j=0}^{k}\sum_{s=0}^{k}c_{ij}x_{ijs} min Z=i=0∑kj=0∑ks=0∑kcijxijs
约束条件 - 车辆的装载量不能超过最大装载量
s u n i = 0 k d i y i s ≤ Q , ( s = 1 , 2 , … , m ) sun_{i=0}^{k}d_{i}y_{is}\le Q,(s=1,2,\dots,m) suni=0kdiyis≤Q,(s=1,2,…,m) - 每个客户的配送任务仅由其中一辆车完成,所有任务由m辆车协同完成
s u n s = 0 m y i s = { 1 , i = 1 , 2 , … , k m , i = 0 sun_{s=0}^{m}y_{is}=\left\{\begin{matrix} 1,\ i=1,2,\dots,k \\ m,\ i=0 \end{matrix}\right. suns=0myis={1, i=1,2,…,km, i=0 - 到达某一客户的车辆有且仅有一辆,从某一客户离开的车辆有且仅有一辆
∑ i = 0 k x i j s ≤ y j s , ( j = 1 , 2 , … , k ; s = 1 , 2 , … , m ) \sum_{i=0}^{k}x_{ijs}\le y_{js},\ (j=1,2,\dots ,k;s=1,2,\dots,m) i=0∑kxijs≤yjs, (j=1,2,…,k;s=1,2,…,m)
∑ j = 0 k x i j s ≤ y i s , ( i = 1 , 2 , … , k ; s = 1 , 2 , … , m ) \sum_{j=0}^{k}x_{ijs}\le y_{is},\ (i=1,2,\dots ,k;s=1,2,\dots,m) j=0∑kxijs≤yis, (i=1,2,…,k;s=1,2,…,m)
显然,上面VRP问题的模型是一个经典的整数规划模型,或者称为0-1规划模型,我们可以借助Matlab中求解线性规划的函数,或用Lingo软件求解,
但是,当问题规模比较大时,上述工具不一定能有效求解,通常我们会利用智能优化算法如遗传算法来求解,或者通过构造合适的模型结构,通过列生成算法求解大规模整数规划问题
VRP(VehicleRoutingProblem,车辆路径问题)是运筹优化中一类普通又重要的问题,Google开源的运筹优化求解器Ortools针对这类问题有专门的调用接口,前面示例中的VRP问题就是车辆容量限制的CVRP问题;如果是时间窗约束,如寄快递会指定快递员上门取件的时间段,这就是时间窗口约束的 VRP问题,即VRPTW问题
在配货场景中,因仓库装卸能力有限,只能同时对两辆车进行装卸,那么其他车辆就需要等待前面的车装卸完成。
类似场景还有飞机场的飞机调度问题,由于飞机场的机位是有限的,如何安排飞机的起降时间和顺序就显得无为重要,这类问题就是资源约束的VRP问题,即VRPC问题。
这些常见的VRP问题,Ortools提供了现成的解决方案
利用求解器Ortools求解车辆容量限制的CVRP问题的实例
配送中心标号0,客户编号1-16,车辆数4,最大载重量15
客户需求1,1,2,4,2,4,8,8,1,2,1,2,4,4,8,8 配送中心与客户,客户之间的距离矩阵
结果
车辆0:
0累积装载(0)->1累积装载(1)->4累积装载(5)->3累积装载(7)->15累积装载(15)->0累积装载(15)
总行驶距离:2192m
总装载量:15
车辆1:
0累积装载(0)->14累积装载(4)->16累积装载(12)->10累积装载(14)->2累积装载(15)->0累积装载(15)
总行驶距离:2192m
总装载量:15
车辆2:
0累积装载(0)->7累积装载(8)->13累积装载(12)->12累积装载(14)->11累积装载(15)->0累积装载(15)
总行驶距离:1324m
总装载量:15
车辆3:
0累积装载(0)->9累积装载(1)->8累积装载(9)->6累积装载(13)->5累积装载(15)->0累积装载(15)
总行驶距离:1164m
总装载量:15