最小コストのフロー問題


9

フローネットワークは有向グラフであるG = (V, E)ソース頂点とs ϵ Vシンク頂点t ϵ Vすべてのエッジ、および(u, v) ϵ E(ノードを接続グラフ上u ϵ Vとはv ϵ V)それに関連付けられた2つの量を有します。

  1. c(u, v) >= 0、エッジの容量
  2. a(u, v) >= 0、1つのユニットをエッジから送信するコスト

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

回答:


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 を使用してそれを解決します。

minxV yVAx,yfx,ysubject to:xVfv,xfx,v=0vV:v{s,t}xVfs,xfx,s=dxVft,xfx,t=dfx,bCx,bxV,yV

  • V
  • s
  • t
  • Ax,yx -> y
  • fx,yx -> y
  • dts
  • Cx,yx -> y

ニースは、線形計画:)残念ながら、ほとんどの言語ではありませんlpSolve... :(
Quintec

それは残念ながら本当です... BTWそれはbase-Rでは利用できません、それはパッケージです...私はTIOにインストールするように頼まなければなりませんでした;)
digEmAll

何らかの理由で、MinCostMaxFlowをMinCostFlowに変更する簡単な方法をまだ見つけていません...私の脳は笑っています、mathematica以外の言語でこれのための関数があったらいいのですが
Quintec

@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)

TIOにはNetworkXライブラリがインストールされていないため、TryItOnlineリンクはありません

次のように、容量と重みの属性を持つエッジリストとしてグラフ入力を取得します。

[(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})]

これは、テストケースの検証に使用したコードのゴルフバージョンです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.