36
MINISTERUL EDUCAȚIEI,CERCETĂRII,TINERETULUI ȘI SPORTULUI COLEGIUL TEHNIC MĂTĂSARI Prof.îndrumător : Săceanu Ion Elev :Şolea Zinica Elena Clasa a XII-a B Profil :Matematică-Informatică 1 ATESTAT PROFESIONAL

Turnurile din Hanoi.docx

Embed Size (px)

Citation preview

Page 1: Turnurile din Hanoi.docx

MINISTERUL EDUCAȚIEI,CERCETĂRII,TINERETULUI ȘI SPORTULUICOLEGIUL TEHNIC MĂTĂSARI

Prof.îndrumător :Săceanu Ion

Elev :Şolea Zinica Elena

Clasa a XII-a B

Profil :Matematică-Informatică

Colegiul Tehnic Mătăsari

1

ATESTAT PROFESIONAL

2015

Page 2: Turnurile din Hanoi.docx

MINISTERUL EDUCAȚIEI,CERCETĂRII,TINERETULUI ȘI SPORTULUICOLEGIUL TEHNIC MĂTĂSARI

Prof.îndrumător :Săceanu Ion

Elev :Şolea Zinica Elena

Clasa a XII-a B

Profil :Matematică-Informatică

Colegiul Tehnic Mătăsari

2

TURNURILE DIN HANOI

2015

Page 3: Turnurile din Hanoi.docx

Cuprins

Argumentarea temei alese……………...pag 4 Noţiuni introductive……………………pag 5Recursivitate…………………………...pag 7Aplicaţii………………………………..pag 9 Turnurile din Hanoi…………………....pag 15Concluzii…….………….……………..pag 24Bibliografie…..………………………..pag 25

Argumentarea temei alese

3

Page 4: Turnurile din Hanoi.docx

Am ales această temă datorită importanţei pe care o are această

tehnică de programare, dar şi pentru că Turnurile din Hanoi era unul din

jocurile mele preferate în copilărie.

Divide et impera se bazează pe principiul descompunerii problemei

în două sau mai multe subprobleme (mai uşoare), care se rezolvă, iar

soluţia pentru problema iniţială se obţine combinând soluţiile

subproblemelor. De multe ori, subproblemele sunt de acelaşi tip şi pentru

fiecare din ele se poate aplica aceeaşi tactică a descompunerii în (alte)

subprobleme, până când (în urma descompunerilor repetate) se ajunge la

probleme care admit rezolvare imediată.

Nu toate problemele pot fi rezolvate prin utilizarea acestei tehnici.

Se poate afirma că numărul celor rezolvabile prin "divide et impera" este

relativ mic, tocmai datorită cerinţei ca problema să admită o

descompunere repetată.

Divide et impera este o tehnică ce admite o implementarea

recursive. Principiul general prin care se elaborează algoritmi recursivi

este: "ce se întâmplă la un nivel, se întâmplă la orice nivel" (având grijă

să asigurăm condiţiile de terminare). Aşadar, un algoritm prin “divide et

impera” se elaborează astfel: la un anumit nivel avem două posibilităţi:

s-a ajuns la o problemă care admite o rezolvare imediată (condiţia de

terminare), caz în care se rezolvă şi se revine din apel;

nu s-a ajuns în situaţia de la punctul 1, caz în care problema curentă este

descompusă în (două sau mai multe) subprobleme, pentru fiecare din ele

urmează un apel recursiv al funcţiei, după care combinarea rezultatelor

are loc fie pentru fiecare subproblemă, fie la final, înaintea revnirii din

apel.

NOŢIUNI INTRODUCTIVE

4

Page 5: Turnurile din Hanoi.docx

Metoda de programare DIVIDE ET IMPERA constă în împărţirea problemei iniţiale de dimensiuni [n] în două sau mai multe probleme de dimensiuni reduse .În general se execută împărţirea în două subprobleme de dimensiuni aproximativ egale şi anume [n/2] . Împărţirea în subprobleme are loc până când dimensiunea acestora devine suficient de mică pentru a fi rezolvate în mod direct(cazul de bază).După rezolvarea celor două subprobleme se execută faza de combinare a rezultatelor în vederea rezolvării întregii probleme.

Pentru a intuii mai bine cum funcţionează această metodă, să ne gândim la modul de organizare a unui turneu de tenis.Concurenţii participant sunt împărţiţi în 2 grupe.Se organizează turneul în cadrul fiecărei grupe, iar finală se va disputa între cei doi câştigători ai turneului de grupe.Câştigătorul finalei este câştigătorul întregului turneu. Organizarea turneului pe grupe se face după cealasi procedeu: se împart concurenţii din cadrul grupei pe semi-grupe , se organizează turneul pe semi-grupe, iar câştigătorul grupei se decide într-un meci de semi-finala între cei 2 câştigători din cele 2 semi-grupe s.a.m.d.. împărţirea se repetă până când avem doar doi jucători, care joacă un meci “direct”.

Metoda DIVIDE ET IMPERA se poate aplica în rezolvarea unei probleme care îndeplineşte următoarele condiţii :

se poate descompune în ( două sau mai multe) suprobleme ; aceste suprobleme sunt independente una faţă de alta (o

subproblema nu se rezolvă pe baza alteia şi nu se foloseşte rezultate celeilalte);

aceste subprobleme sunt similare cu problema iniţială; la rândul lor subproblemele se pot descompune (dacă este

necesar) în alte subprobleme mai simple; aceste subprobleme simple se pot soluţiona imediat prin

algoritmul simplificat. Deoarece puţine probleme îndeplinesc condiţiile de mai sus ,aplicarea metodei este destul de rară. După cum sugerează şi numele "desparte şi stăpâneşte "etapele rezolvării unei probleme (numită problema iniţială) în DIVIDE ET IMPERA sunt :

1. descompunerea problemei iniţiale în subprobleme independente ,smilare problemei de bază ,de dimensiuni mai mici ;

5

Page 6: Turnurile din Hanoi.docx

2. descompunerea treptată a subproblemelor în alte subprobleme din ce în ce mai simple ,până când se pot rezolva imediata ,prin algoritmul simplificat ;

3. rezolvarea subproblemelor simple ;4. combinarea soluţiilor găsite pentru construirea soluţiilor

subproblemelor de dimensiuni din ce în ce mai mari ;5. combinarea ultimelor soluţii determina obţinerea soluţiei

problemei iniţiale .

Metoda DIVIDE ET IMPERA admite o implementare recursivă,deorece subproblemele sunt similare problemei iniţiale, dar de dimensiuni mai mici . Principiul fundamental al recursivităţii este autoapelarea unui subprogram când acesta este activ;ceea ce se întâmplă la un nivel ,se întâmplă la orice nivel ,având grijă să asigurăm condiţia de terminare ale apelurilor repetate .Asemănător se întâmplă şi în cazul metodei DIVITE ET IMPERA ; la un anumit nivel sunt două posibilităţi :s-a ajuns la o (sub)problemă simplă ce admite o rezolvare imediată caz în care se rezolvă (sub)problema şi se revine din apel (la subproblema anterioară,de dimensiuni mai mari);s-a ajuns la o (sub)problema care nu admite o rezolvare imediată ,caz în care o descompunem în două sau mai multe subprobleme şi pentru fiecare din ele se continua apelurile recursive(ale procedurii sau funcţiei). În etapa finală a metodei DIVIDE ET IMPERA se produce combinarea subproblemelor (rezolvate deja) prin secvenţele de revenire din apelurile recursive. Etapele metodei DIVIDE ET IMPERA (prezentate anterior)se pot reprezenta prin următorul subprogram general (procedură sau funcţie) recursiv exprimat în limbaj natural:

Subprogram DIVIMP (PROB); Dacă PROBLEMA PROB este simplă Atunci se rezolva şi se obţine soluţia SOL Altfel pentru i=1,k executa DIVIMP(PROB) şi se obţine SOL1; Se combină soluţiile SOL 1,... ,SOL K şi se obţine SOL; Sfârşit _subprogram;

6

Page 7: Turnurile din Hanoi.docx

Deci ,subprogramul DIVIMP se apelează pentru problema iniţială PROB;aceasta admite descompunerea în K subprobleme simple ;pentru acestea se reapelează recursiv subprogramul ;în final se combină soluţiile acestor K subprobleme.

De obicei problema iniţială se descompune în două subprobleme mai simple ; în acest caz etapele generale ale metodei DIVIDE ET IMPERA se pot reprezenta concret,în limbaj pseudocod ,printr-o procedură recursivă astfel :

Procedura DIVIMP(li,ls,sol); Dacă ((ls-li)<=eps) Atunci REZOLVA (li,ls,sol); Altfel DIVIDE (li,m,ls);

DIVIMP(li,msol1); DIVIMP(m,ls,sol2); COMBINA(sol1,sol2,sol); Sfârşit_ procedura; Procedura DIVIMP se apelează pentru problema iniţială care are dimensiunea între limita inferioară (li) şi limita inferioară(ls);dacă (sub)problema este simplă (ls-li<=eps),atunci procedura REZOLVA îi află soluţia imediat şi se produce întoarcerea din apelul recursiv;dacă (sub)problema este (încă) complexa ,atunci procedura DIVIDE o împarte în două subprobleme ,alegând poziţia m între limitele li şi ls ;pentru fiecare din cele două subprobleme se reapelează recursiv procedura DIVIMP; în final ,la întoarcerile din apeluri se produce combinarea celor două soluitii sol1 şi sol2 prin apelul procedurii COMBINA.

Recursivitatea

7

Page 8: Turnurile din Hanoi.docx

Este o metodă pentru definirea şi calcularea funcţiilor ce se autoapelează.Fie secvenţa {un} , n>=1. Dacă numărul kN şi numerele ui, i>1 sunt

reale sau complexe şi pentru calculul tuturor numerelor se foloseşte relaţia:un+k=a1un+k-1+a2un+k-2+…+akun,

atunci secvenţa este o secvenţă recursivă de ordin k, iar relaţia este o relaţie recursivă de ordin k.

O secvenţă recursivă este caracterizată prin fiecare din termenii săi, prin valoarea de început (de start) şi prin relaţia recursivă ce foloseşte la determinarea unui termen oarecare.

De exemplu, pentru o progresie geometrică cu u1=a, u2=aq, …,un=a*qn-

1, relaţia recursivă se scrie un+1=q*un, unde k=1, u1=a. Este o relaţie

recursivă de ordin 1.Fie progresia aritmetică definită prin u1=a, u2=a+r,…,un=a+(n-1)r,…

Doi termeni consecutivi se găsesc în relaţia :un+1=un+r (1)

care nu e recursivă. Pentru a obţine o relaţie recursivă se consideră :un+2=un+1+r (2)

Din (1)-(2) rezultă un+2=2un+1-un, care este o relaţie recursivă de

ordinul 2 cu u1=a, u2=a+r.

Avantajele folosirii recursivităţii sunt:

Transcrierea imediată (directă) a formulelor de recurenţă din

matematică;

Exprimarea clară a algoritmilor de rezolvare a unor

probleme complexe;

Obţinerea unor programe sursă foarte scurte şi clare

(concise).

Sortare rapidă (quicksort)

8

Page 9: Turnurile din Hanoi.docx

Un tablou V se completează cu n elemente numere reale .Să se ordoneze crescător folosind metoda de sortare rapidă .

Soluţia problemei se bazează pe următoarele etape implementate în programul principal:

se apelează procedura “quick” cu limită inferioară li=1 si limita superioară ls=n; funcţia”poz” realizează mutarea elementului v[i] exact pe poziţia ce o va ocupa acesta în vectorul final ordonat ; funcţia”poz” întoarce (in k ) poziţia ocupată de acest element; în acest fel ,vectorul V se împarte în două părţi : li …k-1 şi k+1…ls;

pentru fiecare din aceste părţi se reapelează procedura“quick”,cu limitele modificate corespunzător ; în acest fel ,primul element din fiecare parte va fi poziţionat exact pe poziţia finală ce o va ocupa în vectorul final ordonat (funcţia“poz”);

fiecare din cele două părţi va fi ,astfel ,împarţită în alte două părţi ;procesul continuă până când limitele părţilor ajung să se suprapună ,ceea ce indică că toate elementele vectorului au fost mutate exact pe poziţiile ce le vor ocupa în vectorul final ;deci vectorul este ordonat ; în acest moment se produc întoarcerile din apelurile recursive şi programul îşi termină execuţia .

program quicksort; type vector= array [1..50] of real ; var v:vector;

i,n,k:integer; function poz(li,ls:integer):integer; var i,j,modi,modj,m:integer; man:real; begin i:=li; j:=ls; modi:=0; modj:=-1; while i<j do begin if v[i]>v[j] then

9

Page 10: Turnurile din Hanoi.docx

begin man:=v[i]; v[i]:=v[j]; v[j]:=man; m:=modi ; modi:=-modj; modj:=-m; end; i:=i+modi; j:=j+modj; end; poz:=i; end procedure quick(li,ls:integer); begin if li<ls then begin

k::=poz(li,ls); quick(li,k-1); quick(k+1,ls); end; end; begin write(‘cate elemente are vectorul ?=’);readln(n); for i:=1 to n do begin write(‘tastati elementul ‘,i,’=’); readln(v[i]); end; quick(1,n);

writeln(‘vectorul ordonat este :’); for i:=1 to n do writeln(v[i]); readln; end.

OBSERVAŢIE dacă elementul se afla în stânga ,atunci se compară cu elementele din dreapta lui şi se sar (j:=j-1)elementele mai mari decât el ; dacă elementul se afla în dreapta ,atunci se compară cu elemente din stânga lui şi se sar (i:=i+1)elementele mai mici decât el.

Sortare prin interclasare(mergesort)

10

Page 11: Turnurile din Hanoi.docx

Tabloul unidimensional V se completează cu n numere reale. Să se ordoneze crescător folosind sortare prin interclasare. Sortarea prin interclasare se bazează pe următoarea logica :vectorul V se împarte ,prin înjumătăţiri succesive ,în vectori din ce în ce mai mici ;când se ating vectorii de maxim două elemente ,fiecare dintre aceştia se ordonează printr-o simplă comparare a elementelor ;câte doi astfel de mini- vectori ordonaţi se interclasează succesiv până se ajunge iar la vectorul V.

program mergesort; type vector=array[1..50] of real ; var v:vector ;n,i:word; procedure schimba(li,ls:word;var a:vector); var man:real; begin if a[li]>a[ls] then begin

man:=a[li]; a[li]:=a[ls]; a[ls]:=man; end; end;

procedure interclas(li,m,ls:word;var a:vector); var b:vector:i,k,p,j:word; begin i:=li; j:=m+1; k:=0; while (i<=m)and(j<=ls) do begin inc(k); if a[i] <a[j] then begin b[k]:=a[i]; inc(i); end else begin b[k]:=a[j]; inc(j); end; end; if i<=m then for p:=i to m do begin1 inc(k);b[k]:=a[p]; end; if j<=ls then for p:=j to ls do begin

11

Page 12: Turnurile din Hanoi.docx

inc(k) ;b[k]:=a[p];

end;

k:=0; for p:=li to ls do begin inc(k); a[p]:=b[k]; end; end;

procedure divi(li,ls:word; var a:vector); var m:word; begin if (ls-li)<=1 then schimba(li,ls,a); else begin m:=(li+ls)div 2; divi(li,m,a); divi(m+1,ls,a); interclas(li,m,ls,a); end;

end; begin

write(‘cate elemente are vectorul?=’);readln(n); for i:=1 to n do begin write(‘tastati elementul’,i,’=’); readln(v[i]); end;

divi(1,n,v); writeln(‘vectorul sortat este:’); for i:=1 to n do writeln(v[i]); end.

OBSERVAŢII mecanismul general de tip Divide et Impera se găseşte implementat în procedura “divi” ;

12

Page 13: Turnurile din Hanoi.docx

o astfel de abordare a problemei sortarii unii vector conduce la economie de timp de calcul ,deoarece operaţia de interclasare a doi vectori deja ordonaţi este foarte rapidă ,iar ordonarea independenta celor două jumătăţi(mini- vectori) consumă în total aproximativ a doua parte din timpul care ar fi necesar ordonării vectorului luat ca întreg .

Sortare prin inserţie binară Să se ordoneze crescător un tablou unidimensional V de n numere reale ,folosind sortarea prin inserţie binară .

Pentru fiecare element v[i] se procedează în patru paşi: se consideră ordonate elementele v[1],v[2],….,v[i-1];

se caută poziţia k pe care urmează s-o ocupe v[i] între elementele v[1],v[2],…,v[i-1](procedura “poz” prin cautare binară); se deplasează spre dreapta elementele din poziţiile k,k+1,…,n(procedura “deplasare”); inserează elementul v[i] în poziţia k (procedura”deplasare”); se obţine o succesiune de k+1 elemente ordonate crescator.

program sortare _binara; type vector =array[1..50] of real ; var n,k,i:integer; v:vector; function poz(li,ls,i:integer):integer; var m:integer; begin if li=ls then if v[i]<v[j] then poz:=li else poz:=i else if ls-li=1 then if v[i]<v[ls] then if v[i]>=v[li] then poz:=ls

else poz:=li else poz:=i else begin m:=(li+ls)div 2;

if v[i]<v[m] then poz:=poz(li,m,i)

13

Page 14: Turnurile din Hanoi.docx

else poz :=poz(m,ls,i); end; end; procedure deplasare(k,i:integer);

var man:real; j:integer;

begin

if k<i then begin man:=v[i]; for j:=I downto k+1 do v[j]:=v[j-1]; v[k]:=man; end; end;

beginwrite(‘cate elemente are vectorul?=’);readln(n);for i:=1 to n do begin write(‘tastati elementul ‘,i,’=’);readln(v[i]); end;for i:=2 to n do begin k:=poz(1,i-1,i); deplasare(k,i); end;writeln(‘vectorul ordonat este :’);for i:=1 to n do writeln(v[i]);

readln;end.

TURNURILE DIN HANOI

Turnul din Hanoi sau Turnurile din Hanoi este un joc matematic sau puzzle. Este format din trei tije şi un număr variabil de discuri, de diferite mărimi, care pot fi poziţionate pe oricare din cele 3 tije. Jocul începe

14

Page 15: Turnurile din Hanoi.docx

având discurile aşezate în stivă pe prima tijă, în ordinea mărimii lor, astfel încât să formeze un turn. Scopul jocului este acela de a mută întreagă stivă de pe o tijă pe altă, respectând următoarele reguli:

-Doar un singur disc poate fi mutat, la un moment dat. -Fiecare mutare constă în luarea celui mai de sus disc de pe o tijă şi glisarea lui pe o altă tijă, chiar şi deasupra altor discuri care sunt deja prezente pe acea tijă. -Un disc mai mare nu poate fi poziţionat deasupra unui disc mai mic.

Legenda jocului

Unul dintre jocurile aparent simple, dar cu un adânc substrat matematic, este binecunoscutul Turn din Hanoi. Acest joc a fost inventat de matematicianul francez Edouard Lucas şi a fost comercializat ca jucărie pentru toate vârstele încă din anul 1883. La început era confecţionat din lemn şi constă în câteva discuri de mărimi diferite şi 3 beţişoare. Provocarea este de a muta turnul format din discuri de pe un beţişor pe alt beţişor liber, urmând două reguli simple: la fiecare mutare se mută un singur disc şi niciodată nu se aşază un disc mai mare peste un disc mai mic. Bineînţeles, scopul este acela de a realiza mutarea turnului folosind cât mai puţine mutări.

Se spune că acest joc este inspirat de legenda Turnului lui Brahma, aflat într-un templu al oraşului indian Benares. Acest turn este format din 64 de discuri de aur, de a căror mutare se ocupă preoţii templului, respectând regulile de mai sus. Legenda spune că atunci când turnul discurilor de aur va fi complet transferat pe o altă tijă, templul se va prăbuşi iar lumea va lua sfârşit. Ceea ce ne face să ne întrebăm cu îngrijorare care este numărul minim de mutări în cazul turnului cu 64 de discuri... Pentru a răspunde la această întrebare, vom începe prin a cerceta ce se întâmplă în cazul jocului cu mai puţine discuri.

Să notăm cele 3 beţişoare folosind literele A, B, C. La început, turnul se află pe beţişorul A, iar noi vrem să îl mutăm pe beţişorul C. Vom nota cu n numărul discurilor, iar cu Un numărul minim de mutări atunci când avem un turn format din n discuri.!!De reţinut• pentru n = 1, turnul se mută printr-o singură mutare, deci U1 = 1;• pentru n = 2, turnul se poate muta prin 3 mutări, deci U2 = 3;• pentru n = 3, turnul se poate muta prin 7 mutări, deci U3 = 7.

15

Page 16: Turnurile din Hanoi.docx

Dar în cazul unui turn format din n discuri? Să ne gândim: în procesul de mutare a acestui turn, ajungem la momentul în care toate discurile înafară de cel mai mare sunt mutate pe un alt beţişor (B) decât cel iniţial (A), formând un turn cu n-1 discuri. Dacă presupunem că am ajuns la acest moment folosind numărul minim de mutări, înseamnă că până acum am făcut Un-1 mutări. În continuare, mutăm discul cel mai mare de pe A pe C, folosind o singură mişcare. Apoi nu ne rămâne decât să mutăm turnul cu n-1 discuri de pe B pe C, peste discul cel mai mare. Acest lucru poate fi făcut prin minim Un-1 mutări. Acum să numărăm câte mutări am făcut în total: Un = Un-1 +1 + Un-1 = 2 Un-1 + 1

Astfel am obţinut o relaţie de recurenţă între numărul minim de mutări pentru un turn cu n discuri şi unul format din n-1 discuri, motiv pentru care acest joc este foarte des folosit ca exemplu pentru tehnici de programare care folosesc recurenţa. Folosind procedeul numit inducţie matematică, se poate demonstra uşor că numărul minim de mutări în cazul turnului cu n discuri este: Un = 2n - 1. Aşadar, revenind la Turnul lui Brahma, numărul minim de mutări este 264 - 1, adică un număr de 20 de cifre! Dacă 264 - 1 ar fi secunde, atunci asta ar însemna circa 584 942 417 355 de ani. Deci putem sta liniştiţi, sfârşitul lumii e departe: chiar dacă preoţii ar munci fără încetare şi ar face o mutare pe secundă, tot le-ar trebui multe mii de milioane de ani pentru a-şi termina treaba.

După ce matematicienii au epuizat de întors pe toate feţele acest joc, ei au descoperit şi alte variante, mult mai provocatoare din punct de vedere matematic. De exemplu, care ar fi numărul maxim de mutări prin care se poate transfera turnul de pe un beţişor pe altul, fără a reveni la o configuraţie anterioară? Dar dacă jocul ar avea 4 sau mai multe beţişoare în loc de 3? Acestea sunt doar câteva exemple care ne arată cum se poate transforma o problemă relativ simplă într-una de o mare complexitate matematică, prin modificarea minimă a unei singure variabile din enunţul problemei... dar până la urmă, în astfel de lucruri stă frumuseţea matematicii!

Prezentarea algoritmului rezolvării

Fie trei tije verticale notate A,B,C .Pe tija A se găsesc aşezate n discuri de diametre diferite ,în ordinea crescătoare a diametrelor,privind de sus în jos . Iniţial ,tijele B şi C sunt goale .Să

16

Page 17: Turnurile din Hanoi.docx

se afişeze toate mutările prin care discurile de pe tija A se muta pe tija B , în aceeaşi ordine ,folosind ca tijă de manevră C şi respectând următoarele reguli: la fiecare pas se muta un singur disc; un disc se poate aşeza numai peste un disc cu diametrul mai mare . Rezolvarea acestei probleme se bazează pe următoarele considerente logice : -daca n=1 ,atunci mutarea este immediata AB(mut discul de pe A pe B); daca n=2,atunci şirul mutărilor este : AC,AB,CB; daca n>2 procedăm astfel : -mut (n-1)discuri AC; -mut un disc AB ; -mut cele (n-1)discuri CB.

Observăm că problema iniţială se descompune în trei subprobleme mai simple ,similare problemei iniţiale: mut (n-1)discuri AC ,mut ultimul disc pe B ,mut cele (n-1)discuri C-->B.Dimensiunile acestor subprobleme sunt : n-1,1,n-1.Aceste subprobleme sunt independente ,deoarece tijele iniţial (pe care sunt dispuse discurile ),tijele finale şi tijele intermediare sunt diferite.Notam H(n,A,B,C)=şirul mutărilor a n discuri de pe A pe B, folosind C. PENTRU n=1 AB

n>1 H(n,A,B,C)= H(n-1,A,C,B),AB, H(n-1,C,B,A)

program turn_hanoi var n:byte; procedure hanoi(n:byte;a,b,c:char); begin if n=1 then writeln(a,’->’,b) else begin hanoi(n-1,a,c,b); writeln(a,’->’,b); hanoi(n-1,c,b,a); end; end;

17

Page 18: Turnurile din Hanoi.docx

begin write(‘nr discuri pe tija A =’);readln(n); writeln(‘mutările sunt următoarele :’); hanoi(n,’A’,’B’,’C’); readln;readln; end.

Program hanoi_recursiv;

uses crt; const Pauză=1;forma=#219;vârf:array [1..3] of Byte=(13,22,22); var nn:integer; procedure HideCursor; assembler; {ascunde cursorul pilpaitor,în modul text} asm MOV AX,$0100;MOV CX,$2607;INT $10 end; procedure ShowCursor;assembler; {reafiseaza cursorul} asm MOV AX,$0100;MOV CX,$0506;INT $10 end;

function coltija(tija:byte):byte; begin coltija:=24*tija-8; end;

procedure mutadreapta(disc,tija1,tija2:byte); var i,k:byte; begin for i:=coltija(tija1)-disc to pred(coltija(tija2)-disc) do begin delay(pauză); if keypressed then halt(1); gotoxy(i,3); for k:=0 to 2*disc do write(' '); gotoxy(i+1,3); for k:=0 to 2*disc do write(forma)

18

Page 19: Turnurile din Hanoi.docx

end end;

procedure mutastanga(disc,tija1,tija2:byte); var i,k:byte; begin for i:=coltija(tija1)-disc downto succ(coltija(tija2)-disc) do begin delay(pauză); if keypressed then halt(1); gotoxy(i,3); for k:=0 to 2*disc do write(' '); gotoxy(i-1,3); for k:=0 to 2*disc do write(forma); end;end;

procedure coboară(disc,tija:byte); var i,k:byte; begin for i:=3 to pred(vârf[tija]-1) do begin delay(pauză); if keypressed then halt(1); gotoxy(coltija(tija)-disc,i); for k:=0 to 2*disc do write(' '); gotoxy(coltija(tija)-disc,i+1); for k:=0 to 2*disc do write(forma); end; dec(vârf[tija]); end;

procedure ridică(disc,tija:byte); var i,k:byte; begin for i:=vârf[tija] down to 4 do begin delay(pauză); if keypressed then halt(1); gotoxy(coltija(tija)-disc,i); for k:=0 to 2*disc do write(' '); gotoxy(coltija(tija)-disc,i-1); for k:=0 to 2*disc do write(forma); end;

19

Page 20: Turnurile din Hanoi.docx

inc(vârf[tija]); end;

procedure muta(disc,tija1,tija2:byte);begin ridică(disc,tija1); {şterge discul cu diametrul cel mai mic de pe tija 1} if tija1<tija2 then {dacă tija1<tija2 atunci discul va} mutadreapta(disc,tija1,tija2) {fi mutat pe o tijă situată la dreapta} else {altfel discul va fi mutat pe o tijă } mutastanga(disc,tija1,tija2); {situată la stânga} coboară(disc,tija2); {redesenează discul ridicat de pe tija 1 pe tija 2}end;

procedure han(n,tija1,tija2,tija3:byte);begin if n=1 then muta(1,tija1,tija2) else begin han(n-1,tija1,tija3,tija2); muta(n,tija1,tija2); han(n-1,tija3,tija2,tija1); end;end;

procedure iniţializări; var k,disc:byte; begin nn:=10; hidecursor;clrscr; for disc:=1 to nn do begin gotoxy(coltija(1)-disc,vârf[1]+disc-1); for k:=0 to 2*disc do write(forma); end; end;

begin{main} iniţializări; gotoxy(28,1); writeln('Turnurile din Hanoi'); han(nn,1,2,3); showcursor;

20

Page 21: Turnurile din Hanoi.docx

A

B

C

A

B

C

B B

1

2

3

4

Muta primele 2 discuri pe tija de manevra

end.

Să analizăm mutările care trebuiesc făcute pentru n=3:

Ø Se mută discul de pe tija A pe tija B (1).

Ø Se mută discul de pe tija A pe tija C (2).

Ø Se mută discul de pe tija B pe tija C (3).

Ø Se mută discul de pe tija A pe tija B (4).

Ø Se mută discul de pe tija C pe tija A (5).

Ø Se mută discul de pe tija C pe tija B (6).

Ø Se mută discul de pe tija A pe tija B (7).

Folosind metoda divide et impera problema iniţială va fi descompusă în subprobleme astfel:PAS1.Se mută primele n-1 discuri de pe tija sursa pe tijă de manevrăPAS2.Se mută discul cu diametrul cel mai mare de pe tija sursa pe tija destinaţie.PAS3.Se mută cele n-1 discuri de pe tijă de manevra pe tija destinaţie.

21

Page 22: Turnurile din Hanoi.docx

Tabel valori :

22

Număr discuri: Număr mutări:

1 1

2 3

3 7

4 15

5 31

6 63

7 127

8 255

9 511

10 1023

11 2047

12 4095

Page 23: Turnurile din Hanoi.docx

CONCLUZII

(analiză a complexităţii; timp pentru algoritmii Divide et Impera) Algoritmii de tip Divide et Impera au bună comportare în timp ,dacă se îndeplinesc următoarele condiţii:-dimensiunile subprogramelor (în care se împarte problema iniţială ) sunt aproximativ egale (“principiu balansării”);-lipsesc fazele de combinare a soluţiilor subproblemelor (căutarea binară).

23

Page 24: Turnurile din Hanoi.docx

BIBLIOGRAFIE

Livia Toca,Cristian Opincaru,AdrianSindile , MANUAL DE INFORMATICĂ PENTRU CLS.a-X a, Editura Niculescu ;

Radu Visinescu,BAZELE PROGRAMĂRII , Editura Petrion ;

Cristian Udrea,TEORIE ŞI APLICAŢII, Editura Arves ;

24