网络流问题
在数学规划中,网络流问题是指一类基于网络模型的流量分配问题。网络流问题的目标是在网络中分配资源,使得网络的流量满足一定的限制条件,并且使得某些目标函数最小或最大化。网络流问题通常涉及一个有向图,图中每个节点表示一个资源,每条边表示资源之间的关系。边上有一个容量值,表示该边上最多可以流动的资源数量。流量从源节点开始流出,经过一系列中间节点,最终到达汇节点。在这个过程中,需要遵守一定的流量守恒和容量限制条件。
具体而言,网络流问题可以分为最大流和最小割两类。最大流问题是寻找在网络中从源节点到汇节点的最大流量,而最小割问题是寻找一组割,将网络划分为两个部分,并且通过这些割的容量之和最小化。如在有向图中分配流量,使每条边的流量不会超过它的容量约束,同时达到路径长度最小或者花费最小等目标函数的优化问题。
网络流问题在实际应用中非常广泛,如货物运输、通信网络、电力网络等:
- 物流:求解仓网规划问题。
- 制造:求解工厂的排班排产问题。
- 交通:求解车辆和货物的匹配问题。
- 通信:求解网络设施的规划, 通信管道的调优问题。
- 能源:求解石油、天然气、电力的最优配送问题。
接下来我们通过两个案例讲解业务场景中遇到的网络流问题,如何运用数学规划的方法建模、采用 MindOpt APL来建模和调用求解器求解它们。
本篇是第一个案例:交通调度_最大化通行量
1. 交通问题规划
已知有七个站点,每个站点都有若干条进站道路与出站道路,道路旁的数字表示单位时间内此路所能承载的最大车辆数,问如何分配车辆使得单位时间从站点出发,最后到达站点的车辆最多?
2. 数学规划模型
以上问题的数学模型如下。
集合
- 站点集合
- 中间站点集合
- 路线集合 ,是站点可连接的集合
参数
- 起点
- 道路 最少能通过的车辆数
- 道路 最多能通过的车辆数
变量
单位时间,道路 通过的车辆数
目标函数
最大化从起点站出发的车的数量,即经过该点的道路的车辆数之和:
约束
进入中间站点 车的数量等于该站点出去车的数量
这里我们汇总的数学模型为:
3. MindOpt APL 建模和求解
MindOpt APL是一款代数建模语言,它可以方便地将数学语言描述成程序,然后调用多种求解器求解。MindOpt Solver对网络流的线性规划求解效率很不错,且能支持大规模的问题。
改写上面的数据图和数学模型,如下代码,在Notebook的cell中运行它:
clear model; # 建模 # net1.mapl set Station :={"a","b","c","d","e","f","g"}; set Middle := {"b","c","d","e","f"}; set Roads :={<"a","b">,<"b","d">,<"c","d">,<"d","e">,<"e","g">,<"a","c">,<"b","e">,<"c","f">,<"d","f">,<"f","g">}; param entr := "a"; param lb := 0; param ub[Roads] := <"a","b"> 50, <"b","d"> 40, <"c","d"> 60, <"d","e"> 50, <"e","g"> 70, <"a","c"> 100, <"b","e"> 20, <"c","f"> 20, <"d","f"> 60, <"f","g"> 70; var x[<i,j> in Roads] >= lb <= ub[i,j]; maximize Total : sum {<entr,j> in Roads } x[entr,j]; #起点进入的最大流量 #流量均衡 subto Balance: forall <k> in Middle do sum {<i,k> in Roads} x[i,k] == sum {<k,j> in Roads } x[k,j]; print "-----------------用MindOpt求解---------------"; option solver mindopt; # (可选)指定求解用的求解器,默认是MindOpt #option mindopt_options 'print=0'; #设置求解器输出级别,减少过程打印 solve; # 求解 print "-----------------Display---------------"; display; # 展示结果 print "经过优化后,最大流量=" ,sum {<entr,j> in Roads } x[entr,j];
运行结果如下:
-----------------用MindOpt求解--------------- Running mindoptampl wantsol=1 mip_integer_tolerance=1e-9 MindOpt Version 0.24.1 (Build date: 20230423) Copyright (c) 2020-2023 Alibaba Cloud. Start license validation (current time : 29-JUN-2023 21:31:04). License validation terminated. Time : 0.006s Only one thread allowed -- optimize with Simplex method. Model summary. - Num. variables : 10 - Num. constraints : 5 - Num. nonzeros : 16 - Bound range : [2.0e+01,1.0e+02] - Objective range : [1.0e+00,1.0e+00] - Matrix range : [1.0e+00,1.0e+00] Presolver started. Presolver terminated. Time : 0.000s Simplex method started. Model fingerprint: ==gZ3B2didHZ Iteration Objective Dual Inf. Primal Inf. Time 0 1.30000e+02 0.0000e+00 4.0000e+00 0.01s 2 1.30000e+02 0.0000e+00 0.0000e+00 0.01s Postsolver started. Simplex method terminated. Time : 0.001s OPTIMAL; objective 130.00 2 simplex iterations Completed. -----------------Display--------------- Primal Solution: x@<a,b> = 50.0000 x@<a,c> = 80.0000 x@<b,d> = 30.0000 x@<b,e> = 20.0000 x@<c,d> = 60.0000 x@<c,f> = 20.0000 x@<d,e> = 50.0000 x@<d,f> = 40.0000 x@<e,g> = 70.0000 x@<f,g> = 60.0000 经过优化后,最大流量=130
4. 结果
运行上述代码后,得到结果为:
Primal Solution: x@<a,b> = 50.0000 x@<a,c> = 80.0000 x@<b,d> = 30.0000 x@<b,e> = 20.0000 x@<c,d> = 60.0000 x@<c,f> = 20.0000 x@<d,e> = 50.0000 x@<d,f> = 40.0000 x@<e,g> = 70.0000 x@<f,g> = 60.0000 最大流量=130
即,从站最多可出发130辆车。并且分流的流量为,如下图
- a到b是50,到c是80;
- b到d是30,到e是20
- c到d是60,到f是20
- d汇总了90的流量,分流到e是50,到f是40
- e汇总了70的流量
- f汇总了60的流量
-它们都汇总到出口g,总共是130