Przeskocz do treści

Delta mi!

Skojarzenia...

Tomasz Idziaszek

o artykule ...

  • Publikacja w Delcie: listopad 2013
  • Publikacja elektroniczna: 01-11-2013

Ten numer Delty jest zdominowany przez tematykę skojarzeń w grafach. Dla przypomnienia: graf nieskierowany to zbiór wierzchołków połączonych krawędziami, skojarzenie zaś w tym grafie to taki podzbiór krawędzi math że każdy wierzchołek grafu jest incydentny z co najwyżej jedną krawędzią z  math

obrazek

Rys. 1 Po lewej: przykładowe skojarzenie w grafie (pogrubiona krawędź). Po prawej: jedyne najliczniejsze skojarzenie w tym samym grafie.

Rys. 1 Po lewej: przykładowe skojarzenie w grafie (pogrubiona krawędź). Po prawej: jedyne najliczniejsze skojarzenie w tym samym grafie.

W wielu zastosowaniach interesować nas będzie wyznaczenie najliczniejszego skojarzenia w grafie, tzn. skojarzenia, które zawiera możliwie najwięcej krawędzi. W tym artykule pokażemy, jak znajdować takie skojarzenia.

obrazek

Rys. 2 Graf z wyróżnioną ścieżką powiększającą skojarzenie (kolor) oraz graf po powiększeniu skojarzenia wzdłuż tej ścieżki.

Rys. 2 Graf z wyróżnioną ścieżką powiększającą skojarzenie (kolor) oraz graf po powiększeniu skojarzenia wzdłuż tej ścieżki.

Nasze algorytmy będą działały metodą przyrostową: dla danego grafu math  i wyróżnionego w nim skojarzenia math  będą znajdować skojarzenie o jedną krawędź większe bądź też będą stwierdzać, że math  jest już najliczniejszym skojarzeniem. W jaki sposób można powiększyć skojarzenie? Zauważmy, że jeśli w grafie istnieją dwa nieskojarzone wierzchołki połączone krawędzią, to można tę krawędź dodać do skojarzenia. Pomysł ten można uogólnić: jeśli w grafie istnieją dwa nieskojarzone wierzchołki math połączone ścieżką, na której dokładnie co druga krawędź jest skojarzona, tzn. ścieżką

display-math

to można wyrzucić ze skojarzenia math krawędzi math dla math nieparzystego i dorzucić do niego math krawędzi math dla math parzystego (Rys. 2). Taką ścieżkę, wzdłuż której powiększamy skojarzenie, nazywamy ścieżką powiększającą to skojarzenie. Jasne jest, że jeśli taka ścieżka w grafie istnieje, to możemy powiększyć skojarzenie. Okazuje się, że implikacja w przeciwną stronę również zachodzi i jest tezą twierdzenia sformułowanego i udowodnionego przez francuskiego matematyka Claude’a Berge’a:

Twierdzenie. Skojarzenie w grafie jest najliczniejsze wtedy i tylko wtedy, gdy nie istnieje ścieżka powiększająca to skojarzenie.

Tak więc to, czego potrzebujemy, to procedura znajdowania ścieżki powiększającej lub stwierdzania, że takowa nie istnieje. Dla ustalenia uwagi możemy skupić się na poszukiwaniu ścieżki powiększającej zaczynającej się w ustalonym nieskojarzonym wierzchołku math – wystarczy przejrzeć wszystkie takie wierzchołki. Oczywiście, moglibyśmy wyznaczyć wszystkie ścieżki wychodzące z tego wierzchołka, korzystając z przeszukiwania z nawrotami. Taka metoda będzie jednak wymagać czasu wykładniczego, zatem potrzebujemy czegoś sprytniejszego.

obrazek

Rys. 3 Graf dwudzielny math z wyróżnionymi krawędziami odwiedzonymi podczas przeszukiwania w głąb oraz graf skierowany math W obu grafach podpisano wierzchołki ze zbioru math

Rys. 3 Graf dwudzielny math z wyróżnionymi krawędziami odwiedzonymi podczas przeszukiwania w głąb oraz graf skierowany math W obu grafach podpisano wierzchołki ze zbioru math

Na początek zajmiemy się grafami dwudzielnymi, tzn. takimi, których zbiór wierzchołków możemy podzielić na takie dwa podzbiory math  że każda krawędź łączy wierzchołki należące do różnych podzbiorów. Spróbujmy usprawnić przeszukiwanie z nawrotami, tak aby odwiedzić każdy wierzchołek co najwyżej raz. A konkretnie: zaczynając z wierzchołka math wykonujemy przeszukiwanie grafu w głąb, z tym że w każdym wierzchołku na głębokości parzystej przeglądamy nieskojarzone krawędzie wychodzące z tego wierzchołka, w każdym zaś wierzchołku na głębokości nieparzystej idziemy krawędzią skojarzoną (może być co najwyżej jedna). Jeśli trafimy na wierzchołek nieskojarzony, to znaczy, że znaleźliśmy ścieżkę powiększającą (Rys. 3). Co ciekawe, jeśli na niego nie trafiliśmy, to znaczy, że ścieżki powiększającej nie ma. Jak to udowodnić?

Rozważmy graf skierowany math  o zbiorze wierzchołków math  Dla każdej krawędzi math math  z naszego math  dodajmy do math  skierowaną krawędź: math  jeśli math  albo math jeśli math  Zauważmy, że w grafie math  istnieje ścieżka powiększająca wtedy i tylko wtedy, gdy w grafie math  da się dojść (zgodnie ze skierowaniem krawędzi) z wierzchołka math do innego wierzchołka nieskojarzonego. A powyższy algorytm to nic innego jak zwykłe przeszukiwanie w głąb grafu math

Przeszukiwanie to działa w czasie math  zatem znalezienie ścieżki powiększającej zajmie czas math  jeśli zaczynamy przeszukiwanie z każdego wierzchołka nieskojarzonego od nowa, lub math  jeśli zaczynamy naraz z wszystkich wierzchołków nieskojarzonych z  math (dlaczego możemy tak zrobić?). Skojarzenie może być powiększone co najwyżej math razy, zatem cały algorytm działa w czasie math Dodajmy, że w praktyce nie opłaca się zaczynać z pustego skojarzenia, ale z jakiegoś skojarzenia znalezionego prostszą metodą (przykładowo, algorytm zachłannie dodający kolejne krawędzie do skojarzenia zawsze znajdzie skojarzenie o liczności równej co najmniej połowie liczności najliczniejszego skojarzenia).

obrazek

Rys. 4 Po lewej: graf ze skojarzeniem (pogrubione krawędzie) i ścieżką powiększającą (kolor). Po prawej: ten sam graf z krawędziami odwiedzonymi przez algorytm.

Rys. 4 Po lewej: graf ze skojarzeniem (pogrubione krawędzie) i ścieżką powiększającą (kolor). Po prawej: ten sam graf z krawędziami odwiedzonymi przez algorytm.

Okazuje się, że w przypadku grafów, które nie są dwudzielne, sprawa się komplikuje, a nasz algorytm nie działa. Istotnie, spójrzmy na graf z rysunku 4 Pomimo tego, że istnieje w nim ścieżka powiększająca z wierzchołka math do wierzchołka math to algorytm nigdy jej nie znajdzie, jeśli zacznie obchodzić cykl od lewej strony (w szczególności nigdy nie odwiedzi wierzchołka math).

Cały kłopot jest powodowany przez cykle, które znajdujemy, przeszukując graf. Problematyczne okazują się mianowicie cykle nieparzystej długości, które są połączone z wierzchołkiem math ścieżką o parzystej długości. Taki cykl nazwiemy kielichem (ang. blossom), a ścieżkę łodygą (ang. stem). Kanadyjski matematyk Jack Edmonds podał następujący sposób, w jaki można sobie z nimi radzić: ściągnąć, czyli zastąpić jednym wierzchołkiem, a następnie rekurencyjnie poszukać ścieżki powiększającej w mniejszym grafie. Przyjrzyjmy się temu pomysłowi bliżej.

obrazek

Rys. 5 Na górze po lewej: graf math z zaznaczonym kielichem. Na górze po prawej: graf math z zaznaczoną ścieżką powiększającą. Na dole: dwie możliwości uzupełnienia ścieżki powiększającej w grafie math

Rys. 5 Na górze po lewej: graf math z zaznaczonym kielichem. Na górze po prawej: graf math z zaznaczoną ścieżką powiększającą. Na dole: dwie możliwości uzupełnienia ścieżki powiększającej w grafie math

Operacja ściągnięcia kielicha wygląda następująco (Rys. 5): zastępujemy wszystkie wierzchołki kielicha jednym wierzchołkiem math  który jest połączony krawędziami z wszystkimi sąsiadami kielicha, otrzymując graf math  Zauważmy, że na rysunku wierzchołek math który łączył kielich z łodygą, był jedynym wierzchołkiem spośród wierzchołków kielicha skojarzonym z wierzchołkiem poza kielichem, zatem wierzchołek math  będzie również skojarzony z dokładnie jednym wierzchołkiem. Wynika z tego, że po ściągnięciu nowo utworzone skojarzenie math  nadal jest poprawne. Okazuje się, że prawdziwy jest następujący lemat:

Lemat. W grafie math  istnieje ścieżka powiększająca skojarzenie math  wtedy i tylko wtedy, gdy w grafie math  istnieje ścieżka powiększająca skojarzenie math

Dla dowodu lematu załóżmy, że w grafie math  znaleźliśmy ścieżkę powiększającą math Pokażemy, jak dzięki niej znaleźć ścieżkę w grafie math  Jeśli ścieżka math nie zawiera wierzchołka math to w oczywisty sposób jest ona również ścieżką powiększającą w  math  W przeciwnym przypadku można ją uzupełnić krawędziami z kielicha, przechodząc go w lewo lub w prawo, w zależności od położenia wierzchołka math którym wchodzi druga krawędź ścieżki (Rys. 5). Ponadto każda ścieżka powiększająca w  math  musi być takiej postaci (tzn. jeśli przecina kielich, to wchodzi do niego krawędzią łodygi), zatem jest również ścieżką powiększającą w  math

Jako zadanie dla Czytelnika pozostawiamy wykazanie, że jeśli w  math  istnieje ścieżka powiększająca, to nasz algorytm wyszukujący ścieżki powiększające albo ją znajdzie, albo znajdzie kielich, który można ściągnąć.

Znalezienie ścieżki powiększającej z ustalonego wierzchołka zajmuje czas math gdyż potencjalnie aż math  razy będziemy musieli wykonać ściągnięcie kielicha. Zatem cały algorytm działa w czasie math

Na koniec zaznaczmy, że opisane algorytmy nie są najlepszymi znanymi algorytmami znajdującymi najliczniejsze skojarzenia w grafach, są za to niezbyt skomplikowane. Przykładowo algorytm Hopcrofta–Karpa dla grafów dwudzielnych oraz algorytm Micalego–Vaziraniego dla grafów dowolnych działają w czasie math  zaś randomizowany algorytm Muchy–Sankowskiego sprowadza znajdowanie skojarzenia w grafie dowolnym do problemu mnożenia macierzy i działa w czasie math