Algoritmus Hanojské věže: Python, C++ Kód

Co je Hanojská věž?

Hanojská věž je matematický hlavolam sestávající ze tří tyčí a mnoha disků umístěných přes sebe. Je také známá jako věž Brahma nebo Lucasova věž, jak ji představil francouzský matematik Edouard Lucas již v roce 1883. Tato hádanka je založena na legendách o pohybu zlatých kotoučů mezi třemi tyčemi.

Toto puzzle má tři tyče a proměnný počet naskládaných disků. Tyto tyče jsou navrženy jako cyklické věže. Takže větší disky o průměru jsou naskládány na spodní straně a menší disky jsou naskládány nahoře.

Zpočátku dostáváme tři kolíky nebo tyče. A jeden z nich (A, zobrazený v příkladu) má všechny disky naskládané. Naším cílem je přesunout celý stoh disků z jedné tyče (A) na druhou (C) při dodržení určitých specifických pravidel.

Zde je počáteční nastavení hádanky -

Problém Hanojské věže
Problém Hanojské věže

A to je konečný cíl -

Hanojské věže

Pravidla Hanojské věže

Zde jsou některá základní pravidla pro Hanojskou věž:

  • Počáteční stav této hádanky, všechny disky budou naskládány do tyče jedna.
  • Konečný stav je, že všechny disky z tyče jedna budou naskládány na tyč dvě nebo tyč tři.
  • Kdykoli můžeme přesunout na disk z jedné tyče na druhou.
  • Z tyče můžeme přesunout pouze nejhořejší kotouč.
  • Disk nelze umístit přes jiný disk, který je menší.

Původní legenda byla o přesunu 64 disků. Kněží mohli pohybovat po jednom disku podle pravidel. Podle legendy existovalo proroctví, že svět skončí, pokud se jim podaří tento čin dokončit. V sekci časové složitosti si ukážeme, že nastavení Hanojské věže na n disků by stálo 2^n – 1 tah.

Pokud by tedy kněží mohli vyžadovat 1 sekundu na přesunutí disků, celkový čas, který by potřebovali k vyřešení hádanky, by byl 2^64 – 1 sekunda nebo 584,942,417,356 26 7 15 let, XNUMX dní, XNUMX hodin a XNUMX sekund.

Algoritmus pro Hanojskou věž

Jedním z obecných způsobů, jak vyřešit Hanojskou věž, je rekurzivní algoritmus. Nejprve se musíme rozhodnout pro dva pruty nebo kolíky jako zdroj a cíl a náhradní kolík by byl pomocný nebo pomocník.

Zde jsou kroky k vyřešení hádanky Hanojské věže:

  • Přesuňte horních n-1 disků ze zdrojového pegu na pomocný kolík.
  • Poté přesuňte n-tý disk ze zdrojového pegu do cílového pegu.
  • Nakonec přesuňte zbývajících n-1 disků z pomocného pegu na cílový kolík.

Pozor: Pokud máme jeden disk, můžeme jej přímo přesunout ze zdroje do cíle.

Jak vyřešit hádanku Hanojská věž

Pojďme si ilustrovat algoritmus pro tři disky a uvažujme peg A jako zdroj, peg B jako pomocník a peg C jako cíl

Krok 1) Zpočátku budou všechny disky naskládány na kolík A.

Puzzle Vyřešte Hanojskou věž

V tomto stádiu:

Zdroj = Peg A
Cíl = Peg C
Pomocník = Peg B

Nyní potřebujeme přesunout horních n-1 disků ze zdroje do pomocníka.

Poznámka: Přestože můžeme přesunout pouze jeden disk najednou, přeruší to náš problém z problému se 3 disky na problém se 2 disky, což je rekurzivní volání.

Krok 2) Protože voláme rekurzivní volání z pegu A a cílem je peg B, použijeme peg C jako pomocníka.

Všimněte si, že jsme opět v první fázi stejného problému Hanojské věže pro dva disky.

Nyní potřebujeme přesunout n-1 nebo jeden disk ze zdroje na pomocníka a přesunout nejmenší disk z kolíku A na kolík C.

Puzzle Vyřešte Hanojskou věž

V tomto stádiu:

Zdroj = kolík A
Cíl = kolík B
Pomocník = kolík C

Krok 3) Potom by podle našeho algoritmu měly být potřeby n-tého nebo druhého disku přeneseny do cíle nebo kolíku B.

Puzzle Vyřešte Hanojskou věž

V tomto stádiu:

Zdroj = kolík A
Cíl = kolík B
Pomocník = kolík C

Krok 4) Nyní přesuneme n-1 disků nebo disk jeden z pomocníka nebo kolíku C do cíle nebo kolíku B podle třetí fáze našeho algoritmu.

Puzzle Vyřešte Hanojskou věž

V tomto stádiu:

Zdroj = kolík A
Cíl = kolík B
Pomocník = kolík C

Krok 5) Po dokončení rekurzivního volání se vrátíme k našemu předchozímu nastavení při první fázi algoritmu.

Krok 6) Nyní, ve druhé fázi, přesuneme náš zdroj do našeho cíle, což je přesun disku 3 na kolík C z kolíku A.

V tomto stádiu:

Zdroj = kolík A
Cíl = kolík C
Pomocník = kolík B

Krok 7) Nyní to můžeme vidět

Puzzle Vyřešte Hanojskou věž

d je přesunout zbývající disky z pomocného (peg B) do cíle (peg C). Jako pomocníka v tomto případě použijeme počáteční zdroj nebo peg A.

Krok 8) Protože nemůžeme přesunout dva disky současně, zavoláme rekurzivní volání pro disk 1. Podle posledního kroku a našeho algoritmus, cílem v tomto kroku je kolík A.

Puzzle Vyřešte Hanojskou věž

V tomto stádiu:

Zdroj = kolíček B
Cíl = kolík A
Pomocník = kolík C

Krok 9) Náš rekurzivní hovor je nyní dokončen. Poté přesuneme disk 2 ze zdroje na místo určení.

Puzzle Vyřešte Hanojskou věž

V tomto stádiu:

Zdroj = kolíček B
Cíl = kolík C
Pomocník = kolík A

Krok 10) Potom přesuneme naše zbývající n-1 nebo disk 1 z pomocníka do cíle.

Puzzle Vyřešte Hanojskou věž

V tomto stádiu:

Zdroj = kolík A
Cíl = kolík C
Pomocník = kolík B

Pseudokód pro Hanojskou věž

START
Procedure Tower_Of_Hanoi(disk, source, dest, helper)
  		IF disk == 1, THEN
      			move disk from source to dest             
   		ELSE
     			Tower_Of_Hanoi (disk - 1, source, helper, dest)     
      			move disk from source to dest          
      			Tower_Of_Hanoi (disk - 1, helper, dest, source)     
   		END IF   
END Procedure

Kód programu v C++

#include <bits/stdc++.h>
using namespace std;
void tower_of_hanoi(int num, string source, string dest, string helper) {
  if (num == 1) {
    cout << " Move disk 1 from tower " << source << " to tower " << dest << endl;
    return;
  }
  tower_of_hanoi(num - 1, source, helper, dest);
  cout << " Move disk " << num << " from tower " << source << " to tower " << dest << endl;
  tower_of_hanoi(num - 1, helper, dest, source);
}
int main() {
  int num;
  cin >> num;
  printf("The sequence of moves :\n");
  tower_of_hanoi(num, "I", "III", "II");
  return 0;
}

Výstup

3
The sequence of moves :
Move disk 1 from tower I to tower III
Move disk 2 from tower I to tower II
Move disk 1 from tower III to tower II
Move disk 3 from tower I to tower III
Move disk 1 from tower II to tower I
Move disk 2 from tower II to tower III
Move disk 1 from tower I to tower III

Kód programu v Python

def tower_of_hanoi(n, source, destination, helper):
	if n==1:
		print ("Move disk 1 from peg", source," to peg", destination)
		return
	tower_of_hanoi(n-1, source, helper, destination)
	print ("Move disk",n," from peg", source," to peg", destination)
	tower_of_hanoi(n-1, helper, destination, source)		
# n = number of disks
n = 3
tower_of_hanoi(n,' A','B','C')

Výstup:

Move disk 1 from peg A to peg B
Move disk 2 from peg A to peg C
Move disk 1 from peg B to peg C
Move disk 3 from peg A to peg B
Move disk 1 from peg C to peg A
Move disk 2 from peg C to peg B
Move disk 1 from peg A to peg B

Složitost věže Hanoi

Zde je časová a prostorová složitost Hanojské věže:

1) Časová složitost:

Když se podíváme zpět na náš algoritmus, můžeme vidět, že zavádíme rekurzivní volání pro (n-1) disky dvakrát. Tato rekurzivní volání (n-1) disků lze rozdělit na další ((n-1)-1) a tak dále, dokud nedostaneme k pohybu pouze jeden disk.

Na tři disky -

  • Disk 3 volá rekurzivní funkci pro disk dva dvakrát.
  • Disk 2 volá rekurzivní funkci pro disk jedna dvakrát.
  • Disk 1 se může pohybovat v rámci konstantního času a času pro tři disky.

= 2*(Čas na řešení pro dva disky) + konstanta Čas na přesunutí disku 3

= 2*(2*čas na vyřešení pro jeden disk + konstanta Čas na přesunutí disku 2) + konstanta Čas na přesunutí disku 3

= (2*2) (konstantní čas pro přesun disku 1) + 2*konstantní čas pro přesun disku 2 + konstantní čas pro přesun disku 3

Pro n disků to lze zapsat jako –

(2n-1 * konstantní čas na pohyb disku 1 + 2n-2 * konstantní čas pro pohyb disku 2 + ….

Výsledkem tohoto geometrického postupu bude O(2n-1), Nebo O(2n), který je exponenciální.

2) Prostorová složitost

Prostorová složitost Hanojské věže je 0(n). Je to proto, že musíme uložit pořadí desek. Když používáme rekurzi, používá zásobník. A maximální velikost zásobníku může být „n“. Proto se prostorová složitost stává O(n).