Minimum maliyet akış sorunu


9

Bir akış ağı , bir G = (V, E)kaynak tepe noktası s ϵ Vve bir lavabo tepe noktası bulunan yönlendirilmiş bir grafiktir ve grafikteki t ϵ Vher kenarın (u, v) ϵ E(bağlantı düğümleri u ϵ Vve v ϵ V) kendisiyle ilişkilendirilmiş 2 miktarı vardır:

  1. c(u, v) >= 0, kenar kapasitesi
  2. a(u, v) >= 0, bir birimi kenardan gönderme maliyeti

Bir işlevi 0 <= f(u, v) <= c(u, v), belirli bir kenardan geçirilen birim sayısı olarak tanımlarız (u, v). Dolayısıyla, belirli bir kenar maliyeti (u, v)olan a(u, v) * f(u, v). En düşük maliyetli akış problemi , belirli bir akış miktarı için her bir kenar üzerinden toplam maliyetini en aza indirmek olarak tanımlanır d, aşağıdaki miktar ile verilir:

maliyet

Sorun için aşağıdaki kısıtlamalar geçerlidir:

  1. Kapasite gereksinimleri : belirli bir kenardan geçen akış, o kenarın kapasitesini aşamaz ( f(u, v) <= c(u, v)).
  2. Eğri simetrisi : yön ters çevrildiğinde belirli bir kenardaki akış antisimetrik olmalıdır ( f(u, v) = -f(v, u)).
  3. Koruma Akış : olmayan emici olmayan kaynak düğüm, net akış 0 olmalıdır (her biri için u ∉ {s, t}, her üzerinden toplama w, sum f(u, w) = 0).
  4. Gerekli akış : kaynaktan çıkan net akış ve lavaboya giden net akış, hem ağ üzerinden gerekli akışa eşit olmalıdır (toplamı toplamak u, sum f(s, u) = sum f(u, t) = d).

Bir akış ağı Gve gerekli bir akış göz önüne alındığında d, düniteleri ağ üzerinden göndermek için minimum maliyeti girin . Bir çözümün var olduğunu varsayabilirsiniz. dve tüm kapasiteler ve maliyetler negatif olmayan tamsayılar olacaktır. NKöşeleri etiketli bir ağ [0, N-1]için kaynak tepe noktası 0ve lavabo tepe noktası olacaktır N-1.

Bu , böylece en kısa cevap (bayt cinsinden) kazanır. Bunun hem diller içinde hem de diller arasında bir rekabet olduğunu unutmayın, bu yüzden ayrıntılı bir dilde çözüm yayınlamaktan korkmayın.

Yerleşiklere izin verilir, ancak aynı cevapta ek bir çözüm olarak veya bağımsız bir cevap olarak yerleşiksiz çözümler eklemeniz önerilir.

Girdi, her bir kenarın ve talebin kapasitelerini ve maliyetlerini içeren herhangi bir makul şekilde olabilir.

Test Durumları

Test senaryoları aşağıdaki biçimde sağlanır:

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

Bu test senaryoları NetworkX Python kütüphanesi ile hesaplanmıştır .



1
Uzun bir süre Golf sonra okuyamıyorum çünkü yanlış algoritma golf olduğunu fark
Quintec

Yanıtlar:


3

[R + lpSolve ], 201 186 149 144 bayt

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

Çevrimiçi deneyin!

Kod aşağıdaki Doğrusal Sorunu oluşturur ve lpSolvepaketi kullanarak çözer :

mbennΣxV ΣyVbirx,yfx,ysubject tÖ:ΣxVfv,x-fx,v=0vV:v{s,t}ΣxVfs,x-fx,s=dΣxVft,x-fx,t=-dfx,bCx,bxV,yV
nerede :

  • V köşe kümesidir
  • s s kaynak köşe noktasıdır
  • t s, hedef (veya lavabo) tepe noktasıdır
  • birx,y için akış maliyeti x -> y
  • fx,yx -> yoptimal çözümdeki kenar akışıdır
  • d lavaboda gerekli akıştır (örn. t ve üretim s)
  • Cx,y maksimum kenar kapasitesi x -> y

Güzel, doğrusal programlama :) Ne yazık ki çoğu dilde bir lpSolve... :(
Quintec

Maalesef bu doğru ... BTW taban-R'de mevcut değil, bir paket ...
TIO'ya

Bazı nedenlerden dolayı MinCostMaxFlow'u MinCostFlow olacak şekilde değiştirmenin kısa bir yolunu bulmadım ... beynim kızartıldı lol, bunun matematiksel dışındaki dillerde bir işlevi olmasını diliyorum
Quintec

@Quintec: MinCostMaxFlow'un belirli bir uygulamasından (örneğin belirli bir dilde) bahsediyor musunuz?
digEmAll

Hayır, el kodlu algoritmam
Quintec

1

Wolfram Dili, 42 bayt

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

Önemsiz yerleşik. Yerleşik olmayan çözüm yakında.


6-8 hafta içinde mi geliyor? : P
Quintec

1

Python 3 + NetworkX , 137 bayt

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'da NetworkX kitaplığı yüklü olmadığı için TryItOnline bağlantısı yok

Grafik girişini, aşağıdaki gibi kapasite ve ağırlık özelliklerine sahip bir kenar listesi olarak alır:

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

Bu, test senaryolarını doğrulamak için kullandığım kodun golf edilmiş bir versiyonudur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.