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.

  • ๐Ÿ—ผ Mรตistatuse seadistamine: Kolm pulka ja n ketast on kahaneva suurusega virnastatud lรคhtepulgale, oodates abipulga abil sihtpulgale liigutamist.
  • ๐Ÿ“œ Reeglid: Korraga liigub ainult รผks ketas, liikuda saab ainult iga pulga รผlemine ketas ja suurem ketas ei saa toetuda vรคiksemale kettale.
  • ๐Ÿ” Rekursiivne idee: Liiguta n-1 ketast abipulgale, liiguta suurim ketas sihtpulgale ja seejรคrel liiguta n-1 ketast abipulgalt sihtpunkti.
  • ๏ธ Aja keerukus: n ketta lahendamine nรตuab 2^n โ€“ 1 kรคiku, mis annab eksponentsiaalse O(2^n) ajalise keerukuse, mis kasvab n suurenedes vรคga kiiresti.
  • ๐Ÿง  Ruumi keerukus: Rekursioonipinu mahutab korraga kuni n kaadrit, seega on rekursiivse lahenduse ruumikeerukus O(n).
  • ๐Ÿ› ๏ธ Rakendused: Rekursiooni, varukoopiate rotatsiooniskeemide, pinupรตhise andmete liikumise, robootikapรตhise jรคrjestamise ja jaga-ja-valitse algoritmide disaini mรตistmise รตpetamine.

Hanoi torni algoritm

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

Hanoi torni probleem

Ja see ongi lรตppeesmรคrk:

Hanoi torn

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.

Lahenda Hanoi torni mรตistatus

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.

Lahenda Hanoi torni mรตistatus

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.

Lahenda Hanoi torni mรตistatus

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.

Lahenda Hanoi torni mรตistatus

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).

Lahenda Hanoi torni mรตistatus

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.

Lahenda Hanoi torni mรตistatus

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.

Lahenda Hanoi torni mรตistatus

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.

Lahenda Hanoi torni mรตistatus

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).

KKK

Hanoi torni algoritm on rekursiivne protseduur, mis liigutab n ketast lรคhte-pegist siht-pegile รผhe abipegi abil, asetades kunagi suuremat ketast vรคiksema peale.

n ketta minimaalne kรคikude arv on 2^n โ€“ 1. Kolme ketta puhul on vaja 7 kรคiku, nelja ketta puhul 15 ja kรผmne ketta puhul 1,023 kรคiku.

Ajaline keerukus on O(2^n), sest iga tรคiendav ketas kahekordistab tรถรถ. Rekursioon T(n) = 2T(n-1) + 1 laheneb vรครคrtuseks 2^n โ€“ 1, mis on eksponentsiaalne.

Ruumi keerukus on O(n), kuna rekursioonivรคljakutsete pinu mahutab iga tรถรถdeldava ketta kohta รผhe kaadri. Maksimaalne rekursioonisรผgavus ulatub n-ni, seega on vajalik lisamรคlu lineaarne ketaste arvuga.

Jah. Iteratiivne lahendus kasutab fikseeritud mustriga tsรผklit: paaritutel kรคikudel vahetatakse vรคikseim ketas tsรผkliliselt pulkade vahel ja paarisarvulistel kรคikudel tehakse ainus lubatud mittevรคikseim kรคik.

Algoritm รตpetab rekursiooni, modelleerib varundamise rotatsiooniskeeme salvestuseks, juhib robotkรคe jรคrjestamist ja esineb neuropsรผhholoogilistes testides, mis mรตรตdavad planeerimisvรตimet.

Tugevdusรตppe agendid lahendavad Hanoi torni probleemi, kรคsitledes iga ketta konfiguratsiooni olekuna ja iga liigutust toiminguna. See on levinud vรตrdlusalus planeerimiseks ja hierarhilise poliitika รตppimiseks.

Jah. GitHub Copilot, ChatGPT ja Gemini Hanoi torni rekursiivsete lahenduste genereerimine Python, C++ja JavaArendajad peaksid ikkagi kontrollima baasjuhtumeid ja argumentide jรคrjekorda.

Vรตta see postitus kokku jรคrgmiselt: