Hanoi torni algoritm: Python, C++ Code
โก Nutikas kokkuvรตte
Hanoi torni algoritm on klassikaline rekursiivne mรตistatus, mis liigutab kettavirna kolme pulga vahel, asetamata kunagi suuremat ketast vรคiksema peale, illustreerides selgelt jaga-ja-valitse-pรตhimรตtteid.

Mis on Hanoi torn?
Hanoi torn on matemaatiline pusle, mis koosneb kolmest vardast ja รผksteise peale asetatud vรคheneva suurusega ketaste virnast. Seda tuntakse ka Brahma torni vรตi Lucase tornina, kuna prantsuse matemaatik Edouard Lucas tutvustas seda 1883. aastal. Pusle pรตhineb legendidel kuldketaste liigutamisest kolme varda vahel.
Sellel puslel on kolm varrast ja muutuv arv virnastatud kettaid. Vardad on paigutatud tsรผkliliste tornidena, nii et suuremad kettad on virnastatud alla ja vรคiksemad kettad peale.
Alguses on meile antud kolm pulka vรตi varrast. รhele neist (nรคites pulk A) on kรตik kettad virnastatud. Eesmรคrk on liigutada kogu virn รผhelt vardast (A) teisele (C), jรคrgides samal ajal mรตnda kindlat reeglit.
Siin on pusle esialgne รผlesehitus:
Hanoi torni probleem
Ja see ongi lรตppeesmรคrk:
Hanoi torni reeglid
Siin on Hanoi torni peamised reeglid:
- Pusle algseisus on kรตik kettad virnastatud รผhele vardale.
- Lรตppseisundis on kรตik esimese varda kettad virnastatud teisele vรตi kolmandale vardale.
- Igal ajahetkel saab รผhelt vardast teisele liikuda ainult รผks ketas.
- Liigutada saab ainult varda kรตige รผlemist ketast.
- Ketast ei saa vรคiksema ketta peale asetada.
Algupรคrane legend rรครคkis 64 ketta liigutamisest. Preestrid said reeglite kohaselt korraga รผhte ketast liigutada. Legendi jรคrgi oli ennustus, et kui nad suudavad selle teo lรตpule viia, tuleb maailmalรตpp. Aja keerukuse osas nรคitame, et n kettaga Hanoi torni seadistamine nรตuab 2^n โ 1 kรคiku.
Seega, kui preestritel kuluks รผhe ketta liigutamiseks 1 sekund, oleks mรตistatuse lahendamise koguaeg 2^64 โ 1 sekundit ehk umbes 584 942 417 356 aastat, 26 pรคeva, 7 tundi ja 15 sekundit.
Hanoi torni algoritm
Hanoi torni lahendamiseks kasutatakse kรตige levinumat rekursiivset algoritmi. Esmalt valime allikaks ja sihtkohaks kaks varrast; varutihvt toimib abivartena.
Siin on sammud Hanoi torni mรตistatuse lahendamiseks:
- Liigutage รผlemised n-1 kettad lรคhtepulgalt abipulgale.
- Liiguta n-ndat ketast lรคhtepulgalt sihtpulgale.
- Liiguta รผlejรครคnud n-1 ketast abipulgalt sihtpulgale.
Mรคrge: Kui meil on รผks ketas, saame selle otse allikast sihtkohta teisaldada.
Kuidas lahendada Hanoi torni mรตistatus
Illustreerime algoritmi kolme ketta jaoks. Vaatleme pulka A allikana, pulka B abikettana ja pulka C sihtkettana.
Step 1) Algselt on kรตik kettad virnastatud pulgale A.
Selles etapis: Allikas = pulk A, Sihtkoht = pulk C, Abiline = pulk B.
Nรผรผd peame รผlemised n-1 kettad allikast abistajasse teisaldama.
Mรคrge: Kuigi korraga saab liigutada ainult รผhte ketast, taandab see samm meie 3 ketta probleemi 2 ketta probleemiks, mida kรคsitletakse rekursiivse kutse abil.
Step 2) Kuna me teeme rekursiivse kutse pesast A, kus sihtkohaks on pesa B, siis kasutame abimehena pesa C.
Pane tรคhele, et oleme tagasi sama Hanoi torni probleemi esimeses etapis, aga nรผรผd kahe kettaga. Liigutame n-1 (st รผhe) ketta lรคhtekettalt abikettale, mis omakorda liigutab vรคikseima ketta pulgalt A pulgale C.
Selles etapis: Allikas = pulk A, Sihtkoht = pulk B, Abimees = pulk C.
Step 3) Algoritmi kohaselt teisaldatakse n-s (teine) ketas nรผรผd sihtkohta, pulka B.
Selles etapis: Allikas = pulk A, Sihtkoht = pulk B, Abimees = pulk C.
Step 4) Nรผรผd liigutame n-1 ketta (ketas รผks) abipulgalt C sihtpulgale B, jรคrgides algoritmi kolmandat etappi.
Selles etapis: Allikas = pulk A, Sihtkoht = pulk B, Abimees = pulk C.
Step 5) Pรคrast rekursiivse kutse lรตpetamist naaseme algoritmi esimeses etapis eelmisele seadistusele.
Step 6) Teises etapis liigutame ketta 3 lรคhtepulgalt A sihtpulgale C.
Selles etapis: Allikas = pulk A, Sihtkoht = pulk C, Abimees = pulk B
Step 7) Jรคrgmine รผlesanne on รผlejรครคnud kettad abikettalt (peg B) sihtkohta (peg C) teisaldada. Seekord kasutame abikettana algset allikat (peg A).
Step 8) Kuna me ei saa kahte ketast korraga liigutada, teeme kettale 1 rekursiivse pรคringu. Meie andmete kohaselt algoritm, on selle sammu sihtkohaks pulk A.
Selles etapis: Allikas = pulk B, Sihtkoht = pulk A, Abimees = pulk C.
Step 9) Meie rekursiivne kutse on lรตppenud. Nรผรผd liigutame ketta 2 lรคhtest sihtkohta.
Selles etapis: Allikas = pulk B, Sihtkoht = pulk C, Abimees = pulk A.
Step 10) Lรตpetuseks liigutame รผlejรครคnud n-1 ketta (ketas 1) abikettast sihtkohta.
Selles etapis: Allikas = pulk A, Sihtkoht = pulk C, Abimees = pulk B
Pseudo Code Hanoi torni jaoks
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
Programmi kood sisse 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รคljund:
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
Programmi kood sisse 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รคljund:
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
Hanoi torni keerukus
Siin on Hanoi torni aja ja ruumi keerukus:
1) Aja keerukus:
Algoritmile tagasi vaadates teeme (n-1) kettale rekursiivse vรคljakutse kaks korda iga vรคljakutse jooksul. Iga (n-1) rekursioon jaguneb ((n-1)-1) rekursiooniks ja nii edasi, kuni jรตuame รผhe ketta baasjuhtumini.
Kolme ketta puhul:
- Ketas 3 kutsub ketta 2 rekursiivset funktsiooni kaks korda.
- Ketas 2 kutsub ketta 1 rekursiivset funktsiooni kaks korda.
- Ketas 1 liigub konstantse aja jooksul, andes aega kolme ketta lahendamiseks.
Vรคljendatud korduvusena:
= 2 ร (kahe ketta lahendamise aeg) + ketta 3 liigutamiseks kuluv konstantne aeg
= 2 ร (2 ร รผhe ketta lahendamise aeg + ketta 2 liigutamise konstantne aeg) + ketta 3 liigutamise konstantne aeg
= (2 ร 2) ร ketta 1 liigutamise konstantne aeg + 2 ร ketta 2 liigutamise konstantne aeg + ketta 3 liigutamise konstantne aeg
n ketta puhul saab sellest jรคrgmine tulemus:
2n-1 ร ketta 1 + 2 liigutamiseks kuluv konstantne aegn-2 ร ketta 2 liigutamise konstantne aeg + โฆ.
See geomeetriline progressioon summastub O(2n โ 1), mis lihtsustub kujule O(2n), eksponentsiaalne ajaline keerukus.
2) Ruumi keerukus:
Hanoi torni ruumikeerukus on O(n). Rekursioon kasutab vรคljakutsete pinu ja pinu maksimaalne sรผgavus vรตrdub n-ga ehk ketaste arvuga. Seetรตttu on ruumikeerukus O(n).










