ASD Ćwiczenia 10: Różnice pomiędzy wersjami
Nie podano opisu zmian |
Nie podano opisu zmian |
||
Linia 36: | Linia 36: | ||
Rozwiązanie <div class="mw-collapsible-content" style="display:none"> | Rozwiązanie <div class="mw-collapsible-content" style="display:none"> | ||
MakeSet(x) | MakeSet(x)<br> | ||
ojciec(x) := x | ojciec(x) := x<br> | ||
ranga(x) := 0 | ranga(x) := 0<br> | ||
Union(x,y) | Union(x,y)<br> | ||
if ranga(x)>ranga(y) then | if ranga(x)>ranga(y) then<br> | ||
ojciec(y) := x | ojciec(y) := x<br> | ||
else | else<br> | ||
ojciec(x) := y | ojciec(x) := y<br> | ||
if ranga(x) = ranga(y) then | if ranga(x) = ranga(y) then<br> | ||
ranga(y) := ranga(y)+1 | ranga(y) := ranga(y)+1<br> | ||
Find(x) | Find(x)<br> | ||
if x <> ojciec(x) then | if x <> ojciec(x) then<br> | ||
ojciec(x) := Find(ojciec(x)) | ojciec(x) := Find(ojciec(x))<br> | ||
return ojciec(x) | return ojciec(x)<br> | ||
</div></div> | </div></div> | ||
Zadanie | |||
Zadanie 5 | |||
Udowodnij Lemat 1. | Udowodnij Lemat 1. | ||
Rozwiązanie | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> | ||
Zauważmy, że ''ranga'' węzła | Rozwiązanie <div class="mw-collapsible-content" style="display:none"> | ||
Zauważmy, że ''ranga'' węzła x w lesie zbiorów rozłącznych powstającym w wyniku ciągu <math>\sigma</math> operacji MakeSet, Union i Find jest równa ''wysokości'' poddrzewa x w lesie dla ciągu operacji <math>\sigma'</math> utworzonego z <math>\sigma</math> przez usunięcie wszystkich operacji Find. Stąd natychmiast wynikają punkty (a) i (b), bo wysokości poddrzew na ścieżce od dowolnego węzła do korzenia tworzą ciąg ściśle rosnący. Punkt (c) wynika z zadania 3, a (d) wynika z (c) (bo każdy węzeł może należeć do co najwyżej jednego poddrzewa o korzeniu rangi r).</div></div> | |||
Zadanie | |||
Zadanie 6 | |||
Udowodnij, że jeśli w implementacji drzewiastej z lączeniem wedlug rangi i kompresją ściezki najpierw wykonujemy wszystkie operacje Union, a dopiero potem wszystkie operacje Find, to zamortyzowany koszt operacji Find jest stały. | Udowodnij, że jeśli w implementacji drzewiastej z lączeniem wedlug rangi i kompresją ściezki najpierw wykonujemy wszystkie operacje Union, a dopiero potem wszystkie operacje Find, to zamortyzowany koszt operacji Find jest stały. | ||
Rozwiązanie | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> | ||
Każdą krawędź drzewa utworzonego w wyniku ciągu operacji Union - z wyjątkiem krawędzi prowadzących do korzenia - przechodzimy tylko raz. | Rozwiązanie <div class="mw-collapsible-content" style="display:none"> | ||
Każdą krawędź drzewa utworzonego w wyniku ciągu operacji Union - z wyjątkiem krawędzi prowadzących do korzenia - przechodzimy tylko raz. </div></div> | |||
Rozwiązanie | Zadanie 7 | ||
Sortujemy krawędzie niemalejąco według wag: | Algorytm Kruskala znajdowania minimalnego drzewa rozpinającego w grafie <math>G = (V,E)</math> z wagami na krawędziach działa następująco: krawędzie są przeglądane w kolejności od najlżejszej do najcięższej. Aktualnie rozważaną krawędź dodajemy do budowanego drzewa, o ile tylko nie powoduje to powstania cyklu. Jak efektywnie zaimplementować ten algorytm? Jaki jest jego czas działania? | ||
for i := 1 to |V| do | |||
<div class="mw-collapsible mw-made=collapsible mw-collapsed"> | |||
T := $\emtyset$; | Rozwiązanie <div class="mw-collapsible-content" style="display:none"> | ||
for j := 1 to m do | Sortujemy krawędzie niemalejąco według wag: <math>e_1, \ldots, e_m</math>; | ||
for i := 1 to |V| do<br> | |||
MakeSet(v_i);<br> | |||
T := $\emtyset$;<br> | |||
for j := 1 to m do<br> | |||
niech e_j = {v_i, v_k);<br> | |||
if Find(v_i) <> Find(v_k) then <br> | |||
T := T $\cup$ e_j;<br> | |||
Union(Find(v_i),Find(v_k))<br> | |||
Koszt tej implementacji jest zdominowany przez koszt sortowania: O(m\log m). | Koszt tej implementacji jest zdominowany przez koszt sortowania: O(m\log m). | ||
</div></div> | |||
Zadanie | Zadanie 8 | ||
Napisz program generujący labirynt następująca metodą: Na początku każda komnata jest otoczona ścianami. W każdym kroku wybieramy losowo ścianę i usuwamy ją, jeśli komnaty po jej obu stronach nie są jeszcze połączone żadną drogą. | Napisz program generujący labirynt następująca metodą: Na początku każda komnata jest otoczona ścianami. W każdym kroku wybieramy losowo ścianę i usuwamy ją, jeśli komnaty po jej obu stronach nie są jeszcze połączone żadną drogą. | ||
Rozwiązanie | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> | ||
Do zarządzania relacją "komnaty są połączone pewną drogą" należy wykorzystać strukturę danych dla zbiorów rozłącznych. | Rozwiązanie <div class="mw-collapsible-content" style="display:none"> | ||
Do zarządzania relacją "komnaty są połączone pewną drogą" należy wykorzystać strukturę danych dla zbiorów rozłącznych.</div></div> | |||
Zadanie | Zadanie 9 | ||
Plansza do gry w Hex ma kształt rombu zbudowanego z sześciokątnych pól. Dwaj gracze wykonują na przemian ruchy polegające na dostawieniu pionka na jedno pole. Celem pierwszego gracza jest zbudowanie z białych pionków drogi łączącej lewy dolny brzeg planszy z prawym górnym, natomiast celem drugiego jest zbudowanie z czarnych pionków drogi łączącej lewy górny brzeg planszy z prawym dolnym. | Plansza do gry w Hex ma kształt rombu zbudowanego z sześciokątnych pól. Dwaj gracze wykonują na przemian ruchy polegające na dostawieniu pionka na jedno pole. Celem pierwszego gracza jest zbudowanie z białych pionków drogi łączącej lewy dolny brzeg planszy z prawym górnym, natomiast celem drugiego jest zbudowanie z czarnych pionków drogi łączącej lewy górny brzeg planszy z prawym dolnym. | ||
Linia 95: | Linia 107: | ||
Zaprojektuj algorytm, który po każdym ruchu sprawdza, czy nastąpiła wygrana któregoś z graczy. | Zaprojektuj algorytm, który po każdym ruchu sprawdza, czy nastąpiła wygrana któregoś z graczy. | ||
Rozwiązanie | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> | ||
Rozwiązanie <div class="mw-collapsible-content" style="display:none"> | |||
Planszę możemy interpretować jako graf, w którym wierzchołki odpowiadają polom, a krawędzie łączą te pola, które sąsiadują ze sobą. Warto dołożyć jeszcze po dwa sztuczne białe i czarne wierzchołki połączone krawędziami z polami z odpowiednich brzegów planszy. Po każdym ruchu algorytm powinien uaktualnić składowe, odpowiednio, w białej albo czarnej części grafu (Union) i sprawdzić, czy sztuczne, "brzegowe" wierzchołki znalazły się w jednej składowej (Find). | Planszę możemy interpretować jako graf, w którym wierzchołki odpowiadają polom, a krawędzie łączą te pola, które sąsiadują ze sobą. Warto dołożyć jeszcze po dwa sztuczne białe i czarne wierzchołki połączone krawędziami z polami z odpowiednich brzegów planszy. Po każdym ruchu algorytm powinien uaktualnić składowe, odpowiednio, w białej albo czarnej części grafu (Union) i sprawdzić, czy sztuczne, "brzegowe" wierzchołki znalazły się w jednej składowej (Find). | ||
</div></div> |
Wersja z 10:50, 16 sie 2006
Zadanie 1 Podaj przykład ciągu operacji MakeSet, Find i Union w implementacji listowej bez łączenia z wyważaniem, których łączny koszt to .
Rozwiązanie
Zadanie 2
Udowodnij, że w implementacji listowej z heurystyką łączenia z wyważaniem koszt wykonania $m$ operacji MakeSet, Find i Union, sposród których n to MakeSet, wynosi .
Rozwiązanie
Zadanie 3
Udowodnij, że w implementacji drzewiastej z łączeniem według wysokości wysokość drzewa zawierającego n węzłów jest mniejsza bądź równa .
Zadanie 4
Napisz pseudokod operacji MakeSet, Union i Find w implementacji drzewiastej z łączeniem według rangi i kompresją ścieżki.
Zadanie 5
Udowodnij Lemat 1.
Zadanie 6
Udowodnij, że jeśli w implementacji drzewiastej z lączeniem wedlug rangi i kompresją ściezki najpierw wykonujemy wszystkie operacje Union, a dopiero potem wszystkie operacje Find, to zamortyzowany koszt operacji Find jest stały.
Zadanie 7
Algorytm Kruskala znajdowania minimalnego drzewa rozpinającego w grafie z wagami na krawędziach działa następująco: krawędzie są przeglądane w kolejności od najlżejszej do najcięższej. Aktualnie rozważaną krawędź dodajemy do budowanego drzewa, o ile tylko nie powoduje to powstania cyklu. Jak efektywnie zaimplementować ten algorytm? Jaki jest jego czas działania?
Zadanie 8
Napisz program generujący labirynt następująca metodą: Na początku każda komnata jest otoczona ścianami. W każdym kroku wybieramy losowo ścianę i usuwamy ją, jeśli komnaty po jej obu stronach nie są jeszcze połączone żadną drogą.
Zadanie 9
Plansza do gry w Hex ma kształt rombu zbudowanego z sześciokątnych pól. Dwaj gracze wykonują na przemian ruchy polegające na dostawieniu pionka na jedno pole. Celem pierwszego gracza jest zbudowanie z białych pionków drogi łączącej lewy dolny brzeg planszy z prawym górnym, natomiast celem drugiego jest zbudowanie z czarnych pionków drogi łączącej lewy górny brzeg planszy z prawym dolnym.
- rysunek ****************************
Zaprojektuj algorytm, który po każdym ruchu sprawdza, czy nastąpiła wygrana któregoś z graczy.