最小成本流问题


9

流网络是一个有向图G = (V, E)具有源顶点s ϵ V和宿顶点t ϵ V,并且其中每一个边缘(u, v) ϵ E上的曲线图(连接节点u ϵ Vv ϵ V)具有与其相关联的2个量:

  1. c(u, v) >= 0,边缘的能力
  2. a(u, v) >= 0,通过边缘发送一个单位的成本

我们定义一个函数0 <= f(u, v) <= c(u, v)为通过给定边的单位数量(u, v)。因此,对于一个给定边缘的成本(u, v)a(u, v) * f(u, v)。的最小代价流问题被定义为在最小化对于给定的流量所有边缘的总成本d,由下面的量给出:

成本

以下约束适用于该问题:

  1. 容量要求:通过给定边的流量不得超过该边的容量(f(u, v) <= c(u, v))。
  2. 倾斜对称:当方向相反时,通过给定边缘的流动必须是反对称的f(u, v) = -f(v, u)
  3. 流保护:净流量到任何非汇聚非源节点必须为0(对于每个u ∉ {s, t},求和所有wsum f(u, w) = 0)。
  4. 需要的流量:净流量的源和净流入水槽通过网络必须都等于所需要的流量的输出(求和所有usum f(s, u) = sum f(u, t) = d)。

给定流网络G和所需流d,输出d通过网络发送单元的最低成本。您可以假定存在解决方案。d并且所有容量和费用均为非负整数。对于带有N[0, N-1]有的顶点的网络,源顶点将为0,宿顶点将为N-1

这是 ,因此最短的答案(以字节为单位)获胜。请记住,这是语言内部以及语言之间的竞争,因此不要害怕用冗长的语言发布解决方案。

允许使用内置插件,但建议您包括不包含内置插件的解决方案,作为相同答案中的其他解决方案或独立答案。

输入可以采用任何合理的方式,包括每个边的能力和成本以及需求。

测试用例

测试用例以以下格式提供:

c=<2D matrix of capacities> a=<2D matrix of costs> d=<demand> -> <solution>

c=[[0, 3, 2, 3, 2], [3, 0, 5, 3, 3], [2, 5, 0, 4, 5], [3, 3, 4, 0, 4], [2, 3, 5, 4, 0]] a=[[0, 1, 1, 2, 1], [1, 0, 1, 2, 3], [1, 1, 0, 2, 2], [2, 2, 2, 0, 3], [1, 3, 2, 3, 0]] d=7 -> 20
c=[[0, 1, 1, 5, 4], [1, 0, 2, 4, 2], [1, 2, 0, 1, 1], [5, 4, 1, 0, 3], [4, 2, 1, 3, 0]] a=[[0, 1, 1, 2, 2], [1, 0, 2, 4, 1], [1, 2, 0, 1, 1], [2, 4, 1, 0, 3], [2, 1, 1, 3, 0]] d=7 -> 17
c=[[0, 1, 4, 5, 4, 2, 3], [1, 0, 5, 4, 3, 3, 5], [4, 5, 0, 1, 5, 5, 5], [5, 4, 1, 0, 3, 2, 5], [4, 3, 5, 3, 0, 4, 4], [2, 3, 5, 2, 4, 0, 2], [3, 5, 5, 5, 4, 2, 0]] a=[[0, 1, 4, 2, 4, 1, 1], [1, 0, 3, 2, 2, 1, 1], [4, 3, 0, 1, 4, 5, 2], [2, 2, 1, 0, 2, 2, 3], [4, 2, 4, 2, 0, 4, 1], [1, 1, 5, 2, 4, 0, 2], [1, 1, 2, 3, 1, 2, 0]] d=10 -> 31
c=[[0, 16, 14, 10, 14, 11, 10, 4, 3, 16], [16, 0, 18, 19, 1, 6, 10, 19, 5, 4], [14, 18, 0, 2, 15, 9, 3, 14, 20, 13], [10, 19, 2, 0, 2, 10, 12, 17, 19, 22], [14, 1, 15, 2, 0, 11, 23, 25, 10, 19], [11, 6, 9, 10, 11, 0, 14, 16, 25, 4], [10, 10, 3, 12, 23, 14, 0, 11, 7, 8], [4, 19, 14, 17, 25, 16, 11, 0, 14, 5], [3, 5, 20, 19, 10, 25, 7, 14, 0, 22], [16, 4, 13, 22, 19, 4, 8, 5, 22, 0]] a=[[0, 12, 4, 2, 9, 1, 1, 3, 1, 6], [12, 0, 12, 16, 1, 2, 9, 13, 2, 3], [4, 12, 0, 2, 2, 2, 2, 10, 1, 1], [2, 16, 2, 0, 2, 1, 8, 4, 4, 2], [9, 1, 2, 2, 0, 5, 6, 23, 5, 8], [1, 2, 2, 1, 5, 0, 13, 12, 12, 1], [1, 9, 2, 8, 6, 13, 0, 9, 4, 4], [3, 13, 10, 4, 23, 12, 9, 0, 13, 1], [1, 2, 1, 4, 5, 12, 4, 13, 0, 13], [6, 3, 1, 2, 8, 1, 4, 1, 13, 0]] d=50 -> 213

这些测试用例是使用NetworkX Python库计算的。



1
打高尔夫很长一段时间,然后才意识到我打高尔夫的算法错误,因为我看不懂
Quintec

Answers:


3

[R + lpSolve ],201个 186 149 144字节

function(c,a,d,`^`=rep,N=ncol(c),G=diag(N),P=t(1^N),M=P%x%G+G%x%-P)lpSolve::lp(,a,rbind(M,diag(N*N)),c('=','<')^c(N,N*N),c(d,0^(N-2),-d,c))$objv

在线尝试!

该代码构造了以下线性问题,并使用lpSolvepackage 解决了该问题:

一世ñXV ÿV一个XÿFXÿsübĴËCŤ ŤØXVFvX-FXv=0vVv{sŤ}XVFsX-FXs=dXVFŤX-FXŤ=-dFXbCXbXVÿV
哪里:

  • V 是一组顶点
  • s s是源顶点
  • Ť s是目标(或宿)顶点
  • 一个Xÿ 边缘的流动成本 x -> y
  • FXÿx -> y最佳解决方案中的边流
  • d 是汇的所需流量(即需求 Ť 和生产在 s
  • CXÿ 是边缘的最大容量 x -> y

不错的线性编程:)不幸的是,大多数语言都没有lpSolve... :(
Quintec

不幸的是,这是真的...顺便说一句,它在base-R上不可用,它是一个软件包...我不得不要求在TIO上安装;)
digEmAll

出于某种原因,我还没有找到将MinCostMaxFlow修改为MinCostFlow的捷径...我的大脑被炸了,大声笑,我希望除mathematica
之外的

@Quintec:您指的是MinCostMaxFlow的特定实现(例如,某种语言)吗?
digEmAll

不,我的手编码算法
Quintec,

1

Wolfram语言,42个字节

FindMinimumCostFlow[#,1,VertexCount@#,#2]&

琐碎的内置功能。非内置解决方案即将推出。


在6-8周内到货吗?:P
Quintec,

1

Python 3 + NetworkX,137个字节

from networkx import*
def f(g,d,z='demand'):N=len(g)**.5//1;G=DiGraph(g);G.node[0][z]=-d;G.node[N-1][z]=d;return min_cost_flow_cost(G)

没有TryItOnline链接,因为TIO没有安装NetworkX库

将图形输入作为具有容量和权重属性的边列表,如下所示:

[(0, 0, {'capacity': 0, 'weight': 0}), (0, 1, {'capacity': 3, 'weight': 1}), (0, 2, {'capacity': 2, 'weight': 1}), (0, 3, {'capacity': 3, 'weight': 2}), (0, 4, {'capacity': 2, 'weight': 1}), (1, 0, {'capacity': 3, 'weight': 1}), (1, 1, {'capacity': 0, 'weight': 0}), (1, 2, {'capacity': 5, 'weight': 1}), (1, 3, {'capacity': 3, 'weight': 2}), (1, 4, {'capacity': 3, 'weight': 3}), (2, 0, {'capacity': 2, 'weight': 1}), (2, 1, {'capacity': 5, 'weight': 1}), (2, 2, {'capacity': 0, 'weight': 0}), (2, 3, {'capacity': 4, 'weight': 2}), (2, 4, {'capacity': 5, 'weight': 2}), (3, 0, {'capacity': 3, 'weight': 2}), (3, 1, {'capacity': 3, 'weight': 2}), (3, 2, {'capacity': 4, 'weight': 2}), (3, 3, {'capacity': 0, 'weight': 0}), (3, 4, {'capacity': 4, 'weight': 3}), (4, 0, {'capacity': 2, 'weight': 1}), (4, 1, {'capacity': 3, 'weight': 3}), (4, 2, {'capacity': 5, 'weight': 2}), (4, 3, {'capacity': 4, 'weight': 3}), (4, 4, {'capacity': 0, 'weight': 0})]

这是我用来验证测试用例的代码的简化版本。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.