Tower of Hanoi Algoritm: Python, C++ Code

⚡ Smart sammanfattning

Hanoi-tornets algoritm är ett klassiskt rekursivt pussel som flyttar en stapel skivor mellan tre pinnar utan att placera en större skiva ovanpå en mindre, vilket tydligt illustrerar dela-och-härska-metoden.

  • 🗼 Pusseluppsättning: Tre pinnar och n skivor staplade i minskande storlek på källpinnen, i väntan på att flyttas till destinationspinnen via en hjälppinn.
  • 📜 regler: Endast en skiva rör sig åt gången, endast den översta skivan på en pinne kan röra sig, och en större skiva kan inte vila på en mindre skiva.
  • 🔁 Rekursiv idé: Flytta n-1 diskar till hjälppinnen, flytta den största disken till destinationspinnen och flytta sedan de n-1 diskarna från hjälppinnen till destinationen.
  • ⏱️ Tidskomplexitet: Att lösa n diskar kräver 2^n – 1 drag, vilket ger en exponentiell O(2^n) tidskomplexitet som växer mycket snabbt när n ökar.
  • 🧠 Rymdkomplexitet: Rekursionsstacken rymmer upp till n ramar samtidigt, så den rekursiva lösningens rymdkomplexitet är O(n).
  • 🛠️ Program: Undervisning i rekursion, rotationsscheman för säkerhetskopiering, stackbaserad dataförflyttning, robotsekvensering och förståelse för design av söndra-och-härska-algoritmer.

Hanoi-tornets algoritm

Vad är Tower of Hanoi?

Hanois torn är ett matematiskt pussel som består av tre stavar och en stapel skivor av minskande storlek placerade ovanpå varandra. Det är också känt som Brahmas torn eller Lucas-tornet, eftersom den franske matematikern Edouard Lucas introducerade det 1883. Pusslet är baserat på legender om att flytta guldskivor mellan tre stavar.

Detta pussel har tre stavar och ett variabelt antal staplade skivor. Stavarna är arrangerade som cykliska torn, så de större skivorna är staplade längst ner och de mindre skivorna är staplade ovanpå.

Inledningsvis får vi tre pinnar eller stavar. En av dem (pinne A i exemplet) har alla skivor staplade. Målet är att flytta hela stapeln från en stav (A) till en annan (C) samtidigt som man följer några specifika regler.

Här är den ursprungliga uppställningen av pusslet:

Tornet i Hanoi problem

Tornet i Hanoi problem

Och detta är det slutgiltiga målet:

Tower of Hanoi

Regler för Tower of Hanoi

Här är de viktigaste reglerna för Hanois torn:

  • I pusslets initiala tillstånd är alla skivor staplade på stång ett.
  • I sluttillståndet staplas alla skivor från stång ett på stång två eller stång tre.
  • Endast en skiva kan röra sig från en stång till en annan åt gången.
  • Endast den översta skivan på en stång kan flyttas.
  • En disk kan inte placeras ovanpå en mindre disk.

Den ursprungliga legenden handlade om att flytta 64 skivor. Prästerna kunde flytta en skiva i taget enligt reglerna. Enligt legenden fanns det en profetia om att världen skulle gå under om de kunde slutföra handlingen. I avsnittet om tidskomplexitet kommer vi att visa att en Hanoi-tornuppsättning med n skivor kräver 2^n – 1 drag.

Så, om prästerna behövde 1 sekund för att flytta en disk, skulle den totala tiden för att lösa pusslet vara 2^64 – 1 sekund, eller ungefär 584 942 417 356 år, 26 dagar, 7 timmar och 15 sekunder.

Algoritm för Tower of Hanoi

Det vanligaste sättet att lösa Hanoi-tornet är en rekursiv algoritm. Först väljer vi två stavar som källa och destination; reservpinnen fungerar som hjälppinne eller hjälptång.

Här är stegen för att lösa Tower of Hanoi-pusslet:

  • Flytta de översta n-1-skivorna från källpinnen till hjälppinnen.
  • Flytta den n:te disken från källpinnen till destinationspinnen.
  • Flytta de återstående n-1 diskarna från hjälppinnen till destinationspinnen.

Obs: Om vi ​​har en enda disk kan vi flytta den direkt från källan till destinationen.

Hur man löser Tower of Hanoi Puzzle

Låt oss illustrera algoritmen för tre skivor. Betrakta peg A som källa, peg B som hjälp och peg C som destination.

Steg 1) Ursprungligen staplas alla skivor på pinne A.

Lös Tower of Hanoi Puzzle

I detta skede: Källa = Peg A, Destination = Peg C, Hjälpare = Peg B.

Nu måste vi flytta de översta n-1-skivorna från källan till hjälparen.

Obs: Även om vi bara kan flytta en disk åt gången, reducerar detta steg vårt 3-diskproblem till ett 2-diskproblem, vilket hanteras av ett rekursivt anrop.

Steg 2) När vi gör ett rekursivt anrop från peg A med peg B som destination, använder vi peg C som hjälpare.

Observera att vi är tillbaka på steg ett för samma problem med Hanoi-tornet, men nu för två skivor. Vi flyttar n-1 (det vill säga en) skiva från källan till hjälpskivan, vilket flyttar den minsta skivan från pinne A till pinne C.

Lös Tower of Hanoi Puzzle

I detta skede: Källa = peg A, Destination = peg B, Hjälpare = peg C.

Steg 3) Enligt algoritmen överförs nu den n:te (2:a) disken till destinationen, peg B.

Lös Tower of Hanoi Puzzle

I detta skede: Källa = peg A, Destination = peg B, Hjälpare = peg C.

Steg 4) Nu flyttar vi n-1-disken (disk ett) från hjälppinne C till destinationspinne B, enligt algoritmens tredje steg.

Lös Tower of Hanoi Puzzle

I detta skede: Källa = peg A, Destination = peg B, Hjälpare = peg C.

Steg 5) Efter att ha slutfört det rekursiva anropet återgår vi till vår tidigare inställning i algoritmens första steg.

Steg 6) I det andra steget flyttar vi disk 3 från källpinne A till destinationspinne C.

I detta skede: Källa = peg A, Destination = peg C, Hjälpare = peg B.

Steg 7) Nästa uppgift är att flytta de återstående diskarna från hjälpen (peg B) till destinationen (peg C). Vi kommer att använda den ursprungliga källan (peg A) som hjälp den här gången.

Lös Tower of Hanoi Puzzle

Steg 8) Eftersom vi inte kan flytta två diskar samtidigt gör vi ett rekursivt anrop för disk 1. Enligt vår algoritm, destinationen i detta steg är peg A.

Lös Tower of Hanoi Puzzle

I detta skede: Källa = peg B, Destination = peg A, Hjälpare = peg C.

Steg 9) Vårt rekursiva anrop är slutfört. Vi flyttar nu disk 2 från dess källa till dess destination.

Lös Tower of Hanoi Puzzle

I detta skede: Källa = peg B, Destination = peg C, Hjälpare = peg A.

Steg 10) Vi avslutar med att flytta den återstående n-1 disken (disk 1) från hjälparen till destinationen.

Lös Tower of Hanoi Puzzle

I detta skede: Källa = peg A, Destination = peg C, Hjälpare = peg B.

Pseudo Code för Hanois torn

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

Programkod in 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;
}

Produktion:

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

Programkod in 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')

Produktion:

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

Komplexiteten av Tower of Hanoi

Här är tids- och rumskomplexiteten i Hanois torn:

1) Tidskomplexitet:

Om vi ​​tittar tillbaka på algoritmen gör vi ett rekursivt anrop för (n-1) diskar två gånger per anrop. Varje (n-1) rekursion delas upp i ((n-1)-1) rekursioner, och så vidare, tills vi når basfallet med en enda disk.

För tre skivor:

  • Disk 3 anropar den rekursiva funktionen för disk 2 två gånger.
  • Disk 2 anropar den rekursiva funktionen för disk 1 två gånger.
  • Skiva 1 rör sig i konstant tid, vilket ger tid att lösa för tre diskar.

Uttryckt som en återkommande händelse:

= 2 × (Tid att lösa för två skivor) + konstant tid att flytta skiva 3

= 2 × (2 × tid att lösa för en disk + konstant tid att flytta disk 2) + konstant tid att flytta disk 3

= (2 × 2) × konstant tid för att flytta disk 1 + 2 × konstant tid för att flytta disk 2 + konstant tid för att flytta disk 3

För n diskar blir detta:

2N 1 × konstant tid att flytta skiva 1 + 2N 2 × konstant tid för att flytta disk 2 + ….

Denna geometriska progression summerar till O(2n – 1), vilket förenklar O (2n), en exponentiell tidskomplexitet.

2) Rymdkomplexitet:

Rymdkomplexiteten för Hanoi-tornet är O(n). Rekursionen använder anropsstacken, och stackens maximala djup är lika med n, antalet diskar. Det är därför rymdkomplexiteten är O(n).

Vanliga frågor

Hanoi-tornets algoritm är en rekursiv procedur som flyttar n diskar från en källpinne till en destinationspinne med hjälp av en hjälppinne, utan att placera en större disk ovanpå en mindre.

Minsta antal drag för n brickor är 2^n – 1. Tre brickor behöver 7 drag, fyra brickor behöver 15 och tio brickor behöver 1 023 drag.

Tidskomplexiteten är O(2^n) eftersom varje ytterligare disk fördubblar arbetet. Rekursionen T(n) = 2T(n-1) + 1 löses till 2^n – 1, vilket är exponentiellt.

Rymdskomplexiteten är O(n) eftersom rekursionsanropsstacken innehåller en ram för varje disk som bearbetas. Det maximala rekursionsdjupet når n, så det nödvändiga hjälpminnet är linjärt i antalet diskar.

Ja. En iterativ lösning använder en loop med ett fast mönster: vid udda drag byter man den minsta skivan cykliskt mellan pinnarna, och vid jämna drag gör man det enda tillåtna draget som inte är det minsta.

Algoritmen lär ut rekursion, modellerar backup-rotationsscheman för lagring, vägleder robotarmssekvensering och förekommer i neuropsykologiska tester som mäter planeringsförmåga.

Agenter för förstärkningsinlärning löser problemet med Hanoi-tornet genom att behandla varje diskkonfiguration som ett tillstånd och varje rörelse som en handling. Det är ett vanligt riktmärke för planering och hierarkiskt policyinlärning.

Ja. GitHub Copilot, ChatGPT och Gemini generera rekursiva lösningar för Tower of Hanoi i Python, C++och JavaUtvecklare bör fortfarande verifiera basfall och argumentordningen.

Sammanfatta detta inlägg med: