Our 3D CAD supplier models have been moved to 3Dfindit.com, the new visual search engine for 3D CAD, CAE & BIM models.
You can log in there with your existing account of this site.
The content remains free of charge.
Licensed under Creative Commons Attribution-Share Alike 2.5 (André Karwath aka Aka).
Wieże Hanoi – problem polegający na odbudowaniu, z zachowaniem kształtu, wieży z krążków o różnych średnicach (popularna dziecięca zabawka), przy czym podczas przekładania wolno się posługiwać buforem (reprezentowanym w tym przypadku przez dodatkowy słupek), jednak przy ogólnym założeniu, że nie wolno kłaść krążka o większej średnicy na mniejszy ani przekładać kilku krążków jednocześnie. Jest to przykład zadania, którego złożoność obliczeniowa wzrasta niezwykle szybko w miarę zwiększania parametru wejściowego, tj. liczby elementów wieży.
Zagadka Wież Hanoi powstała prawdopodobnie w Azji Wschodniej w XIX wieku lub wcześniej. Krążki były ceramiczne, produkowane w Chinach, Japonii i Wietnamie. Gra ta została sprowadzona na Zachód po raz pierwszy przez francuskiego matematyka Édouarda Lucasa w 1883 roku. Do sprzedawanego zestawu dołączona była tybetańska legenda, według której mnisi w świątyni Brahmy rozwiązują tę łamigłówkę dla 64 złotych krążków. Legenda mówi, że gdy mnisi zakończą zadanie, nastąpi koniec świata. Zakładając, że wykonują 1 ruch na sekundę, ułożenie wieży zajmie 264−1 = 18 446 744 073 709 551 615 (blisko 18 i pół tryliona) sekund, czyli około 584 miliardów lat. Dla porównania: Wszechświat ma około 13,7 mld lat.
Wieże Hanoi można łatwo rozwiązać za pomocą prostego algorytmu rekurencyjnego lub iteracyjnego.
Algorytm rekurencyjny składa się z następujących kroków:
Przykładowe implementacje
def hanoi(n, A, B, C):
"""słupki A, B, C są listami"""
if n > 0:
hanoi(n-1, A, C, B)
C.insert(0, A.pop(0))
hanoi(n-1, B, A, C)
defmodule Hanoi do
# Jeśli brak krążków -> wszystko ok, nic nie trzeba robić
def hanoi(0,_,_,_), do: :ok
# Jeśli jeden krążek -> przełożyć na docelowy słupek
def hanoi(1,a,_,c) do
IO.puts "#{a}->#{c}"
end
# Więcej niż jeden -> rozwiąż rekurencyjnie
def hanoi(n,a,b,c) do
hanoi(n-1,a,c,b)
hanoi(1,a,b,c)
hanoi(n-1,b,a,c)
end
end
#include <iostream>
using namespace std;
void hanoi(int n, char A, char B, char C)
{
// przekłada n krążków z A korzystając z B na C
if (n > 0)
{
hanoi(n-1, A, C, B);
cout << A << " -> " << C << endl;
hanoi(n-1, B, A, C);
}
}
int main(int argc, char *argv[])
{
hanoi(3, 'A', 'B', 'C');
return 0;
}
using System;
namespace Hanoi
{
public class WiezeHanoi
{
// przekłada n krążków z A, korzystając z B, na C
static void Hanoi(int n, char A, char B, char C)
{
if(n > 0)
{
Hanoi(n - 1, A, C, B);
Console.WriteLine("\t{0} -> {1}", A, C);
Hanoi(n - 1, B, A, C);
}
}
static void Main()
{
Console.WriteLine("Wieże Hanoi\n");
Console.WriteLine("Algorytm przełożenia trzech krążków z wieży A na wieżę C z wykorzystaniem wieży B\n");
Hanoi(3, 'A', 'B', 'C');
Console.WriteLine("Naciśnij dowolny klawisz...");
Console.ReadKey();
}
}
}
Algorytm rozwiązywania wież Hanoi jest klasycznym przykładem algorytmu rekurencyjnego używanego w nauczaniu informatyki.
Algorytm iteracyjny składa się z następujących kroków:
(*) Kolejny słupek wyznaczamy w zależności od liczby krążków. Jeśli liczba krążków jest parzysta, kolejnym słupkiem jest ten po prawej stronie (gdy dojdziemy do słupka C w następnym ruchu używamy słupka A). Natomiast jeśli liczba krążków jest nieparzysta, kolejnym słupkiem jest ten po lewej stronie (gdy dojdziemy do słupka A w następnym ruchu używamy słupka C)
Równanie określające liczbę ruchów potrzebnych do rozwiązania problemu wież Hanoi dla n krążków:
Łatwo pokazać, że :
a więc .
Aby wykazać, że można przeprowadzić następujące rozumowanie:
Aby móc ruszyć n-ty krążek, trzeba najpierw zdjąć wszystkie leżące na nim krążki, tak by po ich zdjęciu jeden z słupków pozostał wolny (aby na jego "dno" mógł trafić n-ty krążek). A więc ze słupka 1 przekładamy krążki na słupek 3. Ponieważ aż do momentu gdy na drążku 1 pozostanie tylko n-ty krążek nie ma znaczenia czy rzeczywiście się on tam znajduje, a więc do tego momentu sytuacja upraszcza się do rozwiązania problemu wież Hanoi dla n-1 krążków (którego minimalna liczba ruchów wynosi L(n-1)). Na przełożenie krążka n-tego potrzeba co najmniej jeden ruch. Po jego przełożeniu znów potrzeba przełożyć krążki
- jest to oczywiście znów sytuacja n-1 krążków (wymagająca co najmniej L(n-1) ruchów).
A więc
co w połączeniu z górnym ograniczeniem na L(n) daje równość
Powyższe równanie rekurencyjne można w łatwy sposób przekształcić do postaci jawnej, tj. nie korzystającej z rekursji:
Niech
Wtedy
jest to równanie określające ciąg geometryczny o ilorazie równym 2 takie, że
Po powrocie do otrzymujemy
Mimo swojego wieku łamigłówka jest stale tematem prac matematyków i znane są jej bardziej rozbudowane wersje np. z więcej niż trzema słupkami.
W psychologii łamigłówka ta jest jednym z testów na kojarzenie.
W Wikimedia Commons znajdują się multimedia związane z tematem: Wieże Hanoi |
This article uses material from the Wikipedia article "Wieże Hanoi", which is released under the Creative Commons Attribution-Share-Alike License 3.0. There is a list of all authors in Wikipedia
3d,model,playground,board games,computer,strategy,thinktank