Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pa:laboratoare:laborator-11 [2018/05/17 17:03]
stefania.budulan [Implementarea Edmonds-Karp]
pa:laboratoare:laborator-11 [2023/03/15 16:58] (current)
radu.nichita
Line 1: Line 1:
-====== Laborator 11 Flux Maxim ======+====== Laborator 11Flux maxim în rețele de transport ​====== 
 + 
 + 
 +{{:​pa:​new_pa:​partners:​bitdefender-logo.png?​190 |}} Bitdefender provides cybersecurity solutions with leading security efficacy, performance and ease of use to small and medium businesses, mid-market enterprises and consumers. Guided by a vision to be the world’s most trusted cybersecurity solutions provider, Bitdefender is committed to defending organizations and individuals around the globe against cyberattacks to transform and improve their digital experience.
  
 ===== Obiective laborator ===== ===== Obiective laborator =====
  
-  ​*formalizarea noțiunilor de rețea de transport și flux în rețea +În acest laborator vom introduce contextul pentru ​**maximum flow problem** și vom studia algoritmi care pot rezolva această problemă.
-  ​*prezentarea unei metode de rezolvare a problemei de flux maxim +
-  ​*analiza unei implementări a metodei oferite+
  
-===== Importanţă – aplicaţii practice =====+  * Prezentarea noțiunii de rețea de transport și a termenilor asociați. 
 +  * Prezentarea problemei (diverse variante). 
 +  * Prezentarea algoritmilor pentru calcul unui flux maxim într-o rețea de transport.
  
-Un graf orientat poate fi utilizat pentru modelarea unui proces de transport într-o rețea între un producător //s// și un consumator //t//. Destinația nu poate consuma mai mult decât se produce, iar cantitatea trimisă pe o cale nu poate depăși capacitatea sa de transport.+===== Maximum flow problem =====
  
-Rețelele de transport pot modela curgerea lichidului în sisteme ​cu țevideplasarea pieselor pe benzi rulante, deplasarea curentului prin rețele electrice, transmiterea informațiilor prin rețele de comunicare etc.+Vă rugăm să parcugeți [[https://​ocw.cs.pub.ro/​courses/​pa/​laboratoare/​maximum-flow-problem|Maximum flow problem]] pentru a vă familiariza ​cu contextulproblema și notațiile folosite.
  
-===== Descrierea problemei şi a rezolvărilor =====+Concepte necesare:
  
-O problemă des întâlnită într-o ​rețea de transport ​este cea a găsirii fluxului ​maxim posibil prin arcele ​rețelei astfel încât:+  * **rețea de transport** / **flow network** 
 +  * **flux** / **flow** 
 +  * **flux ​maxim** / **maximum flow** 
 +  * **capacitate reziduală** / **residual capacity** 
 +  * **rețea reziduală** / **residual network** 
 +  * **drum de ameliorare** / **augmenting path** 
 +  * **capacitate reziduală a unui drum de ameliorare** / **residual capacity of augmenting path**
  
-1. să nu fie depășite capacitățile arcelor+===== Algoritmi =====
  
-2. fluxul să se conserve în drumul său de la //s// la //t//+Pentru **maximum flow problem** există mai mulți algoritmi, dintre care amintim:
  
-**Definiție 1**+  ​* **Ford–Fulkerson**:​ Este o metodă (nu un algorithm concret), a cărui complexitate este direct proporțională cu valoarea fluxului maxim - $O(m * f_{max})$. [1
 +  ​* **Edmonds-Karp**:​ Este o implementare concretă / optimizare a metodei anterioare - $O(n * m^2)$. [2] 
 +  * **Dinic**: O optimizare bazată pe construirea progresivă a unui graf folosind BFS. În fiecare etapă se poate afla fluxul în $O(n * m)$, iar în total sunt $n -1$ etape. Complexitate finală $O(n^2 * m)$. [3] 
 +  * **Preflow-push / push-relabel**:​ Un algoritm care poate fi optimizat pentru a obține complexitate $O(n^3)$ sau $O(n^2 * m)$.
  
-O rețea de transport este un graf orientat ''​G = (V,​E)''​ cu proprietățile:​+Puteți consulta capitolul **Maximum Flow** din **Introduction to Algorithms** [0] pentru mai multe detalii despre acești algoritmi.
  
-1. există două noduri speciale în ''​V'':​ //s// este nodul sursă (sau producătorul) ​și //t// este nodul terminal (sau consumatorul).+În acest laborator vom studia ​și analiza **metoda Ford-Fulkerson**,​ apoi vom implementa **algoritmul Edmonds-Karp** (care este o optimizare peste Ford-Fulkerson).
  
-2. este definită o funcție totală de capacitate ''​c:​ V×V → R+''​ astfel încât:+===== Ford-Fulkerson =====
  
-  ​''​c (u,v) = 0''​ dacă ''​(u,​v) ∉ E''​ +Algoritmul lui [[https://​en.wikipedia.org/​wiki/​L._R._Ford_Jr.|Lester Randolph ​**Ford** Jr. ]] și [[https://​en.wikipedia.org/​wiki/​D._R._Fulkerson|Delbert Ray **Fulkerson**]]cunoscut ca și algoritmul / metoda [[https://​en.wikipedia.org/​wiki/​Ford%E2%80%93Fulkerson_algorithm|Ford-Fulkerson]] este un algoritm **greedy** pentru calcularea fluxului maxim într-o rețea de transport.
-  ​''​c (u,v) ≥ 0''​ daca ''​(u,​v) ∈ E''​+
  
-3. pentru orice nod ''​v ∈ V \ {s,​t}'' ​există ​cel puțin o cale ''​s ---> v ---> t''​.+Atât timp cât în graf încă ​există ​drumuri de ameliorare (augmenting paths), înseamnă că mai putem adauga flux in rețea prin acele drumuri. La fiecare pas alegem un drum de ameliorare, prin care adăugăm cantitatea maximă posibilă de flux.
  
-**Definiție 2**+<spoiler Ford-Fulkerson - Pseudocod>​
  
-Numim flux în rețeaua ''G = (V,)''​ o funcție totală ''​fV×V → R''​ cu proprietățile:+<code cpp> 
 +// apply Ford-Fulkerson's algorithm for computing maximum flow in network ​G 
 +// 
 +// nodes     list of all nodes from G 
 +// edges     = the list of all edges in G 
 +//             ​example:​ edge (nodeneigh, capacity) 
 +// S         = source in network G 
 +// T         = sink in network G 
 +// 
 +// returnsmaxFlow (maximum flow in G from S to T) 
 +// 
 +Ford-Fulkerson(G=(nodes,​ edges), S, T) { 
 +  // STEP 0initialize 
 +  // * flow in network 
 +  foreach ((u, v) in edges) { 
 +      f[u][v] = 0; 
 +  } 
 +  // * maximum total flow 
 +  totalFlow = 0;
  
-1. Restricție de capacitate: +  while (exists augmenting path p in G) { 
-  ​* ''​f(u,​v) ≤ c(u,v), ∀(u,v) ∈ V''​ - fluxul printr-un arc nu poate depăși capacitatea acestuia+      augment flow f along p; 
 +      update totalFlow; 
 +  ​}
  
-2. Antisimetrie:​ +  return totalFlow; 
-  * ''​f(u,​v) = -f(v,u) , ∀u ∈ V, ∀v ∈ V''​+}
  
-3. Conservarea fluxului+// Usage example
-  * ''​Σ f(u,v= 0∀u ∈ V ∖ {s,t}v ∈ V''​+maxFlow = Ford-Fulkerson(G=(nodesedges), ST); 
 +// Use maxFlow. 
 +</​code>​ 
 +După cum se observămetoda Ford-Fulkerson descrie care este abordarea generală, însă nu ne spune concret cum să găsim drumurile de ameliorare și cum să creștem fluxul pe ele.
  
-Un flux negativ de la u la v este unul virtual, el nu reprezintă un transport efectiv, ci doar sugerează că există un transport fizic de la v la u (este o convenție asemănătoare cu cea făcută pentru intensitățile curenților într-o rețea electrică). Ultima proprietate ne spune că la trecerea printr-un nod fluxul se conservă: suma fluxurilor ce intră într-un nod este 0 (ținând cont de convenția de semn stabilită). +Putem să alegem drumurile ​la întâmplare. Vom obține un rezultat corect ​(nu vom demonstra).
  
-Numim **capacitate reziduală** a unui arc+Din punct de vedere al performanței,​ în cel mai rău caz, pornind o parcurgere oarecare vom găsi în $O(n + m)$ un drum de ameliorare pe care vom putea crește cu exact o unitate cantitatea de flux. Această abordare duce la o complexitate de $O((n + m) |f_{max}|)$ - adică un timp de execuție proporțional cu cantitea de flux pompată. Abordarea este ineficientă.
  
-''​c<​sub>​f</sub(u,v) = c(u,v) - f(u,​v)''​+</spoiler\\
  
-și o interpretăm ca fiind cantitatea de flux adițional care poate fi transportat de la //u// la //v//, fără a 
-depăși capacitatea ''​c(u,​v)''​. 
  
-Exemplu:+În practică **NU** vom folosi direct metoda Ford-Fulkerson,​ ci **vom folosi algoritmul Edmonds-Karp**,​ pe care îl vom analiza în secțiunea următoare.
  
-{{ :​pa:​laboratoare:​101.png?​350 |}} +===== Edmonds-Karp =====
-  +
-Daca avem arcul ''​(u,​v) ∈ V''​ cu ''​c(u,​v) ​15''​ și ''​f(u,​v) ​10'',​ se pot transporta ''​c<​sub>​f</​sub>​(u,​v) ​5''​ unități suplimentare fără a încălca restricția de capacitate. Dar, conform definiției,​ deși arcul ''​(v,​u) ∉ V''​ vom avea totuși o capacitate reziduală ''​c<​sub>​f</​sub>​(v,​u) ​c(v,u) – f(v,​u) ​0 − (−10) ​10'':​ as putea transporta ''​10''​ unități în sens opus care să le anuleze pe cele 10 ale fluxului direct pe muchia ''​(u,​v)''​.+
  
-**Definiție 3**+Algoritmul lui [[https://​en.wikipedia.org/​wiki/​Jack_Edmonds|Jack ​**Edmonds**]] și [[https://​en.wikipedia.org/​wiki/​Richard_M._Karp|Richard M. **Karp**]], cunoscut ca și algoritmul [[https://​en.wikipedia.org/​wiki/​Edmonds%E2%80%93Karp_algorithm|Edmonds-Karp]] reprezintă o implementare concretă a metodei Ford-Fulkerson. Acest algoritm rezolvă problema drumurilor de ameliorare folosind **BFS** - adică drumul cel mai scurt (ca și număr de arce), pe care se poate merge ținând cont de restricția de capacitate ($f(u, v) \lt c(u, v)$).
  
-Fie o rețea de flux ''​G ​(V,​E)'',​ iar //f// fluxul prin ''​G''​. Numim rețea reziduală a lui ''​G'',​ indusă de //f//, o rețea de flux notată cu ''​G<​sub>​f</​sub> ​(V, E<​sub>​f</​sub>​)'',​ astfel încât+==== Edmonds-Karp - pseudocod ====
  
-  * ''​E<sub>f</sub> ​= {(u,v∈ V ∣ c<​sub>​f</sub>(u,v) = c(u,v− f(u,v) 0}''​+<code cpp> 
 +// apply Edmonds-Karp'​s algorithm for computing maximum flow in network G 
 +// 
 +// nodes     = list of all nodes from G 
 +// adj[node] = the adjacency list of node 
 +//             ​example:​ adj[node] ​= {..., neigh, ...} => edge (nodeneigh) 
 +// S         = source in network G 
 +// T         = sink in network G 
 +//         = flow in network G 
 +// c         = capacity in network G 
 +// 
 +// returns: maxFlow ​(maximum flow in G from S to T) 
 +// 
 +Edmonds-Karp(G=(nodesadj), S, T) { 
 +  // STEP 0: initialize 
 +  // * flow in network 
 +  foreach ​(u in nodes) { 
 +      foreach(in nodes
 +          f[u][v] = 0
 +      ​} 
 +  } 
 +  // * maximum total flow 
 +  totalFlow = 0;
  
-Este important de observat că ''​E<​sub>​f<​/sub>''​ și ''​E''​ pot fi disjuncteun arc rezidual ''​(u,v)''​ apare în rețeaua reziduală doar dacă capacitatea sa este strict pozitivă ​(ceea ce nu implică existența arcului în rețeaua originală).+  ​// STEP 1Start BFS for finding augmenting path(s). 
 +  while (BFS finds at least one augmenting path in G) { 
 +    // STEP 2.1: Compute residual capacity of augmenting path. 
 +    rc = +oo; // residual capacity 
 +    foreach ((u, v) in path) { 
 +        rc = min(rc, c[ u ][ v ] - f[ u ][ v ])
 +    }
  
-Un drum de ameliorare este o cale ''​(u1,​ u2, ..., uk)'',​ unde ''​u1 = s''​ și ''​uk = t'',​ în graful rezidual cu ''​c<​sub>​f</sub>(uiui+1> 0, ∀i=1,2,…,​k−1''​. Practic, un drum de ameliorare va reprezenta o cale în graf prin care se mai poate pompa flux adițional de la sursa la destinație.+    // STEP 2.2: Update flow on path with rc. 
 +    foreach ((uvin path) { 
 +        ​f[ u ][ v ] += rc;      ​// Increase on edge (uv)
 +        f[ v ][ u ] -rc;      // Decrease on edge (vu). 
 +    }
  
-Așa cum era de intuit, capacitatea reziduală a unui drum de ameliorare p este cantitatea maximă de flux ce se poate transporta de-a lungul lui:+    // STEP 2.3Update total flow. 
 +    totalFlow += rc; 
 +  }
  
-  ​* ''​c<​sub>​f</​sub>​(p) = min{c<​sub>​f</​sub>​(u,​v) ∣ (u,v) ∈ p}''​+  ​return totalFlow;​ 
 +}
  
-Acum că am introdus noțiunile necesare pentru formalizarea problemei de flux maxim într-un grafputem să prezentăși cea mai utilizată metodă de rezolvare.+// Usage example: 
 +maxFlow = Edmonds-Karp(G=(nodes,​ adj), S, T); 
 +// Use maxFlow. 
 +</​code>​ 
 +Algoritmul Edmons-Karp pornește o parcurgere BFS la fiecare pas. Pentru ​un drum de ameliorare găsitcalculează capacitatea reziduală a acestuia, apoi crește corespunzător fluxul pe acesta.
  
-==== Algoritmul Ford-Fulkerson ====+La **fiecare** pas, atunci când se crește fluxul pe un arc, se scade fluxul pe arcul invers (vom demonstra într-o subsecțiune viitoare necesitatea acestui pas pentru corectitudinea algoritmului).
  
-Aceasta este o metodă iterativă de găsire a fluxului maxim într-un graf care pleacă de la ideea: cât timp mai există ​un drum de ameliorare ​(o cale de la sursă la destinație) pot pompa pe această cale un flux suplimentar egal cu capacitatea reziduală a căii.+Algoritmul se oprește când nu mai există ​drumuri ​de ameliorare. Fluxul pompat până atunci în rețea este maxim.
  
-Acest algoritm reprezintă mai mult un șablon de rezolvare pentru că nu detaliază modul în care se alege drumul de ameliorare din rețeaua reziduală.+==== Exemple ====
  
-<code cpp> +=== Edmonds-Karp: exemplu rezultat ===
-Ford_Fulkerson +
-    Input G(V,E), s, t +
-    Output |fmax| +
-    |fmax| ← 0 +
-    f{u,v) ← 0, ∀(u,v) ∈ V×V +
-    while ∃a path p(s ---> t) in Gf such that cf(u,v) > 0, ∀(u,v) ∈ p +
-        find cf(p) min{cf(u,v) | cf(u,v) ∈ p} +
-        |fmax| +cf(p) +
-        for-each (u,v) ∈ p +
-            f(u,v) ← f(u,v) + cf(p) +
-            f(v,u) ← −f(u,v) +
-    return |fmax| +
-</​code>​+
  
-Complexitatea va fi ''​O(E * f max)''​ pentru că în ciclul while putem găsi, în cel mai rău caz, doar cai care duc la creșterea fluxului cu doar o unitate la fiecare pas.+{{https://​ocw.cs.pub.ro/​courses/​_media/​pa/​new_pa/​lab12-edmonds-karp-example.png?​512| Exemplu Edmonds-Karp}}
  
-Ne punem acum problema dacă acest algoritm ​este corect, dacă la final vom avea cu adevărat fluxul maxim posibil prin graf. Corectitudinea algoritmului derivă imediat din teorema ​**Flux maxim - tăietura minimă**.+Fluxul maxim calculat cu Edmonds-Karp pentru rețeaua atașată este**2**.
  
-Numim o **tăietură a unui graf** o partiție ''​(S,​T)''​ a nodurilor sale cu proprietatea ''​s ∈ S''​ si ''​t ∈ T''​. ​+Drumurile de ameliorare folosite sunt:
  
-**Teorema flux maxim – tăietura minimă: ​**+  ​$1 - 2 - 4 - 6$ (capacitate reziduală ​**+1**) 
 +  * $1 - 3 - 5 - 6$ (capacitate reziduală **+1**)
  
-Pentru o rețea de flux ''​G(V,​E)''​ următoarele afirmații sunt echivalente:+=== Exemplu Edmonds-Karpexemplu simplu pas cu pas ===
  
-1. ''​f'' ​este fluxul maxim în ''​G''​+În această secțiune vom exemplifica de ce doar simpla incrementare a fluxului pe arcele directe nu este suficientă pentru a găsi fluxul maxim în rețea. Următoarea secțiunea conține soluția.
  
-2. Rețeaua reziduală ''​G<sub>f</​sub>''​ nu conține drumuri de ameliorare+<spoiler Exemplu>
  
-3. Există o tăietură ''​(S,​T)''​ a lui ''​G''​ astfel încât fluxul net prin tăietură este egal cu capacitatea acelei tăieturi.+Pornim de la rețeaua din figura următoare:
  
-**Obs:** Prin orice tăietură fluxul este egal cu cel maxim pentru că nu există o altă cale pe care ar putea ajunge flux de la sursă la destinație și care să nu treacă prin tăietură (ar încălca tocmai definiția ei); sau, altfel spus, valoarea unui flux într-o rețea este dată de fluxul oricărei tăieturiAstfel, fluxul total va fi mărginit de cea mai mică capacitate a unei tăieturiDacă este îndeplinit punctul 3al teoremei atunci știm că acea tăietură nu poate fi decât una de capacitate minimă. Ultima incercare de a gasi o cale de la sursa la drena va rezulta in gasirea doar a elementelor marginite de o astfel de taietura.+{{https://ocw.cs.pub.ro/​courses/​_media/​pa/​new_pa/​lab12-edmonds-karp-example.png?512| Exemplu Edmonds-Karp}}
  
-Exemplu:+  * ''​%%n = 6%%'',​ ''​%%m = 7%%''​ 
 +  * Sursa este ''​%%S = 1%%'',​ iar terminalul este ''​%%T = 6%%''​. 
 +  * Funcția de capacitate ''​%%c%%''​ are valorile din figură.
  
-Rețeaua inițială: +Dacă rulăm Edmonds-Karp,​ o posibilă succesiune de stări pentru rețea este cea din figura următoare:
-{{ :​pa:​laboratoare:​102.png?​350 |}}+
  
-Rețeaua reziduală:​ +{{https://​ocw.cs.pub.ro/​courses/​_media/​pa/​new_pa/​lab12-edmonds-karp-basic-example-01.png?512Exemplu Edmonds-Karp}}
-{{ :pa:​laboratoare:​103.png?350 |}}  +
  
-Observăm că deși muchia ''​(d,​c)''​ are capacitate 0 în rețeaua originală (ea nu ar putea transporta ​flux) în rețeaua reziduală ​avem ''​c(d,​c) = 1''​ ceea ce îi permite să facă parte din drumul de ameliorare ''​p1 = (s, a, b, d, c, t)''​ de capacitate ''​c<​sub>​f</​sub>​(p1) = 1'',​ astfel ​că adăugarea acestui flux suplimentar pe muchia ''​(d,​c)'' ​nu va duce la încălcarea restricției de capacitate; sau am fi putut alege drumul ''​p2=(s,​ a, c, t)''​ cu ''​c<​sub>​f</​sub>​(p2) = 1''​ sau ''​p3 = (s,​a,​b,​d,​t)''​ cu ''​c<​sub>​f</​sub>​(p3) = 1''​. +  * Inițial fluxul în rețea este zero. 
-Performanța algoritmului ține de modul în care va fi ales drumul de ameliorare, ​se poate întâmpla ca pentru ''​|fmax|'' ​de valoarea mare o alegere nepotrivită să ducă la timpi de execuție foarte mari+  * Se vor găsi 2 drumuri ​de ameliorare $1 - 2 - 4 - 6$ și $ 1 - 3 - 5 - 6$. Pe fiecare drum se pompează câte o unitate de flux
 +  * În rețeaua reziduală ​obținută se observă că nu se mai poate ajunge ​de la S la T. 
 +  * Prin urmare fluxul obținut este maxim și are valoare $1 + 1 = 2$.
  
-==== Implementarea Edmonds-Karp ==== 
  
-Așa cum am văzut, algoritmul Ford-Fulkerson nu definește o metodă de alegere a drumului de ameliorare pe baza căruia se modifică fluxul în graf. Implementarea Edmonds-Karp alege întotdeauna cea mai scurtă cale folosind o căutare în lățime în graful rezidual unde fiecare arc are ponderea 1. Se poate demonstra că lungimea căilor găsite astfel crește monoton cu fiecare nouă ameliorare.+<note warning>
  
-<code cpp> +NU avem control asupra drumurilor găsite de BFS, adică ordinea în care acestea vor fi aleseci știm doar că se va alege cele mai scurte drumuri.
-Edmonds-Karp +
-    Input G(V,E), s, t +
-    Output |fmax| +
-    |fmax| ← 0 +
-    f(u,v) ← 0, ∀(u,v) ∈ V×V +
-    while true +
-        p(s ⇢ t) ← BFS(Gf,s,t) +
-        if not ∃p(s ⇢ t) +
-            break; +
-        find cf(p) = min{cf(u,v) ∣ cf(u,v) ∈ p} +
-        |fmax| += cf(p) +
-        for-each (u,v) ∈ p +
-            f(u,v) ← f(u,v) + cf(p) +
-            f(v,u) ← −f(u,v) +
-    return |fmax| +
-</​code>​+
  
-Plecând de la ideea că drumurile de ameliorare găsite au lungimi din ce în ce mai mari se poate arăta că în această implementare fluxul se mărește de cel mult ''​O(V*E)''​ ori ([1], pag.513). ​+</​note>​
  
-Complexitatea algoritmului va fi ''​O(V*E<​sup>​2</​sup>​)''​. Să luăm un exemplu ​de rulare al acestui algoritm. Vom considera starea ​rețelei după ce a fost sita prima cale de pompare flux(inițial toate arcele sunt etichetate cu 0/0 conform notației stabilite):​ +altă succesiune posibilă și corectă de stări pentru ​rețea se sește în figura următoare:
-  +
-{{ :​pa:​laboratoare:104.png?500 |}}+
  
-**Obs:** In cazul ultimului drum de ameliorare găsit in exemplul dat, se observa ca deși nu exista muchia ''​(d,​c)''​ se simulează un flux pe aceasta printr-unul negativ in sens opus.+{{https://​ocw.cs.pub.ro/​courses/​_media/​pa/​new_pa/​lab12-edmonds-karp-basic-example-02.png?512| Exemplu Edmonds-Karp}}
  
-===== Variații ale problemei clasice ===== +  * Inițial fluxul în rețea este zero. 
-In rețelele clasice studiate pana acum aveam o sursa unica care putea produce oricât, destinația unica consuma oricât, orice nod intermediar conserva fluxul, iar singura constrângere a muchiilor era limitarea superioara a fluxului prin capacitateSa vedem cum putem generaliza aceste condiții si daca rețelele obținute ar putea fi reduse ​la una clasica.+  * Se găsește drumul de ameliorare $1 - 2 - 5 - 6$ (tot de lungime 3 arce) cu capacitatea reziduală 1. Se pompează această unitate de flux. 
 +  * În rețeaua reziduală ​obținută se observă că nu se mai poate ajunge de la S la T. 
 +  * Fluxul total obținut este **1**, care **NU** este maxim.
  
-==== Surse si destinații multiple ====+Prin urmare ajungem într-un punct în care algoritmul a greșit și nu mai poate pompa flux în plus. Parcugeți următorul exemplu pentru a vedea concret cum se rezolvă această problemă.
  
-{{ :​pa:​laboratoare:​105.png?​350 |}}+</​spoiler>​ \\
  
-Se observă ca putem reduce acest graf la cel cunoscut prin adăugarea unei meta-surse legată de sursele mici prin muchii de capacitate nelimitata si analog un meta-terminal cu aceleași proprietăți. Global comportamentul rețelei de flux nu se va schimba. 
  
-==== Cuplaj bipartit maxim ====+=== Exemplu Edmonds-Karp:​ exemplu detaliat cu flux pe arce inverse ​===
  
-Fiind dat un graf neorientat ''​G = (V,​E)'',​ un cuplaj este o submultime de muchii ''​M''​ inclusa in ''​E''​ astfel incat pentru toate varfurile ''​v ∈ V'',​ exista cel mult o muchie in ''​M''​ incidenta in ''​v''​. Spunem ca un varf  ''​v ∈ M''​ este cuplat de cuplajul ''​M''​ daca exista o muchie in ''​M''​ incidenta in ''​v''​. Un cuplaj maxim este un cuplaj de cardinalitate maxima. In cazul grafurilor bipartite, multimea de varfuri poate fi partitionata in ''​V = L U R'',​ unde ''​L''​ si ''​R''​ sunt disjuncte si toate muchiile din ''​E''​ sunt intre ''​L''​ si ''​R''​. Problema poate fi rezolvata ​cu ajutorul notiunii de flux, construind reteaua de transport ''​G'​ = (V',​E'​)''​ pentru graful bipartit ''​G''​. Vom alege sursa //s// si destinatia //t// ca fiind noi varfuri care nu sunt in ''​V''​ si vom construi ''​V'​ = V U {s,​t}''​Arcele orientate ale lui ''​G'''​ sunt date de:+În această secțiune vom arăta ce face algoritmul pas cu pas și vom observa necesitatea și corectitudinea scăderii fluxului pe arcele inverse.
  
-  * ''​E'​ = { (s, u) u ∈ L } U { (u, v) : u ∈ L, v ∈ R si (u, v) ∈ E} U { (v, t) : v ∈ R}''​+Pornim de la rețeaua din figura următoare:
  
-Pentru a completa constructia,​ vom atribui fiecarei muchii din E' capacitatea unitate.+{{https://​ocw.cs.pub.ro/​courses/​_media/​pa/​new_pa/​lab12-edmonds-karp-negative-flow-01.png?​512| Exemplu Edmonds-Karp}}
  
-==== Rețea cu noduri ce nu conservă fluxul ​====+  * ''​%%n ​6%%'',​ ''​%%m ​7%%''​ 
 +  * Sursa este ''​%%S ​1%%'',​ iar terminalul este ''​%%T ​6%%''​. 
 +  * Funcția de capacitate ''​%%c%%''​ are valorile din figură
 +  * Observăm că pentru fiecare arc $(u, v)$ am dus un arc imaginar $(v, u)$ de capacitate **0**. Aceste arce fictive reprezintă cheia funcționării algoritmului Edmonds-Karp:​ de fiecare dată când vom pompa (adăuga) flux pe un arc $(u, v)$, vom scădea cu aceeași valoare ​fluxul ​pe arcul $(v, u)$.
  
-Spre deosebire de //s// si //t// care produc/​consumă oricâtun nod intermediar ar putea produce sau consuma o cantitate constanta ​de flux la trecerea prin el. In acest caz vom avea un invariant la nivel de nod care ia forma:+Să vedem în continuare la ce ne ajută dacă alegem din noughinionist, drumul ​de amelioarare $1 - 2 - 5 - 6$ și dacă de data aceasta putem corecta. Vom face acțiunile marcate în figura următoare:
  
-  * ''​f<​sub>​in<​/sub> − f<​sub>​out<​/sub> = di'',​ unde ''​di''​ este cantitatea produsă suplimentar (''>​ 0''​) sau solicitată (''<​ 0''​) de un nod+{{https://ocw.cs.pub.ro/​courses/​_media/​pa/​new_pa/​lab12-edmonds-karp-negative-flow-02.png?​512| Exemplu Edmonds-Karp}}
  
-Am putea transforma egalitatea in:+  * Se pompează o unitate de flux pe drumul $1 - 2 - 5 - 6$. Prin urmare pe arcele marcate cu verde creștem fluxul cu **+1** unități de flux, iar pe arcele marcate cu roșu scădem (**-1** unități de flux). 
 +  * La pasul următor, se pornește BFS din 1 și se înaintează folosind aceeași condiție - se poate merge pe o muchie $(u, v)$ dacă $f(u, v) \lt c(u, v)$. De data aceasta, această condiție se îndeplinește și pentru unele dintre muchiile inverse - cele cu **-1/0**.
  
-  * ''​(f<​sub>​in</​sub>​ + |di|) – f<​sub>​out</​sub>​ = 0''​ , dacă ''​di < 0''​ +Vom face acțiunile marcate în figura următoare:
-  * ''​f<​sub>​in</​sub>​ − ( f<​sub>​out</​sub>​ + |di|) =  0''​ , daca ''​di > 0''​+
  
-Altfel spus, un nod ce consumă flux poate fi transformat intr-unul ce conservă fluxul și are un in-arc adițional de capacitate ''​|di|'',​ iar unul ce produce flux va avea un out-arc de aceeași capacitate.+{{https://​ocw.cs.pub.ro/​courses/​_media/​pa/​new_pa/​lab12-edmonds-karp-negative-flow-03.png?512| Exemplu Edmonds-Karp}}
  
-La nivelul unei rețele întregi se adaugă un nod sursă cu muchii către toate nodurile ce consumau flux si un nod destinație dinspre toate nodurile ce produceau flux+  * Drumul de ameliorare găsit este $1 - 3 - 5 - 2 - 4 - 6$, care are capacitatea reziduală **1**. Se pompează **+1** pe acest drum (arcele cu verde), se scade în sens invers (arcele cu roșu). 
 +  * La următoarea incercare de apelare BFS, nu se mai poate ajunge de la S la T, prin urmare algoritmul se oprește! 
 +  * Fluxul găsit este **1 + 1 = 2**, care este maxim!
  
-Exemplu: 
  
-{{ :​pa:​laboratoare:​106.png?​250 |}} +<note warning>
-  +
-se va transforma in: +
-  +
-{{ :​pa:​laboratoare:​107.png?​250 |}}+
  
-==== Rețea cu limite inferioare ​de capacitate ====+Să observăm că starea finală a rețelei conține 2 unități de flux. Dacă ne uităm ​cu atenție, observăm că avem o unitate ​de flux pe drumul $1 - 2 - 4 - 6$ și alta pe $1 - 3 - 5 - 6$.
  
-Există cazuri în care aș vrea ca datele de pe muchiile rețelei sa facă parte dintr-un anumit interval ''​[infsup]''​. Pe o astfel de muchie ​fluxul ​trebuie ​să respecte inegalitatea ''​inf ≤ f ≤ sup''​+Deși Edmonds-Karp nu a ales inițial aceste 2 drumuri, s-a corectat pe parcursiar în final, dacă fluxul ​maxim trebuia ​să treacă pe aici, rețeaua reziduală a fost actualizată / corectată până s-a întâmplat acest lucru!
  
-Plecând tot de la condițiile de conservare la nivel de nod putem translata intervalul ''​[inf,​ sup]''​ în ''​[0,​ sup-inf]''​ și să considerăm ​că nodul sursă a consumat ''​inf''​ unități de flux iar nodul destinație a produs ''​inf''​ unități. Din exterior entitatea alcătuită din doua noduri și o muchie este văzută ca acționând ​în același fel asupra fluxului ce o traversează.+Semnificația înaintării pe un arc fictiv este că defapt cautăm să deviem fluxul ​de pe un drum ales anterior (de exemplu, $1 - 2 - 5 - 6$), pe o altă cale (de exemplu, porțiunea $1 - 2$ să se continue cu $2 - 4 - 6$), astfel încât să putem folosi partea eliberată (de exemplu, $5 - 6$), în construcția unui nou drum la pasul curent.
  
-Iată un exemplu de transformare:​+</​note>​
  
-{{ :​pa:​laboratoare:​108.png?​250 |}} +==== Complexitate ====
-  +
-Bineînțeles că toate aceste transformări pot fi combinate pentru a se ajunge la rețeaua de flux clasică.+
  
-===== Concluzii și observații =====+  * **complexitate temporală**:​ $T O(n * m^2)\ sau\ O(|V| * |E|^2)$ 
 +  * **complexitate spațială** : $S O(n)\ sau \ O(|V|)$
  
-Laboratorul de față s-a vrut a fi doar o introducere în domeniul fluxurilor într-un graf – modalitate de a reprezenta probleme de circulație a materialelor atât de frecvent întâlnite. In [1] și [2] găsiți și alți algoritmi interesanți împreună cu studiul complexității lor (algoritmul de pompare preflux, algoritmul „mutare-in-fata”). Spre exemplu, cel mai bun algoritm în prezent pentru cuplajul bipartit maxim se executa in ''​O(√V*E)''​.+<spoiler Detalii (analiză + optimizări)>
  
-===== Referinte =====+  * **complexitate temporală**:​ Demonstrația se găsește în **Introduction to Algorithms**. Ideea de bază este că de fiecare dată când creștem fluxul pe un drum de ameliorare, o muchie devine saturată. Dacă vreodată această muchie va mai fi folosită în alt drum de ameliorare (în cazul unei corecții), aceasta va fi folosită într-un drum mai lung. Respectivele distanțe sunt monotone și limitate de $O(|V|)$. 
 +  * **complexitate spațială** : Stocăm o coadă pentru algoritmul BFS. De asemenea, în implementare vom stoca și un vector de părinți pentru a putea parcurge un drum de ameliorare de la T la S (sens invers).
  
-[1] Introducere in algoritmi, Thomas H. Cormen, Charles E. Leiserson, Ronald R. Rivest – Capitolul VI Algoritmi pe grafuri: Flux maxim+</​spoiler>​ \\
  
-[2] Introducere in analiza algoritmilor,​ Cristian A. Giumale – Cap. V Algoritmi pr grafuri: 
-Fluxuri maxime intr-un graf 
  
-[3] Un articol de la MIT: [[http://​web.mit.edu/​15.053/​www/​AMP-Appendix-C.pdf | A Labeling Algorithm for the maximum flow network problem]]+===== TLDR =====
  
-[4] Resurse wiki – +  * Ford-Fulkerson este un tipar general, **în practică** vom folosi doar algoritmul Edmonds-Karp. 
-[[http://en.wikipedia.org/​wiki/​Edmonds%E2%80%93Karp_algorithm | Edmonds Karp]] [[http://en.wikipedia.org/​wiki/​Max-flow_min-cut_theorem | Max Flow - Min Cut Theorem]]+    * Algoritmul de bazează pe pomparea fluxului pe arcele directe și scăderea pe arcele inverse. 
 +    * Ordinea în care drumurile de amelioare sunt găsite nu conteazăEste un algoritm greedy de tip constructiv care își corectează deciziile pe parcurs. În final mereu găsește fluxul maxim! 
 +  * Dacă în plus avem și costuri pe arce, putem determina flux maxim de cost minim cu Edmonds-Karp înlocuind BFS cu Dijkstra pentru găsirea drumurilor de ameliorare.
  
-[5] +===== Exerciții =====
-[[http://​www.cs.princeton.edu/​~wayne/​cs423/​lectures/​max-flow-applications-4up.pdf | Aplicatii flux maxim]]+
  
-===== Exercitii ===== 
  
 <​note>​ <​note>​
-In acest laborator vom folosi scheletul de laborator din arhiva {{pa:​new_pa:​skel-lab11.zip}}. 
-</​note>​ 
  
 +Scheletul de laborator se găsește pe pagina [[https://​github.com/​acs-pa/​pa-lab/​tree/​main/​skel/​lab12|pa-lab::​skel/​lab12]].
 +
 +</​note>​
 <note warning> <note warning>
-Inainte de a rezolva exercitiile,​ asigurati-va ca ati citit si inteles toate precizarile din sectiunea 
-[[https://​ocw.cs.pub.ro/​courses/​pa/​skel_graph | Precizari laboratoare 07-12]]. 
  
-Prin citirea acestor ​precizari va asigurati ca+Înainte de a rezolva exercițiile,​ asigurați-vă că ați citit și înțeles toate precizările din secțiunea [[https://​ocw.cs.pub.ro/​courses/​pa/​skel_graph | Precizari laboratoare 07-12]]. 
-   ​cunoasteti ​**conventiile** folosite + 
-   ​evitati ​**buguri** +Prin citirea acestor ​precizări vă asigurați că
-   ​evitati ​**depunctari** la lab/​teme/​test+ 
 +  ​știți ​**convențiile** folosite 
 +  evitați ​**buguri** 
 +  evitați ​**depunctări** la lab/​teme/​test 
  
 </​note>​ </​note>​
  
 +==== Edmonds-Karp ====
  
-=== Flux maxim === +Se dă un graf orientat cu n noduri ​și m arce. Graful are pe arce **capacitati pozitive**
-Se da un graf **orientat** cu **n** noduri ​si **m** arce. Graful are pe arce **capacitati pozitive**.+ 
 +Folosiși Edmonds-Karp pentru a găsi fluxul maxim între nodul sursă 1 și nodul destinație n în graful dat.
  
-Folositi **Edmonds-Karp** pentru a gasi **fluxul maxim** intre nodul sursa **1** si nodul destinatie **n** in graful dat. 
  
 <note warning> <note warning>
-Restrictii si precizari: 
-  * $ n <= 1.000 $ 
-  * $ m <= 5.000 $ 
-  * $ 1 <= c <= 110.000 $, unde c este capacitatea unui arc 
-  * Nu exista arc de la **n** la **1**. 
-  * timp de executie 
-    * C++: 1s 
-    * Java: 2s 
-</​note>​ 
  
 +Restricții și precizări:
  
-<note> +  * $ n <= 10^3 $ 
-Rezultatul se va returna sub forma unui singur numar **F**, reprezentand fluxul maxim ce poate fi trimis prin retea+  $ m <= 5 10^3 $ 
-</​note>​+  ​$ 1 <= c <= 110.000$unde c este capacitatea unui arc 
 +  * Nu există arce de la n la 1
 +  * timp de execuție 
 +    * C++: ''​%%1s%%''​ 
 +    * Java: ''​%%2s%%''​
  
-=== BONUS === 
-Rezolvati problema [[https://​infoarena.ro/​problema/​harta| harta]] pe infoarena. 
  
-<hidden+</note
-===== Probleme =====+<​note>​ 
 + 
 +Rezultatul se va returna sub forma unui singur număr, reprezentând fluxul maxim ce poate fi trimis prin rețea.
  
-<note warning> 
-După rezolvarea problemei, toți studenții trebuie să încarce o arhivă cu sursele rezolvării pe Moodle (click [[http://​cs.curs.pub.ro/​2016/​mod/​assign/​view.php?​id=5835|aici]]) pentru a li se puncta laboratorul. 
 </​note>​ </​note>​
  
-==== Networking ​====+==== BONUS ====
  
-Pornind de la un graf orientat conex și două noduri ''​u''​ și ''​v''​ ale acestuia se cere să se determine următorele elemente: +La acest laborator, asistentul va alege 1-2 probleme din secțiunea extra.
-[6p primul punct rezolvat + 3p al doilea]+
  
-a) Tăietura minimală a grafului afișată sub forma a unei mulțimi de cardinal minim de muchii ce trebuie eliminate pentru a deconecta ''​u''​ și ''​v''​.+==== Extra ====
  
-b) Pentru topologia dată, afișați numărul maxim de drumuri disjuncte între ''​u''​ și ''​v'',​ dar și drumurile în sineDouă drumuri sunt considerate disjuncte dacă nu au nicio muchie în comun+  * [[https://​infoarena.ro/​problema/​cuplaj|infoarena/​cuplaj]] 
 +  * [[https://​infoarena.ro/​problema/​fmcm|infoarena/​fcmm]] 
 +  * [[https://​infoarena.ro/​problema/​drumuri2|infoarena/​drumuri2]] 
 +  * [[https://​infoarena.ro/​problema/​joc4|inforena/​joc4]] 
 +  * [[https://​acm.timus.ru/​problem.aspx?​space=1&​num=1533|acm/​fat-hobbits]]
  
-Graful din schelet:+===== Referințe =====
  
-{{ :​pa:​laboratoare:​graf_flux.png?150 |}} +[0] Chapter **Maximum Flow**, “Introduction to Algorithms”,​ Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and Clifford Stein.
-==== Generare de graf orientat ====+
  
-Se dă o listă de ''​N''​ noduri, pentru fiecare cunoscându-se gradul de intrare si de ieșire al acestoraRealizați un program care să construiască un graf **orientat** ''​G''​ cu ''​N''​ noduricare să satisfaca gradele dateNu se permite mai mult de o muchie între două noduri.\\ +[1] [[http://​www.cs.yale.edu/​homes/​lans/​readings/​routing/​ford-max_flow-1956.pdf|Maximal flow through a network]]L.RFord, D.R. Fulkerson
-Exemplu:+
  
-^ Nod ^ Grad intrare ^ Grad iesire ^ +[2] [[http://​www.eecs.umich.edu/​~pettie/​matching/​Edmonds-Karp-network-flow.pdf|Theoretical improvements in algorithmic efficiency for network flow problems]], Edmonds, Jack; Karp, Richard M. 
-|  1  |  1  |  3  | + 
-|  ​ ​| ​ 1  |  2  ​+[3] [[https://​www.cs.bgu.ac.il/​~dinitz/​Papers/​Dinitz_alg.pdf|Dinitz Algorithm]],​ Yefim Dinitz
-|  ​ ​| ​ 3  |  1  | +
-|  4  |  2  |  1  ​|+
  
-O soluție posibilă de muchii: 
-<​code>​ 
-1 2 
-1 4 
-1 3 
-2 3 
-2 1 
-3 4 
-4 3 
-</​code>​ 
-</​hidden>​ 
pa/laboratoare/laborator-11.1526565817.txt.gz · Last modified: 2018/05/17 17:03 by stefania.budulan
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0