Problema di flusso a costo minimo


9

Una rete di flusso è un grafico diretto G = (V, E)con un vertice di origine s ϵ Ve un vertice di sink t ϵ Ve in cui ogni bordo (u, v) ϵ Edel grafico (che collega i nodi u ϵ Ve v ϵ V) ha 2 quantità associate ad esso:

  1. c(u, v) >= 0, la capacità del bordo
  2. a(u, v) >= 0, il costo dell'invio di un'unità attraverso il bordo

Definiamo una funzione 0 <= f(u, v) <= c(u, v)come il numero di unità che passano attraverso un determinato fronte (u, v). Pertanto, il costo per un determinato vantaggio (u, v)è a(u, v) * f(u, v). Il problema del flusso di costo minimo è definito come la riduzione al minimo del costo totale su tutti i bordi per un determinato importo di flusso d, dato dalla seguente quantità:

costo

I seguenti vincoli si applicano al problema:

  1. Requisiti di capacità : il flusso attraverso un determinato bordo non può superare la capacità di quel bordo ( f(u, v) <= c(u, v)).
  2. Simmetria obliqua : il flusso attraverso un determinato bordo deve essere antisimmetrico quando la direzione è invertita ( f(u, v) = -f(v, u)).
  3. Conservazione del flusso : il flusso netto in qualsiasi nodo non-source non-sink deve essere 0 (per ciascuno u ∉ {s, t}, sommando tutto w, sum f(u, w) = 0).
  4. Flusso richiesto : il flusso netto fuori dalla sorgente e il flusso netto nel lavandino devono entrambi uguagliare il flusso richiesto attraverso la rete (sommando tutto u, sum f(s, u) = sum f(u, t) = d).

Data una rete di flusso Ge un flusso richiesto d, genera il costo minimo per l'invio di dunità attraverso la rete. Si può presumere che esista una soluzione. de tutte le capacità e i costi saranno numeri interi non negativi. Per una rete con Nvertici etichettati con [0, N-1], il vertice di origine sarà 0e il vertice di sink sarà N-1.

Questo è , quindi vince la risposta più breve (in byte). Ricorda che si tratta di una competizione all'interno delle lingue e tra le lingue, quindi non aver paura di pubblicare una soluzione in una lingua dettagliata.

Gli incorporati sono consentiti, ma si consiglia di includere soluzioni senza incorporati, sia come soluzione aggiuntiva nella stessa risposta, sia come risposta indipendente.

L'input può essere in qualsiasi modo ragionevole che includa le capacità e i costi di ciascun vantaggio e la domanda.

Casi test

I casi di test sono forniti nel seguente formato:

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

Questi casi di test sono stati calcolati con la libreria NetworkX Python .



1
Il golf da molto tempo ha poi capito che stavo giocando a golf con l'algoritmo sbagliato perché non so leggere
Quintec,

Risposte:


3

[R + lpSolve ], 201 186 149 144 byte

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

Provalo online!

Il codice crea il seguente problema lineare e risolverlo usando il lpSolvepacchetto:

mionΣXV ΣyVUNX,yfX,ySuBject to:ΣXVfv,X-fX,v=0vV:v{S,t}ΣXVfS,X-fX,S=dΣXVft,X-fX,t=-dfX,BCX,BXV,yV
dove:

  • V è l'insieme dei vertici
  • S s è il vertice di origine
  • t s è il vertice target (o sink)
  • UNX,y è il costo del flusso per il frontex -> y
  • fX,y è il flusso del bordo x -> ynella soluzione ottimale
  • d è la portata richiesta al dispersore (cioè la domanda di e la produzione in )tS
  • CX,y è la capacità massima del bordox -> y

Programmazione lineare e piacevole :) Purtroppo la maggior parte delle lingue non ha lpSolve... :(
Quintec,

Questo è purtroppo vero ... BTW non è disponibile su base-R, è un pacchetto ... Ho dovuto chiedere di installare su TIO;)
digEmAll

Per qualche motivo devo ancora trovare un modo breve di modificare MinCostMaxFlow per diventare MinCostFlow ... il mio cervello è fritto lol, vorrei che ci fosse una funzione per questo in lingue diverse dalla matematica
Quintec,

@Quintec: ti riferisci a un'implementazione specifica (ad esempio in una determinata lingua) di MinCostMaxFlow?
digEmAll

No, il mio algoritmo codificato a mano
Quintec,

1

Wolfram Language, 42 byte

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

Trivial builtin. Soluzione non integrata in arrivo.


Arriverà tra 6-8 settimane? : P
Quintec,

1

Python 3 + NetworkX , 137 byte

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)

Nessun collegamento TryItOnline perché TIO non ha installato la libreria NetworkX

Prende l'input grafico come un elenco di bordi con attributi di capacità e peso, in questo modo:

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

Questa è una versione golfizzata del codice che ho usato per verificare i casi di test.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.