Algorytm Forda-Fulkersona

Metoda Forda-Fulkersona lub algorytm Forda-Fulkersona ( FFA ) to zachłanny algorytm , który oblicza maksymalny przepływ w sieci przepływów . Czasami nazywa się to „metodą” zamiast „algorytmem”, ponieważ podejście do znajdowania ścieżek rozszerzających na wykresie resztkowym nie jest w pełni określone lub jest określone w kilku implementacjach o różnych czasach działania. Został opublikowany w 1956 roku przez LR Forda Jr. i DR Fulkersona . Nazwa „Ford – Fulkerson” jest również często używana w odniesieniu do algorytmu Edmondsa – Karpa , który jest w pełni zdefiniowaną implementacją metody Forda – Fulkersona.

Idea algorytmu jest następująca: dopóki istnieje ścieżka od źródła (węzeł startowy) do ujścia (węzeł końcowy), z dostępną przepustowością na wszystkich krawędziach ścieżki, wysyłamy przepływ wzdłuż jednej ze ścieżek. Następnie znajdujemy inną ścieżkę i tak dalej. Ścieżka z dostępną pojemnością jest nazywana ścieżką rozszerzającą .

Algorytm

Niech i dla każdej krawędzi od do v , niech do i być przepływem Chcemy znaleźć maksymalny przepływ od źródła s do ujścia t . Po każdym kroku algorytmu zachowywane są:

Ograniczenia pojemności Przepływ wzdłuż krawędzi nie może przekroczyć jej wydajności.
Symetria skośna Przepływ netto od u do v musi być przeciwieństwem przepływu netto od v do u (patrz przykład).
Zachowanie przepływu Przepływ netto do węzła wynosi zero, z wyjątkiem źródła, które „wytwarza” przepływ, oraz ujścia, które „konsumuje” przepływ.
Wartość (f) Przepływ wychodzący z s musi być równy przepływowi docierającemu do t .

Oznacza to, że przepływ przez sieć jest legalnym przepływem po każdej rundzie w algorytmie. rezydualną definiujemy sieć i brak przepływu. Zauważ, że może się zdarzyć, że przepływ z v do u jest dozwolony w sieci rezydualnej, chociaż zabroniony w sieci oryginalnej: if i wtedy do .

 Algorytm  Forda-Fulkersona 
Wejścia Biorąc pod uwagę sieć o przepustowości c , węźle źródłowym s i węźle ujścia t sol
Wyjście Oblicz przepływ f od s do t o maksymalnej wartości
  1. dla wszystkich krawędzi
  2. Chociaż istnieje ścieżka p od s do t w , taka, że wszystkich krawędzi :
    1. Znajdź do
    2. dla każdej krawędzi
      1. Wyślij przepływ wzdłuż ścieżka )
      2. ( Przepływ może być „powrócił” później )
  • „←” oznacza przypisanie . Na przykład „ największy przedmiot ” oznacza, że ​​wartość największego zmienia się na wartość elementu .
  • return ” kończy działanie algorytmu i wyświetla następującą wartość.

Ścieżkę w kroku 2 można znaleźć na przykład za pomocą przeszukiwania wszerz (BFS) lub przeszukiwania w głąb w sol fa . Jeśli użyjesz pierwszego, algorytm nazywa się Edmonds-Karp .

Kiedy nie można znaleźć więcej ścieżek w kroku 2, s nie będzie w stanie dotrzeć do t w sieci rezydualnej. Jeśli S jest zbiorem węzłów osiągalnych przez s w sieci rezydualnej, to całkowita przepustowość w pierwotnej sieci krawędzi od S do reszty V jest z jednej strony równa całkowitemu przepływowi, który znaleźliśmy od s do t , oraz z drugiej strony służy jako górna granica dla wszystkich takich przepływów. Dowodzi to, że przepływ, który znaleźliśmy, jest maksymalny. Zobacz także Twierdzenie o maksymalnym przepływie i minimalnym cięciu .

Jeśli wykres Załóżmy, że i . Dodaj nowe źródło z krawędzią. od do każdego węzła o pojemności . I nowy zlew z krawędzią z każdego węzła do , z pojemnością . Następnie zastosuj algorytm Forda-Fulkersona.


jeśli węzeł u ograniczenie przepustowości , zastępujemy ten węzeł dwoma węzłami i krawędź o pojemności . Następnie zastosuj algorytm Forda-Fulkersona.

Złożoność

Dodając ścieżkę zwiększania przepływu do przepływu już ustalonego na wykresie, maksymalny przepływ zostanie osiągnięty, gdy na wykresie nie będzie już można znaleźć ścieżek zwiększania przepływu. Jednak nie ma pewności, że ta sytuacja kiedykolwiek zostanie osiągnięta, więc najlepsze, co można zagwarantować, to to, że odpowiedź będzie poprawna, jeśli algorytm się zakończy. W przypadku, gdy algorytm działa w nieskończoność, przepływ może nawet nie zbliżać się do przepływu maksymalnego. Taka sytuacja występuje jednak tylko przy nieracjonalnych wartościach przepływu. Gdy pojemności są liczbami całkowitymi, czas pracy Forda-Fulkersona jest ograniczony przez (patrz dużego O ), gdzie jest krawędzi na wykresie, a maksymalnym przepływem na Dzieje się tak, ponieważ każdą ścieżkę zwiększającą można znaleźć w czasie i zwiększa przepływ o liczbę całkowitą wynoszącą co najmniej górną granicą .

Odmianą algorytmu Forda-Fulkersona z gwarantowanym zakończeniem i czasem działania niezależnym od maksymalnej wartości przepływu jest działa w .

Przykład integralny

pokazuje pierwsze kroki Forda-Fulkersona w sieci przepływowej z 4 węzłami i . Ten przykład pokazuje zachowanie algorytmu w najgorszym przypadku. przez sieć przesyłany jest . Gdyby zamiast tego zastosowano przeszukiwanie wszerz, potrzebne byłyby tylko dwa kroki.

Ścieżka Pojemność Wynikowa sieć przepływów
Początkowa sieć przepływu Ford-Fulkerson example 0.svg
Ford-Fulkerson example 1.svg
Ford-Fulkerson example 2.svg
Po 1998 kolejne kroki...
Sieć finalna Ford-Fulkerson example final.svg

jest „cofany” z { displaystyle ścieżki

Niekończący się przykład

Ford-Fulkerson forever.svg

Rozważmy sieć przepływów pokazaną po prawej stronie, ze źródłem zlew , pojemnościami krawędzi , mi odpowiednio , i i pojemność wszystkich innych krawędzi niektóre liczby całkowite . Stała została wybrana tak, że } Używamy ścieżek rozszerzających zgodnie z poniższą tabelą, gdzie , i .

Krok Ścieżka powiększająca Wysłany strumień Pojemność resztkowa
0
1
2
3
4
5

Należy zauważyć, że zarówno po kroku 1, jak i po kroku 5, resztkowe pojemności krawędzi mi , i w postaci odpowiednio , i przez pewien . Oznacza to, że możemy użyć ścieżek rozszerzających , , i nieskończenie wiele razy, a pojemności resztkowe tych krawędzi będą zawsze w tej samej postaci. Całkowity przepływ w sieci po kroku 5 wynosi . Jeśli nadal będziemy używać ścieżek rozszerzających jak powyżej, całkowity przepływ zbiegnie się do . przepływ wartości , wysyłając jednostki przepływu wzdłuż , 1 jednostka przepływu wzdłuż przepływu wzdłuż v_ . Dlatego algorytm nigdy się nie kończy, a przepływ nawet nie zbliża się do maksymalnego przepływu.

Inny niekończący się przykład oparty na algorytmie euklidesowym podaje Backman & Huynh (2018) , gdzie pokazują również, że najgorszy przypadek czasu działania algorytmu Forda-Fulkersona w sieci w liczbach porządkowych to .

Implementacja algorytmu Edmondsa-Karpa w języku Python

 


 
    




      
            
          

        import  collections  class  Graph  :  """  Ta klasa reprezentuje graf skierowany przy użyciu  reprezentacji macierzy sąsiedztwa.  """  def  __init__  (  self  ,  graph  ):  self  .  graph  =  graph  # resztkowy wykres  self  .  wiersz  =  len  (  wykres  )  def  bfs  (  self  ,  s  ,  t  
        





        
            

        
          

        
         ,  parent  ):  """  Zwraca true, jeśli istnieje ścieżka od  źródła "s" do ujścia "t" w resztkowym grafie.  Wypełnia również parent[], aby zapisać ścieżkę.  """  # Zaznacz wszystkie wierzchołki jako  nieodwiedzone  =  [  Fałsz  ]  *  jaźń  .  wiersz  # Utwórz kolejkę dla  kolejki BFS   =  kolekcje  .  deque  ()  # Zaznacz węzeł źródłowy jako odwiedzony i umieść go  w kolejce 
          

        
         
              

            
            
            
                
                 .  append  (  s  )  odwiedzono  [  s  ]  =  Prawda  # Standardowa pętla BFS  while  kolejka  :  u  =  kolejka  .  popleft  ()  # Pobierz wszystkie sąsiednie wierzchołki usuniętego z kolejki u  # Jeśli sąsiad nie został odwiedzony, zaznacz go  # odwiedzono i dodaj do kolejki  dla  ind  ,  val  in  enumerate  (  self  .  graph  [  u  ]):  if        0
                    
                      
                      

        
        
          (  odwiedzone  [  ind  ]  ==  False  )  i  (  val  >  ):  kolejka  .  append  (  ind  )  odwiedziliśmy  [  ind  ]  =  Prawdziwy  rodzic  [  ind  ]  =  u  # Jeśli osiągnęliśmy ujście w BFS zaczynając od źródła, zwróć  # prawda, w przeciwnym razie  zwróć  odwiedzone  [  t  ] 

    
       
        
            

          0  

        
           # Zwraca maksymalny przepływ od s do t w danym grafie  def  edmonds_karp  (  self  ,  source  ,  sink  ):  # Ta tablica jest wypełniana przez BFS i do przechowywania ścieżki  parent  =  [  -  1  ]  *  self  .  row  max_flow  =  # Na początku nie ma przepływu  # Zwiększ przepływ , dopóki istnieje ścieżka od źródła do ujścia ,  podczas gdy  self  .  bfs  (  źródło  ,  ujście  ,  
            
            
            
              
              
               
                   
                  parent  ):  # Znajdź minimalną pojemność resztkową krawędzi wzdłuż  # ścieżki wypełnionej przez BFS. Lub możemy powiedzieć, znajdź maksymalny przepływ   # przez znalezioną ścieżkę.  path_flow  =  float  (  "Inf"  )  s  =  sink  while  s  !=  source  :  path_flow  =  min  (  path_flow  ,  self  .  graph  [  rodzic  [  s  ]][  s  ])  s  =  

            
              

            
            
              
               
                  
                  
                 parent  [  s  ]  # Dodaj przepływ ścieżki do ogólnego przepływu  max_flow  +=  path_flow  # zaktualizuj resztkowe pojemności krawędzi i odwróć krawędzie  # wzdłuż ścieżki  v  =  sink  while  v  !=  source  :  u  =  parent  [  v  ]  self  .  graph  [  u  ][  v  ]  -=  ścieżka_przepływu  siebie  .  wykres  [  v  ][  u   
                  

          ]  +=  ścieżka_przepływu  v  =  rodzic  [  v  ]  powrót  maks_przepływu 

Zobacz też

Notatki

Linki zewnętrzne

Media związane z algorytmem Forda-Fulkersona w Wikimedia Commons