Algoritmul Turnului Hanoi: Python, C++ Cod

Ce este Turnul din Hanoi?

Turnul din Hanoi este un puzzle matematic format din trei tije ศ™i numeroase discuri aศ™ezate una peste alta. Este cunoscut ศ™i sub numele de Turnul lui Brahma sau turnul Lucas, aศ™a cum l-a introdus matematicianul francez Edouard Lucas รฎn 1883. Acest puzzle se bazeazฤƒ pe legende despre miศ™carea discurilor de aur รฎntre trei tije.

Acest puzzle are trei tije ศ™i un numฤƒr variabil de discuri stivuite. Aceste tije sunt proiectate ca turnuri ciclice. Deci, discurile mai mari รฎn diametru sunt stivuite รฎn partea de jos, iar discurile mai mici sunt stivuite deasupra.

Iniศ›ial, ni se dau trei cuie sau tije. ศ˜i unul dintre ele (A, prezentat รฎn exemplu) are toate discurile stivuite. Ne propunem sฤƒ mutฤƒm un รฎntreg teanc de discuri de la o tijฤƒ (A) la alta (C) respectรขnd niศ™te reguli specifice.

Iatฤƒ configuraศ›ia iniศ›ialฤƒ a puzzle-ului -

Problema Turnului din Hanoi
Problema Turnului din Hanoi

ศ˜i acesta este scopul final -

Turnul din Hanoi

Regulile Turnului din Hanoi

Iatฤƒ cรขteva reguli esenศ›iale pentru Turnul din Hanoi:

  • Starea iniศ›ialฤƒ a acestui puzzle, toate discurile vor fi stivuite รฎntr-o tijฤƒ.
  • Starea finalฤƒ este cฤƒ toate acele discuri de la tija unu vor fi stivuite pe tija douฤƒ sau tija trei.
  • Putem muta un disc de pe o tijฤƒ la alta รฎn orice moment.
  • Putem muta doar discul de sus de pe tijฤƒ.
  • Un disc nu poate fi plasat peste un alt disc, care este mai mic.

Legenda originalฤƒ era despre mutarea a 64 de discuri. Preoศ›ii puteau muta cรขte un disc, conform regulilor. Potrivit legendei, a existat o profeศ›ie conform cฤƒreia lumea se va sfรขrศ™i dacฤƒ ar putea duce la bun sfรขrศ™it actul. รŽn secศ›iunea de complexitate a timpului, vom arฤƒta cฤƒ o setare a Turnului din Hanoi de n discuri ar costa 2^n โ€“ 1 miศ™care.

Deci, dacฤƒ preoศ›ii ar putea avea nevoie de 1 secundฤƒ pentru a muta discurile, timpul total de care ar avea nevoie pentru a rezolva puzzle-ul ar fi de 2^64 โ€“ 1 secundฤƒ sau 584,942,417,356 de ani, 26 de zile, 7 ore ศ™i 15 secunde.

Algoritm pentru Turnul din Hanoi

O modalitate generalฤƒ de a rezolva Turnul din Hanoi este un algoritm recursiv. รŽn primul rรขnd, trebuie sฤƒ decidem asupra a douฤƒ tije sau cuie ca sursฤƒ ศ™i destinaศ›ie, iar cuiul de rezervฤƒ ar fi un auxiliar sau un ajutor.

Iatฤƒ paศ™ii pentru a rezolva puzzle-ul Turnul din Hanoi:

  • Mutaศ›i discurile superioare n-1 de la suportul sursฤƒ la suportul de ajutor.
  • Dupฤƒ aceea, mutaศ›i al n-lea disc de la peg-ul sursฤƒ la cel de destinaศ›ie.
  • รŽn cele din urmฤƒ, mutaศ›i restul n-1 discuri de pe piciorul de ajutor pe piciorul de destinaศ›ie.

notiศ›e: Dacฤƒ avem un singur disc, รฎl putem muta direct de la sursฤƒ la destinaศ›ie.

Cum sฤƒ rezolvi puzzle-ul Turnul din Hanoi

Sฤƒ ilustrฤƒm algoritmul pentru trei discuri ศ™i sฤƒ considerฤƒm peg A ca sursฤƒ, peg B ca ajutor ศ™i peg C ca destinaศ›ie

Pas 1) Iniศ›ial, toate discurile vor fi stivuite pe suportul A.

Rezolva puzzle turnul din Hanoi

รŽn aceastฤƒ etapฤƒ:

Sursa = Peg A
Destinaศ›ie = Peg C
Ajutor = Peg B

Acum, trebuie sฤƒ mutฤƒm discurile de sus n-1 de la sursฤƒ la helper.

Notฤƒ: Deศ™i putem muta doar un disc la un moment dat, problema noastrฤƒ trece de la o problemฤƒ de 3 discuri la o problemฤƒ de 2 discuri, care este un apel recursiv.

Pas 2) Pe mฤƒsurฤƒ ce numim un apel recursiv de la peg A ศ™i destinaศ›ia este peg B, vom folosi peg C ca ajutor.

Observaศ›i cฤƒ suntem din nou la prima etapฤƒ pentru aceeaศ™i problemฤƒ a turnului din Hanoi pentru douฤƒ discuri.

Acum trebuie sฤƒ mutฤƒm n-1 sau un disc de la sursฤƒ la helper, mutรขnd cel mai mic disc de la peg A la peg C.

Rezolva puzzle turnul din Hanoi

รŽn aceastฤƒ etapฤƒ:

Sursa = peg A
Destinaศ›ie = peg B
Ajutor = pion C

Pas 3) Apoi, conform algoritmului nostru, al n-lea sau al doilea disc trebuie transferat รฎn destinaศ›ia sau peg-ul B.

Rezolva puzzle turnul din Hanoi

รŽn aceastฤƒ etapฤƒ:

Sursa = peg A
Destinaศ›ie = peg B
Ajutor = pion C

Pas 4) Acum, vom muta discurile n-1 sau discul unul de la helper sau peg C la destinaศ›ie sau peg B conform celei de-a treia etape a algoritmului nostru.

Rezolva puzzle turnul din Hanoi

รŽn aceastฤƒ etapฤƒ:

Sursa = peg A
Destinaศ›ie = peg B
Ajutor = pion C

Pas 5) Dupฤƒ finalizarea apelului recursiv, vom reveni la setarea anterioarฤƒ la prima etapฤƒ a algoritmului.

Pas 6) Acum, รฎn a doua etapฤƒ, ne vom muta sursa la destinaศ›ia noastrฤƒ, care este mutarea discului 3 la pionul C de la pilonul A.

รŽn aceastฤƒ etapฤƒ:

Sursa = peg A
Destinaศ›ie = peg C
Ajutor = chela B

Pas 7) Acum putem vedea asta

Rezolva puzzle turnul din Hanoi

d este de a muta discurile rฤƒmase de la helper (peg B) la destinaศ›ie (peg C). Vom folosi sursa iniศ›ialฤƒ sau peg A ca ajutor รฎn acest caz.

Pas 8) Deoarece nu putem muta douฤƒ discuri simultan, vom apela un apel recursiv pentru discul 1. Conform ultimului pas ศ™i a noastrฤƒ Algoritmul, o destinaศ›ie รฎn acest pas este chela A.

Rezolva puzzle turnul din Hanoi

รŽn aceastฤƒ etapฤƒ:

Sursa = peg B
Destinaศ›ie = peg A
Ajutor = pion C

Pas 9) Apelul nostru recursiv este finalizat acum. Apoi mutฤƒm discul 2 de la sursฤƒ la destinaศ›ie.

Rezolva puzzle turnul din Hanoi

รŽn aceastฤƒ etapฤƒ:

Sursa = peg B
Destinaศ›ie = peg C
Ajutor = chel A

Pas 10) Apoi mutฤƒm n-1 sau discul 1 rฤƒmas de la helper la destinaศ›ie.

Rezolva puzzle turnul din Hanoi

รŽn aceastฤƒ etapฤƒ:

Sursa = peg A
Destinaศ›ie = peg C
Ajutor = chela B

Pseudocod pentru Turnul din Hanoi

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

Codul programului รฎn 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;
}

producศ›ie

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

Codul programului รฎn 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')

ieศ™ire:

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

Complexitatea Turnului din Hanoi

Iatฤƒ complexitatea รฎn timp ศ™i spaศ›iu a Turnului din Hanoi:

1) Complexitatea timpului:

Dacฤƒ ne uitฤƒm รฎnapoi la algoritmul nostru, putem vedea cฤƒ introducem un apel recursiv pentru (n-1) discuri de douฤƒ ori. Acele apeluri recursive pentru (n-1) discuri pot fi รฎmpฤƒrศ›ite รฎn alte ((n-1)-1) ศ™i aศ™a mai departe pรขnฤƒ cรขnd obศ›inem un singur disc de mutat.

Pentru trei discuri-

  • Discul 3 apeleazฤƒ de douฤƒ ori o funcศ›ie recursivฤƒ pentru discul doi.
  • Discul 2 apeleazฤƒ de douฤƒ ori o funcศ›ie recursivฤƒ pentru disc.
  • Discul 1 se poate miศ™ca รฎntr-un timp constant ศ™i timp de rezolvat pentru trei discuri.

= 2*(Timp de rezolvare pentru douฤƒ discuri) + constant Timp de mutare a discului 3

= 2*(2*timp de rezolvare pentru un disc + constantฤƒ de timp pentru a muta discul 2) + constantฤƒ de timp pentru a muta discul 3

= (2*2) (timp constant pentru mutarea discului 1) + 2*timp constant pentru mutarea discului 2 + timp constant pentru mutarea discului 3

Pentru n discuri, poate fi scris ca โ€“

(2n-1 * timp constant pentru a muta discul 1 + 2n-2 * timp constant pentru a muta discul 2 + ....

Aceastฤƒ progresie geometricฤƒ va avea ca rezultat O(2n-1) Sau O(2n), care este exponenลฃial.

2) Complexitatea spaศ›iului

Complexitatea spaศ›ialฤƒ a Turnului din Hanoi este 0(n). Asta pentru cฤƒ trebuie sฤƒ stocฤƒm secvenศ›a plฤƒcilor. Cรขnd folosim recursiunea, aceasta foloseศ™te stiva. ศ˜i dimensiunea maximฤƒ a stivei poate fi โ€žnโ€. De aceea complexitatea spaศ›iului devine O(n).

Rezumaศ›i aceastฤƒ postare cu: