Popularyzatorem łamigłówki znanej jako Wieże Hanoi jest francuski matematyk Édouard Lucas. Zajmował się on m.in. badaniem właściwości ciągu Fibonacciego (podał wzór na jego n‑ty wyraz) i opracował własną metodę sprawdzania, czy liczba naturalna jest liczbą pierwszą. Ideę Wież Hanoi Lucas przedstawił w 1883 roku.

Na czym polega zagadka Wież Hanoi?

Zagadka Wież Hanoi polega na przeniesieniu n krążków z jednego słupka na drugi. Musi jednak zostać spełnionych kilka warunków:

  • krążki muszą mieć różne średnice,

  • wszystkie krążki początkowo są nałożone na jeden ze słupków,

  • krążki są ułożone w kolejności od krążka o największej średnicy (na dole słupka) do krążka o najmniejszej średnicy (na górze słupka),

  • jednorazowo możemy przenieść tylko jeden krążek,

  • nie można położyć większego krążka na mniejszym,

  • mamy do dyspozycji dodatkowy, pomocniczy słupek, na który możemy tymczasowo nakładać krążki.

Gdy wszystkie krążki znajdą się na docelowym słupku, uznajemy problem za rozwiązany. Poniżej został zobrazowany stan początkowy – wszystkie krążki znajdują się na słupku A, a następnie stan końcowy – wszystkie krążki znajdują się na słupku C. Pomocniczym słupkiem jest słupek B.

RdHYtzjRP3egy
Źródło: Contentplus.pl Sp. z o.o., licencja: CC BY-SA 3.0.

Rozwiązanie iteracyjne

Zastanówmy się, w jaki sposób rozwiązać zagadkę Wież Hanoi iteracyjnieiteracjaiteracyjnie.

Aby rozwiązać problem, krążki musimy przekładać na zmianę. Pierwszym krokiem jest przeniesienie najmniejszego krążka ze słupka, na którym jest nałożony, na kolejny słupek. Kolejny słupek wyznaczamy w następujący sposób:

  • Jeżeli liczba krążków jest parzysta, kolejnym słupkiem jest słupek po prawej stronie, czyli ze słupka A przenosimy na słupek B, ze słupka C na słupek A.

  • Jeżeli liczba krążków jest nieparzysta, kolejnym słupkiem jest ten po lewej stronie, czyli ze słupka A przenosimy na słupek C itd.

Drugi krok polega na tym, że innym krążkiem wykonamy jedyny dostępny ruch, to znaczy taki, w którym nie położymy większego krążka na mniejszy.

Dwa powyższe kroki powtarzamy tak długo, aż wszystkie krążki znajdą się na słupku C.

Kolejne etapy rozwiązania zagadki Wież Hanoi dla trzech krążków zostały przedstawione poniżej. Na czerwono zostały oznaczone krążki, które będziemy przenosić, natomiast na fioletowo krążki, które zostały właśnie przeniesione.

R16tLCSW03i4Q1
Źródło: Contentplus.pl Sp. z o.o., licencja: CC BY-SA 3.0.

Jak widać na powyższym obrazku, wykonaliśmy siedem ruchów w celu przeniesienia trzech krążków.

Buddyjska legenda a informatyka

Dlaczego na lekcji informatyki w ogóle zajmujemy się układanką pochodzącą z czasów, gdy nie istniały jeszcze komputery? Otóż Wieże Hanoi zbudowane są podobnie do struktury danych zwanej stosemstosstosem, wykorzystywanej przez procesory podczas przetwarzania informacji.

Tak jak w przypadku krążków składających się na wieżę, w stosie dostępny jest tylko element znajdujący się na samym jego szczycie. Jedyną różnicą jest to, że elementy stosu mają postać ciągów zer i jedynek, a nie krążków. Procesory albo odkładają dane na szczyt stosu, albo pobierają ze stosu odłożone tam elementy.

Rozwiązanie rekurencyjne

Zapisany za pomocą pseudokodu algorytm wykorzystujący rekurencjęRekurencjarekurencję wygląda w następujący sposób:

Linia 1. funkcja wiezaHanoi otwórz nawias okrągły n przecinek A przecinek B przecinek C zamknij nawias okrągły. Linia 2. jeżeli n zamknij nawias ostrokątny 0 wykonaj dwukropek. Linia 3. wiezaHanoi otwórz nawias okrągły n minus 1 przecinek A przecinek C przecinek B zamknij nawias okrągły. Linia 4. wypisz dwukropek cudzysłów Przeniesienie z cudzysłów A cudzysłów do cudzysłów C. Linia 5. wiezaHanoi otwórz nawias okrągły n minus 1 przecinek B przecinek A przecinek C zamknij nawias okrągły.

Rekurencyjne rozwiązanie zagadki Wież Hanoi zawarte jest w trzech krokach:

  1. W trzeciej linii pseudokodu wywołujemy rekurencyjnie funkcję wiezaHanoi. Ta wywołana rekurencyjnie funkcja zrealizuje nam przeniesienie n - 1 górnych krążków ze słupka A na słupek B. Na słupku A pozostanie n-ty, największy krążek. Reszta krążków będzie nałożona na słupku B.

  2. W czwartej linii przenosimy n-ty krążek ze słupka A na słupek docelowy C.

  3. W piątej linii ponownie wywołujemy rekurencyjnie funkcję wiezaHanoi, aby przenieść n - 1 krążków ze słupka B na słupek C, na którym położony jest już największy krążek.

Ilustracja przedstawia kroki algorytmu rekurencyjnego dla sześciu krążków.

R1F5fvIlkOg35
Źródło: Contentplus.pl Sp. z o.o., licencja: CC BY-SA 3.0.

Złożoność obliczeniowa

Liczba przeniesień pojedynczego krążka, które należy wykonać, aby rozwiązać zagadkę Wież Hanoi wynosi:

2n  1

Na przykład dla trzech krążków liczba przeniesień wynosi:

23  1 = 8  1 = 7

Zatem złożoność obliczeniowa algorytmu rozwiązania problemu Wież Hanoi to:

O(2n)

Jest to złożoność wykładniczazłożoność wykładniczazłożoność wykładnicza, to znaczy rośnie bardzo szybko wraz ze wzrostem liczby krążków, czyli parametru wejściowego.

Słownik

funkcja rekurencyjna
funkcja rekurencyjna

funkcja, która wywołuje samą siebie aż do momentu osiągnięcia przypadku bazowego

iteracja
iteracja

słowo pochodzące od łacińskiego iteratio (powtarzanie); oznacza powtarzanie w pętli tych samych instrukcji, aż do spełnienia pewnego warunku

myślenie rekurencyjne
myślenie rekurencyjne

myślenie, które polega na tym, że wartość pewnej wielkości obliczana jest poprzez odwołanie się do wielkości określonych dla mniejszych wartości parametrów

przypadek bazowy
przypadek bazowy

warunek w funkcji rekurencyjnej, po spełnieniu którego funkcja nie wywołuje samej siebie po raz kolejny

przypadek rekurencyjny
przypadek rekurencyjny

warunek w funkcji rekurencyjnej, po spełnieniu którego funkcja ponownie wywołuje siebie samą

rekurencja
rekurencja

sytuacja, w której funkcja wywołuje samą siebie aż do napotkania przypadku podstawowego

stos
stos

struktura danych, w której informacje pobierane są z wierzchołka i odkładane na wierzchołek; struktura typu LIFO (Last In, First Out – ostatni na wejściu, pierwszy na wyjściu)

zagadka Wież Hanoi
zagadka Wież Hanoi

problem, polegający na przeniesieniu wieży z krążków z jednego słupka na drugi, przy czym można przenosić tylko po jednym krążku z wierzchu stosu; nie jest dozwolone położenie większego krążka na mniejszym

złożoność wykładnicza
złożoność wykładnicza

złożoność, która jest określona za pomocą funkcji wykładniczej, rośnie w zależności od rozmiaru danych wejściowych n