P. 1
curs_proiectarea_alg

curs_proiectarea_alg

|Views: 4,972|Likes:
Published by gheorghehazi

More info:

Published by: gheorghehazi on Mar 14, 2011
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

05/08/2013

pdf

text

original

Sections

  • 1. INTRODUCERE ÎN PROIECTAREA ALGORITMILOR
  • 1.1. Definiţii
  • 1.2. Obiectul disciplinei
  • 1.3. Proprietăţi ale algoritmilor
  • 1.4. Date
  • 1.5. Tipuri de prelucrări
  • 1.6. Exerciţii
  • 2. DESCRIEREA ALGORITMILOR
  • 2.1. Limbaj algoritmic
  • 2.2. Specificarea datelor
  • 2.3. Exemple de algoritmi
  • 2.4. Tehnica rafinării succesive şi subalgoritmi
  • 2.5. Exerciţii
  • 3. VERIFICAREA CORECTITUDINII ALGORITMILOR
  • 3.1. Etapele verificării corectitudinii
  • 3.2. Elemente de analiză formală a corectitudinii
  • 3.3. Exerciţii
  • 4. ANALIZA COMPLEXITĂTII ALGORITMILOR
  • 4.1. Scopul analizei complexităţii
  • 4. 2. Timpi de execuţie
  • 4.3. Ordin de creştere
  • 4.4. Notaţii asimptotice
  • 4.5. Etapele analizei complexităţii
  • 4.6. Analiza empirică a complexităţii algoritmilor
  • 4.7. Exerciţii
  • 5. METODE ELEMENTARE DE SORTARE
  • 5.1. Problematica sortării
  • 5.2. Sortare prin inserţie
  • 5.3. Sortare prin selecţie
  • 5.4. Sortare prin interschimbarea elementelor v
  • 5.5. Exerciţii
  • 6. TEHNICI DE ELABORARE A ALGORITMILOR: REDUCERE ŞI DIVIZARE
  • 6.2. Algoritmi recursivi
  • 6.3. Tehnica reducerii
  • 6.4. Tehnica divizării
  • 6.5. Exerciţii
  • 7.1. Introducere
  • 7.2. Sortare prin interclasare
  • 7.3. Sortare rapidă
  • 7.4. Exerciţii
  • 8. TEHNICA ALEGERII LOCAL OPTIMALE ("GREEDY")
  • 8.1. Introducere
  • 8.2. Principiul tehnicii
  • 8.3. Verificarea corectitudinii si analiza complexităţii
  • 8.4. Aplicaţii
  • 8.5. Exerciţii
  • ANEXA Program pentru împachetare optimă (varianta 3)
  • 9. TEHNICA PROGRAMĂRII DINAMICE
  • 9.1. Introducere
  • 9.2. Principiul tehnicii şi etapele aplicării
  • 9.3. Aplicaţii
  • 9.4. Exerciţii
  • 10. TEHNICA CĂUTĂRII CU REVENIRE
  • 10.1. Introducere
  • 10.2. Principiul metodei şi structura generală a algoritmului
  • 10.3. Aplicaţii
  • 10.4. Exerciţii
  • EPILOG. SFATURI PENTRU PROIECTAREA ALGORITMILOR
  • EXERCIŢII SUPLIMENTARE
  • BIBLIOGRAFIE

UNIVERSITATEA DIN BACĂU FACULTATEA DE INGINERIE

Gheorghe Hazi

PROIECTAREA ALGORITMILOR

CURS PENTRU UZUL STUDENŢILOR

Bacău - 2007

Proiectarea algoritmilor

CUPRINS 1. Introducere în proiectarea algoritmilor............................................4 1.1. Definiţii..........................................................................................4 1.2. Obiectul disciplinei........................................................................4 1.3. Proprietăţi ale algoritmilor.............................................................5 1.4. Date………………………………………………………………7 1.5. Tipuri de prelucrări........................................................................7 1.6. Exerciţii..........................................................................................8 2. Descrierea algoritmilor...................................................................12 2.1. Limbaj algoritmic..........................................................................12 2.2. Specificarea datelor.......................................................................15 2.3. Exemple de algoritmi....................................................................16 2.4. Tehnica rafinării succesive şi subalgoritmi...................................21 2.5. Exerciţii.........................................................................................22 3. Verificarea corectitudinii algoritmilor.............................................24 3.1. Etapele verificării corectitudinii....................................................24 3.2. Elemente de analiză formală a corectitudinii................................26 3.3. Exerciţii.........................................................................................30 4. Analiza complexităţii algoritmilor...................................................32 4.1. Scopul analizei complexităţii.........................................................32 4.2. Timpi de execuţie...........................................................................33 4.3. Ordin de creştere............................................................................37 4.4. Notaţii asimptotice.........................................................................38 4.5. Etapele analizei complexităţii........................................................42 4.6. Analiza empirică a complexităţii algoritmilor...............................42 4.7. Exerciţii..........................................................................................43 5. Metode elementare de sortare..........................................................46 5.1. Problematica sortării......................................................................46 5.2. Sortare prin inserţie........................................................................47 5.3. Sortare prin selecţie........................................................................49 5.4. Sortare prin interschimbarea elementelor vecine...........................50 5.5. Exerciţii..........................................................................................54 6. Tehnici de elaborare a algoritmilor: reducere şi divizare.................56 6.1. Motivaţie.........................................................................................57 6.2. Algoritmi recursivi.........................................................................58 6.3. Tehnica reducerii............................................................................61 6.4. Tehnica divizării.............................................................................66 6.5. Exerciţii..........................................................................................70 7. Aplicaţii ale tehnicii divizării. Sortarea prin interclasare şi sortarea rapidă..............................................................................71 7.1. Introducere......................................................................................71 Cuprins -2-

Proiectarea algoritmilor 7.2. Sortare prin interclasare...................................................................71 7.3. Sortare rapidă...................................................................................74 7.4. Exerciţii............................................................................................78 8. Tehnica alegerii local optimale ("greedy")………………………….80 8.1. Introducere........................................................................................80 8.2. Principiul tehnicii.............................................................................80 8.3. Verificarea corectitudinii si analiza complexităţii............................83 8.4. Aplicaţii............................................................................................84 8.5. Exerciţii............................................................................................88 8.6. Anexa - Program pentru împachetare optimă (varianta 3)...............89 9. Tehnica programării dinamice............................................................93 9.1. Introducere........................................................................................93 9.2. Principiul tehnicii şi etapele aplicării...............................................93 9.3. Aplicaţii............................................................................................98 9.4. Exerciţii...........................................................................................105 10. Tehnica căutării cu revenire..............................................................107 10.1. Introducere.....................................................................................107 10.2. Principiul metodei şi structura generală a algoritmului.................107 10.3. Aplicaţii..........................................................................................111 10.4. Exerciţii..........................................................................................117 Epilog. Sfaturi pentru proiectarea algoritmilor............................................118 Exerciţii suplimentare...................................................................................122 Bibliografie...................................................................................................141

Cuprins -3-

Elaborarea unui algoritm necesită: cunoştinţe specifice domeniului de unde provine problema de rezolvat. un algoritm este o entitate matematică care este independentă de maşina pe care va fi executat. În cadrul algoritmului sunt descrise prelucrările necesare pentru a obţine soluţia problemei pornind de la datele de intrare. Spre deosebire de un program. la unele probleme. INTRODUCERE ÎN PROIECTAREA ALGORITMILOR 1. O definiţie mai precisă.Proiectarea algoritmilor 1. Primul algoritm se consideră a fi algoritmul lui Euclid (utilizat pentru determinarea celui mai mare divizor comun a două numere naturale). ci doar pentru a descrie într-o manieră ordonată activităţi care constau în parcurgerea unei succesiuni de paşi (cum este de exemplu utilizarea unui telefon public sau a unui bancomat). Analiza algoritmilor presupune verificarea corectitudinii acestora şi a eficienţei. Definiţii Un algoritm este o metodă de rezolvare pas cu pas a problemelor. ce a trăit în secolul al IX-lea şi care a scris o lucrare despre efectuarea calculelor numerice într-o manieră algebrică. tehnici generale de rezolvare a problemelor. care depinde de un limbaj de programare. nefiind neapărat legat de rezolvarea unei probleme cu caracter ştiinţific. Soluţia problemei se obţine prin execuţia algoritmului. alKhowarizmi (al-Kwarizmi). să fi avut dificultăţi în găsirea soluţiei de rezolvare. Acesta trebuie să poată fi implementat pe un calculator. Atunci când aţi găsit o soluţie nu ştiaţi dacă ea este cea mai bună. Un algoritm este considerat corect dacă prin aplicarea lui asupra datelor problemei conduce Introducere -4- . intuiţie şi gândire algoritmică. În matematică există o serie de algoritmi: cel al rezolvării ecuaţiei de gradul doi. schema lui Horner (pentru determinarea câtului şi restului împărţirii unui polinom la un binom) etc. Termenul de algoritm poate fi înţeles în sens larg. Algoritmul poate fi executat pe o maşină formală (în faza de proiectare şi analiză) sau pe o maşină fizică (calculator) după ce a fost codificat într-un limbaj de programare.1. Dacă până acum aţi scris programe. este: Un algoritm este o succesiune bine precizată de prelucrări care aplicate asupra datelor de intrare ale unei probleme permit obţinerea în timp finit a soluţiei acesteia. algoritmul lui Eratostene (pentru generarea numerelor prime mai mici decât o anumită valoare). Obiectul disciplinei Obiectul disciplinei de „Proiectarea algoritmilor” îl reprezintă studiul algoritmilor din perspectiva elaborării şi analizei lor. 1. O problemă este constituită din date de intrare şi un enunţ care specifică relaţia existentă între datele de intrare şi soluţia problemei. Această carte vă va îndruma cum să lămuriţi asemenea probleme. este posibil ca.2. Termenul de algoritm provine de la numele unui matematician persan. în sensul cursului nostru.

în schimb pentru a doua problemă nu se poate scrie un algoritm atâta timp cât nu se cunoaşte un criteriu de oprire a prelucrărilor. 3. (ii) să se construiască mulţimea multiplilor lui n.3. 4. 2. 4. 4.Proiectarea algoritmilor la soluţia acestuia şi eficient dacă prin execuţia acestuia rezultatul se obţine într-un interval de timp rezonabil. 3. 5) Introducere -5- . fără ambiguităţi. Pentru rezolvarea primei probleme se poate elabora uşor un algoritm. Prin intermediul algoritmilor nu pot fi prelucrate structuri infinite. 3. 3. 5)). O modalitate de ordonare ar fi următoarea: se compară primul element cu al doilea iar daca nu se află în ordinea bună se interschimbă (în felul acesta se obţine (1. 5).Un algoritm trebuie să funcţioneze pentru orice dată de intrare. 1. Algoritmii pot fi efectiv utilizaţi doar dacă folosesc resurse de calcul în volum acceptabil. Un algoritm trebuie să admită o descriere finită şi fiecare dintre prelucrările pe care le conţine trebuie să poate fi executată în timp finit. Deşi metoda descrisă mai sus a permis ordonarea crescătoare a şirului (2. Considerăm un număr natural n şi următoarele două probleme: (i) să se construiască mulţimea divizorilor lui n. Un algoritm destinat rezolvării unei probleme trebuie să permită obţinerea rezultatului pentru orice date de intrare valide şi nu numai pentru date particulare de intrare. În orice etapă a execuţiei algoritmului trebuie să se ştie exact care este următoarea etapă ce va fi executată. Un algoritm prost conceput nu poate fi ”reparat” prin artificii de programare. pentru şirul astfel transformat se compară al doilea element cu al treilea şi dacă nu se află în ordinea dorită se interschimbă (la această etapă şirul rămâne neschimbat). Să considerăm problema ordonării crescătoare a şirului de valori: (2. 2. Indiferent de complexitatea unei aplicaţii informatice. Rigurozitate. 2. Nu orice problemă poate fi rezolvată algoritmic. se continuă procedeul până ˆ penultimul element se compară cu ultimul. 5). Oricât de sofisticată ar fi tehnologia software utilizată (interfeţe. Prelucrările algoritmului trebuie specificate riguros. Prin resurse de calcul se înţelege volumul de memorie şi timpul necesar pentru execuţie. Proprietăţi ale algoritmilor Un algoritm trebuie să posede următoarele proprietăţi: Generalitate. 1. Din acest motiv dobândirea unor cunoştinţe solide privind elaborarea şi analiza algoritmilor este o condiţie necesară în formarea unui bun programator. Analiza presupune aplicarea unor tehnici de demonstrare specifice matematicii. 4. 1. Eficienţă. structurare globală a aplicaţiei) eficienţa aplicaţiei este în mod esenţial determinată de eficienţa algoritmilor implicaţi. Finitudine. In felul acesta se obţine (1. la bazele ei stau algoritmi destinaţi rezolvării problemelor fundamentale ale aplicaţiei. Exemple 1.

1. 5) conduce la (2. Un algoritm trebuie să se oprească. 4. Se consideră următoarea secvenţă de prelucrări: Pas 1. Pas 3. altfel se opreşte algoritmul. Dacă x Є [-10. Atât timp cât şansa ca algoritmul să se termine este nenulă algoritmul poate fi considerat corect (în cazul prezentat mai sus este vorba despre un algoritm aleator). 4. Măreşte valoarea lui x cu 2. 3. 3. Presupunem că timpul de execuţie a unei prelucrări este -3 10 s şi că problema are dimensiunea n = 100. Un algoritm trebuie să se oprească după un interval rezonabil de timp. Dacă. Ce se poate spune despre finitudinea acestui algoritm ? Dacă s-ar obţine alternativ cap respectiv pajură. 10] se reia de la Pasul 2. secvenţa de mai sus nu poate fi considerată un algoritm. Pas 2. Atât timp cât nu se stabileşte un criteriu după care se decide dacă x se măreşte sau se micşorează. Fie se măreşte x cu 1 fie se micşorează x cu 1. caz în care procesul s-ar opri după 11 repetări ale pasului 2. 1. 2. deci succesiunea de prelucrări nu se termină niciodată. 5). însă se foloseşte un algoritm caracterizat prin T (n) = 2 atunci timpul de execuţie va fi de circa 27 19 10 secunde adică aproximativ 10 ani. Atribuie variabilei x valoarea 0. Dacă se obţine cap se măreşte x cu 1 iar dacă se obţine pajură se micşorează x cu 1. Să considerăm că rezolvarea unei probleme implică prelucrarea a n date şi că numărul de prelucrări T (n) depinde de n. Considerăm următoarea secvenţă de prelucrări: Pas 1. Pas 3. Există însă şi posibilitatea să se obţină de 11 ori la rând cap (sau pajură). Atribuie variabilei x valoarea 1. Dacă se foloseşte un algoritm caracterizat -3 -1 prin T(n) = n atunci timpul de execuţie va fi 100 x 10 = 10 secunde. Se aruncă o monedă. Ambiguitatea poate fi evitată prin utilizarea unui limbaj riguros de descriere a algoritmilor. În acest caz specificarea prelucrărilor nu mai este ambiguă chiar dacă la execuţii diferite se obţin rezultate diferite. prelucrarea ar putea fi infinită. Este uşor de observat că x nu va lua niciodată valoarea 100. Din acest motiv succesiunea de prelucrări nu poate fi considerată un algoritm corect. n Introducere -6- . 5. Prelucrările dintr-un algoritm trebuie să fie neambigue. 4. Să considerăm că Pas 2 se înlocuieşte cu: Pas 2. Pas 2. Dacă x este egal cu 100 atunci se opreşte prelucrarea altfel se reia de la Pas 2.Proiectarea algoritmilor ea nu poate fi considerată un algoritm de sortare întrucât dacă este aplicată şirului (3.

ansamblu de valori distincte pentru care nu are importanta ordinea în care sunt reţinute • şir finit .5. • Transfer. o valoare de adevăr sau un caracter). Datele structurate omogene ce vor fi utilizate în continuare sunt cele destinate reprezentării unor structuri algebrice simple: • mulţime finită . Acestea sunt entităţi purtătoare de informaţie (relevantă pentru problema de rezolvat). Permite afectarea unei valori unei variabile. O expresie descrie un calcul efectuat asupra unor date şi conţine operanzii (specifică datele asupra cărora se efectuează calculele) şi operatori (specifică prelucrările ce se vor efectua). Prelucrările simple sunt: • Atribuire. Cel mai frecvent sunt folosite tablourile unidimensionale (pentru reprezentarea şirurilor şi mulţimilor) şi cele bidimensionale (pentru reprezentarea matricelor). Daca toate datele componente au aceeaşi natură atunci structura este omogenă. Date Prelucrările efectuate în cadrul unui algoritm se efectuează asupra unor date.Proiectarea algoritmilor 1. Considerăm datele ca fiind containere ce conţin informaţie. 1.tabel bidimensional de valori Pentru reprezentarea acestor date vom folosi structura de tablou caracterizată prin faptul ca fiecare valoare componentă poate fi specificată prin precizarea unuia sau mai multor indici. Permit preluarea datelor de intrare ale problemei şi furnizarea rezultatului. pentru care are importanţă ordinea în care sunt reţinute • matrice . Introducere -7- . • Structurate: sunt constituite din mai multe date simple între care exista o relaţie de structură. valoarea curentă a unei date fiind informaţia pe care o conţine la un moment dat. Valoarea atribuita poate fi rezultatul evaluării unei expresii. Tipuri de prelucrări Asemenea datelor şi prelucrările pot fi clasificate în simple si structurate. altfel este o structura heterogenă. În funcţie de rolul jucat în cadrul algoritmului datele pot fi constante (valoarea lor rămâne nemodificată pe parcursul algoritmului) sau variabile (valoarea lor poate fi modificată). În mod normal prelucrările din algoritm se efectuează în ordinea în care sunt specificate. În cazul în care se doreşte modificarea ordinii naturale se transferă controlul execuţiei la o anumita prelucrare. • Control. Din punctul de vedere al informaţiei pe care o poarta datele pot fi: • Simple: conţin o singura valoare (poate fi un număr.ansamblu de valori. nu neapărat distincte.4.

Se înmulţeşte y cu 2 iar produsul se scrie sub y. Exerciţii 1. Condiţia este.Proiectarea algoritmilor Structurile de prelucrare sunt: • Secvenţiala. În funcţie de momentul în care este analizată condiţia exista prelucrări repetitive condiţionate anterior (condiţia este analizata înainte de a efectua prelucrarea) şi prelucrări condiţionate posterior (condiţia este analizată a după efectuarea prelucrării). Se scrie x alături de y (pe aceeaşi linie). Permite specificarea situaţiilor în care. Este o succesiune de prelucrări (simple sau structurate). Se caracterizează prin existenţa unei prelucrări care se repetă şi a unei condiţii de oprire (sau de continuare). Este metoda descrisa un algoritm ? Este el corect (determina produsul celor doua numere) ? Să considerăm calculul produsului 12 x 5. ∞) ⎩ • De ciclare (repetitivă).1] ⎪ f ( x) = ⎨ ⎪1 + ( x − 1) 2 . în funcţie de realizarea sau nerealizarea unei condiţii. Permite modelarea situaţiilor când o prelucrare trebuie repetată. În acest caz prelucrarea este dată de adunare n⎠ i =1 ⎝ iar condiţia de oprire este aceea ca să se fi adunat toţi termenii. Un exemplu de prelucrare n ⎛ 1⎞ ciclică este calcul sumei ∑ ⎜1 + ⎟ . • De decizie (alternativă). o expresie a cărui rezultat este o valoare logică (adevărat sau fals). Se consideră următoarea metodă de înmulţire a doua numere întregi x si y. de regulă. 1. Se adună toate valorile de pe coloana a doua care corespund unor valori impare aflate pe prima coloană. se efectuează o prelucrare sau o alta prelucrare. Calculele se opresc în momentul în care pe prima coloană se obţine valoarea 1. Procedeul continuă construindu-se astfel doua coloane de numere. x ∈ (−∞.6. x ∈ (1. x | y ------------12 | 5 6 | 10 3 | 20 1 | 40 ----------60 Introducere -8- . de exemplu. Se împarte x la 2 si câtul împărţirii se scrie sub x (restul se ignoră). O astfel de prelucrare apare. Execuţia structurii secvenţiale consta în execuţia prelucrărilor componente în ordinea în care sunt specificate. în evaluarea unei funcţii definite prin: ⎧ x.

Starea cu toţi biţii1 sau 0 nu este luată în considerare. Introducere -9- .an } şi se cere să se determine doua submulţimi disjuncte B si C astfel încât B ∪ C = A şi a i ∈B ∑ ai − ∑ ai a i ∈C este minimă. Daca numărul este impar vânzătoarea poate da o moneda de 5 iar ceea ce rămâne (un număr par) în monede de 2. Indicaţie. (b) Se consideră doua dispozitive de stocare (de exemplu discuri magnetice) si o mulţime de fişiere a căror dimensiuni însumate nu depăşeşte capacitatea globală a celor două discuri. O variantă de generare a submulţimilor B. A = {a1. Se va tine cont de semnul numărului. Cea mai simplă metodă este cea a ”forţei brute” prin care se generează toate perechile de submulţimi (B. apartenenţa la mulţimea C. Consideram ca o vânzătoare dispune doar de monede de 2 unităţi şi 5 unităţi. Prin urmare prelucrarea este finită.Proiectarea algoritmilor Ca urmare a împărţirilor succesive la 2 valorile de pe prima coloana descresc până se ajunge la un cât egal cu 1. 3. Dacă restul este un număr par atunci vânzătoarea poate da doar monede de 2. C) şi se alege cea care minimizează diferenţa specificată mai sus. Cei n biţi pot fi modelaţi prin variabile logice. de exemplu bitul n. Indicaţie. iar cei cu valoarea 1. Consideram următoarele doua probleme: (a) O gospodina a făcut o serie de cumpăraturi şi are la dispoziţie doua sacoşe. un bit. Pentru n mare. va avea o singură valoare. numărul de partiţii ce trebuie testate devine mare 29 (pentru n = 10 este 511 iar pentru n = 100 este de ordinul 10 ). Numărul de scăderi efectuate indica valoarea părţii întregi. C este aceea a utilizării unui număr binar cu n biţi. iar pentru a elimina stările în care cele două submulţimi au componenţa inversă. Ambele probleme pot fi formalizate astfel: se considera o mulţime de numere pozitive.. 4. Propuneţi un algoritm care sa stabilească modul de plata a unui rest (restul este de cel puţin 4). Problema consta în a distribui cumpăraturile în cele doua sacose astfel încât diferenţa între greutăţile celor doua sacoşe sa fie cât mai mică.. biţii cu valoarea 0 indicând apartenenţa la mulţimea B. Pentru numere negative se aduna succesiv 1 până se obţine o valoare mai mare sau egala cu 0. Se încearcă repartizarea fişierelor în cele doua discuri astfel încât diferenţa dintre spatiile rămase libere sa fie cât mai mică. Numărul de partiţii distincte n-1 este 2 -1 daca.. În cazul în care este pozitiv se scade succesiv valoarea 1 până când se ajunge la o valoare mai mica strict decât 1.. Este vreo legătură între cele două probleme ? Găsiţi metode de rezolvare. Corectitudinea prelucrării derivă din faptul ca metoda realizează de fapt conversia în baza 2 a primului număr. Propuneţi un algoritm pentru determinarea părţii întregi a unui număr real. iar produsul se obţine prin înmulţirea succesivă a celui de al doilea număr cu puteri ale lui 2 şi prin însumarea acelor produse care corespund unor cifre nenule în reprezentarea binara a primului număr. Indicaţie.a2. 2.

for i:=1 to n do l[i]:=false.numef).Items. listbox1.Clear. inc(i). var l. dif.difmin:real. stare: '+inttostr(nrst).lopt:tablel.nrstmax:longword. end. nrst:=1.Items. sir2:=''. listbox1. nrst.add('Nr.n).Proiectarea algoritmilor O rutină în limbajul DELPHI este arătată mai jos: procedure TForm1. i:=1. listbox1. if dif<difmin then begin difmin:=dif. closefile(fis_in).Items. sir1:=''.add(' '). for i:=1 to n do read(fis_in.l). while l[i] do begin l[i]:=false.l). i:word.sir2:string. nrstopt:=1.add('Optim: '+inttostr(nrstopt)+' Diferenta: '+floattostr(difmin)).n-1))-1.add('Sacosa 1: '+sir1). listbox1. inc(nrst). l[i]:=true. nrstopt:=nrst. for i:=1 to n do if lopt[i] then sir1:=sir1+floattostr(a[i])+' ' else sir2:=sir2+floattostr(a[i])+' '.nrstopt.10 - . lopt:=l.a[i]).Button2Click(Sender: TObject).a. l[1]:=true. Introducere .dif. end. while not l[n] do begin dif:=calcdif(n.a. difmin:=calcdif(n. afisiter('Nr. maxim stari: '+inttostr(nrstmax)). sir1. reset(fis_in). end. readln(fis_in. nrstmax:=trunc(power(2.l).a. listbox1. begin assignfile(fis_in.Items.

button3. s2:=0. button1.Visible:=false.Visible:=true. iar funcţia calcdif calculaeză diferenţa dintre cele două sacoşe. Ea este prezentată mai jos. button2. Metoda este. begin s1:=0.Items. s1. O metodă mai bună.a:tabler. end.Visible:=false. după care se selectează elementele din şir în cele două submulţimi astfel încât. button4. aşa cum am specificat ineficientă. for i:=1 to n do if l[i] then s1:=s1+a[i] else s2:=s2+a[i]. result:=abs(s1-s2). în orice moment diferenţa dintre suma elementelor mulţimilor să fie minimă. end.11 - .Proiectarea algoritmilor listbox1. listbox1.add('Sacosa 2: '+sir2).s2:real. var i:word. Procedura afisiter afişează într-un box componenţa sacoşelor în fiecare stare generată. este aceea în care se sortează şirul de intrare. În legătură cu această metodă vom reveni. care nu garantează însă obţinerea soluţiei optime.Visible:=false. Introducere .Visible:=true. function calcdif(n:word.l:tablel):real.

Ele cuprind operatori şi operanzi. Limbajul de descriere a algoritmilor este numit şi pseudocod. MOD (restul împărţirii întregi). alfanumerice sau logice. Citire – Încărcarea unor variabile simple sau structurate de la dispozitivul de intrare. Unele probleme pot fi rezolvate utilizând o descriere matematică. DESCRIEREA ALGORITMILOR Rezolvarea în paşi a problemelor este descrisă. < (strict mai mic).Proiectarea algoritmilor 2. Prelucrările simple sunt: Atribuire – Unei variabile v i se atribuie valoarea unei expresii v ← < expresie> Expresiile pot fi numerice. v READ tabel. • Limbaj algoritmic – Este un limbaj artificial constituit dintr-un vocabular restrâns ce conţine simboluri şi cuvinte cheie asociate prelucrărilor şi identificatori pentru memorarea datelor. pentru a arăta apropierea de limbajele de programare. • logici: OR (sau). printr-o succesiune de afirmaţii prin care se precizează ordinea de efectuare a operaţiilor şi condiţiile de oprire. NOT (negaţie) • funcţii cu una din tipurile de mai sus. de obicei. / (împărţire). Descrierea algoritmilor . Fiecărui tip de prelucrare elementară îi corespunde un simbol grafic.12 - . Sunt acceptate şi expresii matematice. Limbaj algoritmic Permite. v De precizat că în cazul citirii secvenţiale a înregistrărilor dintr-un fişier sau o tabelă a unei baze de date trebuie indicat controlul sfârşitului de fişier utilizând funcţii care indică acest lucru. ≥ sau >= (mai mare sau egal). dar cu reguli sintactice mult mai libere. Din acest motiv pentru descrierea algoritmilor se folosesc: • Scheme logice – Permit descrierea algoritmului în mod grafic. cum ar fi funcţia EOF(fişier). dintr-un fişier sau dintr-un tabel al unei baze de date: READ v READ fişier. *(înmulţire). ≥ sau >= (mai mare sau egal). • relaţionali: = (egal). Important este ca descrierea algoritmului să fie clară şi fără ambiguităţi. DIV (împărţire întreagă). ≠ sau <> (diferit).1. Operatorii pot fi: • aritmetici: + (adunare). însă acesta nu este suficient de clar. -(scădere). variabila v având acelaşi tip cu expresia. Prelucrările succesive sunt indicate prin conectarea prelucrărilor elementare şi prin săgeţi. utilizând simboluri şi cuvinte cheie să se precizeze prelucrările simple şi cele structurate. ≤ sau <= (mai mic sau egal). > (strict mai mare). 2. AND (şi). unele detalii necesare pentru codificarea într-un limbaj de programare neputând fi precizate. Ca orice limbaj se bazează pe un set redus de cuvinte cheie şi reguli de sintaxă minime. ^ (ridicare la putere).

......... O structură condiţională cu o singură prelucrare se reprezintă sub forma: IF <condiţie> THEN <prelucrare> O structură cu mai multe ramuri se reprezintă utilizând mai multe IF –uri succesive. Structurile alternative sunt prezentate grafic în figura 2... altfel se execută <prelucrare 2>. se reprezintă prin: IF <condiţie> THEN <prelucrare 1> ELSE <prelucrare 2 > Dacă <condiţie> = T (adevărat) atunci se execută <prelucrare 1>.... O structură condiţională.13 - .. condiţionale şi repetitive.. <expresie> WRITE tabel.. Condiţia poate fi precizată înaintea prelucrării sau după aceasta.....2. Structura condiţională – Se utilizează atunci când. Varianta condiţionată anterior se scrie în pseudocod sub forma generală: WHILE <condiţie> DO <prelucrare> sau sub forma controlului unui contor: Descrierea algoritmilor .Proiectarea algoritmilor Scriere – Scrierea la dispozitivul de ieşire... Structuri repetitive – permit descrierea unor prelucrări repetitive.... se execută o ramură sau alta în funcţie de valoarea adevărată sau falsă a condiţiei... Acestea sunt prelucrări repetitive condiţionate anterior sau condiţionate posterior... IF <condiţie 1> THEN <prelucrare 1> ELSE IF <condiţie 2> THEN <prelucrare 2> ELSE IF <condiţie 3> THEN <prelucrare 3> ....... <prelucrarea n > fiecare dintre prelucrările 1... Structura secvenţială – O succesiune de n prelucrări se specifică astfel: <prelucrarea 1 > <prelucrarea 2 > ....n fiind prelucrări simple de tipul celor de mai sus.... <expresie> Prelucrările structurate sunt: secvenţiale.1. cu două ramuri de prelucrare.... numărul de repetări fiind determinat de o condiţie. în prezenţa unei condiţii..... într-un fişier sau într-un tabel a unei baze de date a unei expresii: WRITE <expresie> WRITE fişier...

Descrierea grafică a structurilor repetitive este arătată în figura 2.14 - . Descrierea algoritmilor . În modulul prelucrare trebuie să existe o modificare a condiţiei. Dacă condiţia nu este adevărată de la început. Reprezentarea grafică a structurii repetitive cu condiţia la sfârşit este reprezentată grafic în figura 3. prelucrarea se execută cât timp condiţia specificată este adevărată.1 Structuri condiţionale În prima formă. De asemenea este necesar ca în modulul de prelucrarea să existe posibilitatea modificării condiţiei de buclare astfel încât ea să nu se repete la infinit. Variantele cu un contor care ia valori între două limite v1 şi v2.Proiectarea algoritmilor v←v1 WHILE v ≤ v2 DO <prelucrare> v←v+pas sau FOR i← v1 . Structura repetitivă condiţionată posterior se scrie în pseudocod astfel: REPEAT <prelucrare> UNTIL <condiţie> Prelucrarea se execută cel puţin o dată şi se opreşte când condiţia este adevărată. pas DO <prelucrare> T condiţie F T condiţie F prelucrare 1 prelucrare 2 prelucrare Figura 2. altcum bucla se repetă la nesfârşit. v2 . la execuţie. prelucrarea nu se execută niciodată. modelate prin bucla WHILE sau FOR se execută de un număr finit de paşi.

. De exemplu pentru variabilele simple a. boolean şi şir de caractere.. tablouri) precizările privind caracteristicile acestora sunt obligatorii..15 - prelucrare T condiţie F Figura 3 Structura repetitivă condiţionată posterior .Proiectarea algoritmilor v=v1 T condiţie F prelucrare T prelucrare v ≤ v2 F v←v+pas Figura 2 Structuri repetitive condiţionate anterior 2. Declararea tipului se face sub forma: INTEGER a REAL b BOOLEAN c CHARCATER d În cazul datelor structurate declaraţiile sunt de tipul: pers=RECORD nume:CHARACTER prenume: CHARACTER nota:INTEGER.m2] Descrierea algoritmilor .. uşor de intuit. nu este necesară specificarea tipului de date. de obicei..2.d de tipul întreg. INTEGER t1[n1.b. tipul lor fiind...n2. Pentru datele structurate (înregistrări. Specificarea datelor Pentru datele simple. respectiv real.n2] REAL t2[n1.c. de regulă. m1.

c=0” ELSE WRITE „Ecuatie imposibila” ELSE c x1 ← − b WRITE „Ecuatie de gradul I.x1. Referirea la un element dintr-un tablou unidimensional se face sub forma t1i.b. Structura de decizie B1.b.b. este: REAL a.c. m1 ≤ j ≤ m2.c.3.x2 Descrierea algoritmilor .c IF a=0 THEN IF b=0 THEN IF c=0 THEN WRITE „Identitate. Exemple de algoritmi A.c.b.prenume.aria READ a. sau t2ij. în pseudocod. pers. 2. Vom folosi formula lui Heron A = p ⋅ ( p − a ) ⋅ ( p − b) ⋅ ( p − c) . a.Proiectarea algoritmilor Referirea la un câmp dintr-o înregistrare se va face sub forma: pers.x1 ELSE delta ← b 2 − 4 ⋅ a ⋅ c IF delta < 0 THEN b x1 ← − 2⋅a − delta x2 ← 2⋅a WRITE „Solutii complex conjugate:”. a.c a+b+c p← 2 aria ← p ⋅ ( p − a ) ⋅ ( p − b) ⋅ ( p − c) WRITE aria B. Algoritmul de calcul. Structura secvenţială Să se scrie un algoritm pentru calculul ariei unui triunghi oarecare cunoscânduse lungimile laturilor a.c ЄR. x=”.x2 READ a. unde p este semiperimetrul.Să se scrie un algoritm pentru rezolvarea ecuaţiei de gradul II: 2 a ⋅ x + b ⋅ x + c = 0 . pers. cu n1 ≤ i ≤n2.nota.delta.p.b. n1 ≤ i ≤n2.16 - . REAL a.b.b.nume.x1.

b)Să se afişeze cele 3 valori în ordine crescătoare. este aceea în care se presupune că valoarea minimă este dată de prima valoare. comparând variabilele două câte două: REAL a.min READ a. care poate fi generalizată.17 - . a)Să se scrie un algoritm pentru determinarea minimului celor 3 valori. după care aceasta se compară cu toate valorile următoare reţinându-se minimul la fiecare comparaţie.c.min READ a.c IF a < b THEN IF a < c THEN min←a ELSE min←c ELSE IF b < c THEN min←b ELSE min←c WRITE min O variantă mai compactă.x2 B2.b.Proiectarea algoritmilor ELSE IF delta=0 THEN b x1 = − 2⋅a WRITE „Solutie unica:”.b.c.b.x1 ELSE − b + delta x1 ← 2⋅a − b − delta x2 ← 2⋅a WRITE „Solutii reale distincte:”. a) O primă variantă se obţine uşor.c min←a IF b < min THEN min←b IF c < min THEN min←c Descrierea algoritmilor .b.x1.c. Se consideră trei valori reale a.b. REAL a.

b ELSE WRITE c. La proiectarea unei structuri repetitive trebuie stabilite: i) valorile iniţiale ale variabilelor care intervin în prelucrarea repetitivă.c IF a < b THEN IF b < c THEN WRITE a.a C.b.b.c IF (c < b) AND (b < a) THEN WRITE c. Descrierea algoritmilor . REAL a.b.b.c. două câte două valori: REAL a.c.b IF (b < c) AND (c < a) THEN WRITE b.c IF (a < b) AND (b < c) THEN WRITE a.a IF (a < c) AND (c < b) THEN WRITE a.a ELSE WRITE c.Proiectarea algoritmilor WRITE min b) O primă variantă este aceea în care se verifică fiecare variantă de ordonare.c.c ELSE IF a < c THEN WRITE a.18 - .b IF (c < a) AND (a < b) THEN WRITE c.b.c ELSE IF b < c THEN WRITE b.a. succesiv.b.c.c.a.c.a O altă variantă se obţine comparând.b ELSE IF a < c THEN WRITE b.b.min READ a.min READ a.a. ii) prelucrările care se repetă.b.a. iii) condiţia de oprire. Structuri repetitive.c IF (b < a) AND (a < c) THEN WRITE b.

n READ n S←0 i←1 REPEAT S←S+i3 i←i+1 UNTIL i > n b) Am putea aplica metoda de mai sus. n DO S←S+i3 WRITE S INTEGER S. ε > 0. adică calculând toţi termenii sumei şi adunându-i. c) INTEGER S.1). nЄN*. nЄN*. Dacă notăm termenul sumei x cu T(i) atunci putem scrie: T (i ) = T (i − 1) ⋅ .n REAL x. a) Calculul sumei poate fi descrisă prin următoarele trei variante echivalente INTEGER S. n(ε) fiind acea valoare a lui n pentru i =1 care raportul xi/i! < ε. Putem observa însă că volumul de calcul se reduce semnificativ dacă calculăm termenii succesivi unul în funcţie de precedentul.19 - .n READ n S←0 FOR i← 1.i. i INTEGER i. n ≤ n(ε).1).x i←1 S←0 T←1 WHILE i ≤ n DO T←T·x/i Descrierea algoritmilor . i =1 i =1 i! n 3 n xi ∑ i! .i. xЄ(0.n READ n S←0 i←1 WHILE i ≤ n S←S+i3 i←i+1 WRITE S n xЄ(0.Proiectarea algoritmilor xi Să se scrie algoritmi pentru calculul sumelor: a) ∑ i . b) ∑ .S READ n.i.

n] media← 0 i←1 WHILE i ≤ n DO ∑ xi i =1 n n Descrierea algoritmilor .Proiectarea algoritmilor S←S+T i←i+1 WRITE S c) Întrucât nu cunoaştem de la început numărul de repetări..b.20 - . x2.. Vom folosi algoritmul lui Euclid prin care cmmdc se determină prin împărţirea succesivă împărţitorului la ultimul rest. media READ n.b d←a i←b r←d MOD i WHILE r≠0 DO d←i i←r r←d MOD i WRITE i e) Să se scrie un algoritm pentru determinarea medie aritmetice a unui şir finit de numere x1.i. primul deîmpărţit fiind a.n]. x[1. iar primul împărţitor fiind b. ultimul deîmpărţit este cmmdc. Dacă restul este zero.r READ a.d. INTEGER a.. vom stabili că sumarea se face atâta timp cât termenii sumei sunt mai mari ca ε.. INTEGER i REAL x.n REAL x[1. Media se calculează cu relaţia: media = INTEGER i.ε S←0 i←1 T←x WHILE T ≥ ε DO S←S+T i←i+1 T←T·x/i WRITE S d) Să se scrie un algoritm pentru determinarea celui mai mare divizor comun a numerelor naturale a şi b..xn.S..

j=1. n DO IF xi < min THEN min←xi RETURN min Descrierea algoritmilor . Apelul unui subalgoritm se face cu parametri efectivi. Avantajul acestei tehnici rezidă în aceea că problemele elementare sunt mai uşor de înţeles şi rezolvat.. Vom reţine în vectorul b[m] minimele elementelor de pe linii.2..2. Tehnica rafinării succesive şi subalgoritmi Este o metodă prin care o problemă iniţială. complexă.2. Aceşti parametri au rolul de parametri formali şi nu trebuie să impună limite şi restricţii suplimentare. Structura unui subalgoritm are forma generală: <nume subalgoritm> (<parametri formali>) <date locale> <prelucrări> RETURN <rezultate> În funcţie de mediul de dezvoltare.n]. Considerăm matricea a[m.. Exemplu Să se determine cea mai mare valoare dintre minimele valorilor elementelor unei matrice pe linii. Algoritmul pentru determinarea minimului de pe linii: minim (real:n. Efectul unui subalgoritm este transmiterea către algoritmul apelant a unor parametri modificaţi sau modificarea directă a unor variabile în programul apelant. este descompusă în mai multe probleme care se rezolvă separat..Proiectarea algoritmilor media←media+xi i←i+1 media←media/n WRITE media 2.m şi apoi determinarea elementului maxim din vectorul bi. În acest scop subalgoritmii trebuie să definească un set de parametrii de apel care să permită utilizarea ei în multiple cazuri.m.x) INTEGER i REAL min min←x1 FOR i = 2. specifice aplicaţiei respective. întrucât la apeluri în diverse situaţii poate conduce la efecte necontrolate. subalgoritmii pot avea o serie de efecte colaterale care constau în modificarea unor variabile ale programului apelant. i=1.n pentru fiecare linie i=1.4. Din acest motiv se recomandă ca toate rezultatele să fie returnate prin parametri formali. Această ultimă situaţie nu este de dorit în practică.... Vom avea de rezolvat două subprobleme: determinarea minimului din vectorii linie aij.21 - .. De asemenea o procedură elaborată pentru o subproblemă poate fi utilizată pentru rezolvarea unui număr mare de probleme de acelaşi fel..

m]. 4.n. Exerciţii Scrieţi algoritmi pentru rezolvarea următoarelor probleme: n n 1 1. Se va considera precizia îndeplinită atunci când diferenţa dintre doi termeni ai şirului este mai mică ca ε..b[1. a) Să se determine toţi divizorii unui număr natural. h) Descrierea algoritmilor .m.xm maxim (real:m. Să se calculeze a) ∏ (i + 1) ..1. c) ∑ (− 1)i ⋅ . x2. a > 0. fn=fn-1+fn-1 (şirul Fibonacci). neglijând termenii mai mici ca ε: ∞ i ∞ ∞ ∞ x x 2 ⋅i x 2⋅i +1 xi a) ∑ . x[1.i READ n.x) INTEGER i REAL max max←x1 FOR i = 2. f0=1. m DO IF xi > max THEN max←xi RETURN max Algoritmul principal va fi: REAL a[1. d) ∑ (− 1)i +1 ⋅ (2 ⋅ i )! i = 0 (2 ⋅ i + 1)! i = 0 i i =1 i! i =0 3.. f) Să se genereze toate perechile de numere prime între ele mai mici ca o valoare dată. g) Să se scrie descompunerea în factori primi a unui număr natural.m...a FOR i ← 1.. d) Să se verifice dacă două numere sunt prime între ele. n DO xj←aij bi←minim(n. b) ∑ 2 i =1 (i!) i =1 2. b) ∑ (− 1)i ⋅ .5. Să se genereze primele N elemente şi să se calculeze cu precizia ε..b) RETURN maxmin 2.Proiectarea algoritmilor Algoritmul pentru determinarea maximului dintr-un şir. m DO FOR j ← 1. xn=(xn-1+a/xn-1). c) Să se verifice dacă un număr este prim sau nu. x1. limitele şirurilor a) xn=(1+1/n)n. f1=1.n].22 - .. Să se calculeze sumele următoare.x) maxmin←maxim(m. c) xn=fn/fn-1. maxmin INTEGER m. b) Să se determine toţi divizorii comuni a două numere naturale. b) x1=a.n]. e) Să se genereze toate numerele prime mai mici decât o valoare dată.

5. c) Să se determine valoarea obţinută prin inversarea cifrelor unui număr natural. a) Să se determine suma cifrelor unui număr natural.23 - . Descrierea algoritmilor . d) Să se determine reprezentarea în baza 2 a unui număr natural.Proiectarea algoritmilor Să se determine cele mai mare divizor comun şi cel mai mic multiplu comun folosind descompunerea în factori primi. b) Să se determine toate cifrele distincte dintr-un număr natural.

• Demonstrarea faptului că pornind de la precondiţii şi aplicând prelucrările specificate în algoritm se ajunge la satisfacerea postcondiţiilor.Înseamnă a stabili volumul de resurse (spaţiu şi timp) necesar pentru execuţia algoritmului pe o maşină de calcul. Se demonstrează că algoritmul funcţionează corect pentru orice date de intrare. De obicei. Principalul avantaj al acestei abordări îl reprezintă simplitatea. Ideea verificării este de a stabili care trebuie să fie starea la fiecare moment astfel încât în final să fie satisfăcute postcondiţiile. Se testează algoritmul pentru diverse instanţe ale problemei. Dezavantajul este reprezentat de faptul că uneori este dificil de găsit o demonstraţie.Proiectarea algoritmilor 3. Starea algoritmului este modificată prin atribuiri de valori variabilelor.Înseamnă a verifica dacă algoritmul conduce după un număr finit de prelucrări la obţinerea soluţiei problemei. În cazul prelucrărilor secvenţiale Verificării corectitudinii algoritmilor . Abordarea analitică poate însă conduce la o mai bună înţelegere a algoritmului şi la identificarea porţiunilor ce conţin eventuale erori. În analiza corectitudinii este utilă noţiunea de stare a unui algoritm înţeleasă ca ansamblul valorilor pe care le au variabilele prelucrate în cadrul algoritmului la un moment dat (pas al prelucrării). • Analiza complexităţii . O dată stabilite aceste stări intermediare este suficient să se verifice că fiecare prelucrare asigură transformarea stării care o precede în cea care o succede. prin găsirea unor situaţii în care algoritmul nu funcţionează corect. VERIFICAREA CORECTITUDINII ALGORITMILOR Proiectarea unui algoritm presupune şi analiza acestuia. In această situaţie algoritmul se descompune în subalgoritmi şi se demonstrează pentru fiecare parte corectitudinea. găsirea unei justificări a corectitudinii poate fi dificilă în cazul algoritmilor complecşi. Varianta experimentală permite uneori identificarea situaţiilor pentru care algoritmul nu funcţionează corect.24 - . • Identificarea proprietăţilor pe care trebuie să le satisfacă rezultatul (postcondiţiile problemei). În verificarea analitică a corectitudinii se parcurg următoarele etape principale: • Identificarea proprietăţilor datelor de intrare (precondiţiile problemei). se poate trage concluzia că acesta nu satisface cerinţele impuse. Pe de altă parte. Principalul avantaj îl reprezintă faptul că este garantată corectitudinea pentru orice date de intrare. ce constă din: • Verificarea corectitudinii . 3. o Analitică. iar principalul dezavantaj îl reprezintă faptul că testarea nu poate acoperi întotdeauna toate variantele posibile de date de intrare.1. Etapele verificării corectitudinii Pentru a stabili dacă un algoritm rezolvă problema pentru care a fost elaborat se poate alege una dintre următoarele variante: o Experimentală.

2. n. Dealtfel este uşor de găsit un contraexemplu (de exemplu şirul {2..n] astfel că setul de precondiţii este constituit doar din n ≥ 1 (şirul nu este vid). n − 1 DO IF ai+1 > ai THEN min ← ai ELSE min ← ai+1 RETURN min În acest caz prelucrarea din corpul ciclului conduce la min = min {ai.. Verificării corectitudinii algoritmilor . Dacă algoritmul se scrie sub forma: minim(n.ai} că min = min{a1.. 3... i. 1. Presupunem că min ≤ ak pentru orice k = 1.. care determină minimul unui şir finit de numere reale: minim(n. n DO IF min > ai THEN min ← ai RETURN min Analizând algoritmul de mai sus vedem că enunţul problemei nu impune nici o restricţie asupra tabloului a[1. La pasul i al ciclului FOR valoarea lui min se modifică astfel: • Dacă min ≤ ai+1 atunci min rămâne nemodificat.. Conform metodei inducţiei matematice rezultă că postcondiţia este satisfăcută.. Principala sursă de erori o reprezintă prelucrările repetitive în care se pot specifica în mod greşit iniţializările. Exemplu. 4}) pentru care algoritmul de mai sus nu funcţionează corect. prelucrările din corpul ciclului sau condiţia de oprire (continuare).Proiectarea algoritmilor (succesiuni de atribuiri). n.2.. • Dacă min > ai+1 atunci min se înlocuieşte cu ai+1 Astfel în oricare dintre variante se obţine că min ≤ ai+1... Considerăm următorul algoritm.25 - . Demonstrăm prin inducţie matematică după variabila i că min ≤ ai . an}. Cum min = a1 şi valoarea lui min este înlocuită doar cu una mai mică rezultă că min ≤ a1. 5. În schimb se poate demonstra că algoritmul returnează min{an-1. Rămâne să arătăm că postcondiţia rezultă în urma aplicării algoritmului.2.. Rămâne să arătăm că min ≤ ai+1.. Pentru a demonstra că o prelucrare repetitivă este corectă se foloseşte adesea metoda inducţiei matematice.a) min ← a1 FOR i ← 2.. verificarea este în general simplă constând în a analiza succesiv efectul fiecărei atribuiri asupra stării algoritmului.. deci algoritmul este corect. i = 1.. ai+1} astfel că nu mai poate demonstra că pornind de la min = min{a1.ai+1}. Postcondiţia este reprezentată de proprietatea valorii minime: min ≤ ai pentru orice i = 1.a) min ← a1 FOR i ← 1.

. structura alternativă şi structura repetitivă. y = b} (după A1) P2 = {aux = a. P3 → Q.2. Regula structurii secvenţiale Fie algoritmul A constituit din succesiunea de prelucrări (A1.26 - .. şi notăm P → Q .. Exemplu.3..2. Fie a şi b două valori întregi.. pentru i=1. A. cu A algoritmul şi cu Q postcondiţiile. iar postcondiţiile sunt {x = b. A. iar x şi y două variabile ce conţin valorile a şi b. y = a} (după A3) Este uşor de remarcat că P = P0. y = a}. Notăm cu Pi-1 şi Pi starea algoritmului înainte şi respectiv după efectuarea prelucrării Ai. Să se interschimbe valorile celor două variabile. Precondiţiile problemei sunt: {x = a. y = b} (înainte de A1) P1 = {aux = a. dacă următoarea afirmaţie este adevărată: A • Dacă datele problemei satisfac precondiţiile P atunci: (i)rezultatul satisface postcondiţiile Q. Regula structurii secvenţiale poate fi enunţată astfel: Dacă P → P0. y = b} (după A2) P3 = {aux = a. Elemente de analiză formală a corectitudinii Pentru a se introduce o disciplină în demonstrarea corectitudinii algoritmilor s-a dezvoltat o metodă formală de analiză bazată pe următoarea strategie: • pe baza precondiţiilor şi postcondiţiilor problemei se stabilesc pentru fiecare prelucrare aserţiuni privind valorile datelor şi relaţiile dintre ele. x = b.2.n şi Pn → Q. y = b}..Proiectarea algoritmilor 3. Verificarea poate fi descompusă la nivelul structurilor de prelucrare. Consideram prelucrările algoritmului: A1: aux ← x A2: x← y A3: y←aux Ai A Aserţiunile privind stările algoritmului sunt următoarele: P0 = {x = a.. Vom stabili reguli pentru cele trei structuri de bază: structura secvenţială. x = b. (ii)algoritmul A se termină după un număr finit de paşi. Pi −1 → Pi . atunci P → Q .Q) formează un algoritm corect. Pi −1 → Pi pentru i=1. Notăm cu P precondiţiile problemei.A2. Pentru fiecare dintre structurile de prelucrare există reguli care uşurează verificarea. pentru fiecare prelucrare se demonstrează că asigură satisfacerea aserţiunii care o urmează dacă este satisfăcută aserţiunea care o precede.An). Dacă însă algoritmul de mai sus se înlocuieşte cu: A1: x ← y A2: y ← x Ai Verificării corectitudinii algoritmilor . Spunem că tripletul (P. x = a.

Pot fi scrise şi următoarele reguli: a) Întărirea precondiţiei – Dacă R ⊂ P şi P → Q atunci R → Q . atunci P ∧ c → Q şi P ∧ c → Q . y = a} (după A2) P3 = {x = b. 1 1 B. y = b} (după A1) P2 = {x = a . P3 → Q. adică algoritmul rămâne corect dacă se reduc cerinţele pentru datele de ieşire. Pi −1 → Pi . Regula structurii alternative Considerăm stuctura: IF c THEN A1 ELSE A2 Dacă P şi Q sunt precondiţiile.b. Aceeaşi problemă poate fi rezolvată fără a folosi o variabilă auxiliară efectuând prelucrările: A1: x ← x . Regula sugerează că trebuie verificată corectitudinea fiecărei ramuri (atât când c este adevărată cât şi în cazul în care este falsă). Exemplu. atunci P → Q . b) Slăbirea postcondiţiei – Dacă Q ⊂ R şi P → Q atunci P → R .27 A A A A A A A Ai A A1 A2 .Proiectarea algoritmilor aserţiunile corespunzătoare sunt: {x = b.b. distincte: IF a < b THEN m←a ELSE m←b Verificării corectitudinii algoritmilor . y = b} (înainte de A1) P1 = {x = a . adică algoritmul rămâne corect dacă se particularizează datele de intrare. y = b}. pentru i=1. respectiv postcondiţiile atunci regula poate fi enunţată în modul următor: Dacă c este bine definită (poate fi evaluată). y = a} (după A3) Este uşor de remarcat că P = P0.3. Considerăm problema determinării minimului dintre două valori reale.y A2: y ← x + y A3: x ← y .2.x Aserţiunile privind stările algoritmului sunt următoarele: P0 = {x = a. În acest caz aserţiunile A1 şi A2 nu conduc la postcondiţia Q. atât după A1 cât şi după A2. c) Proprietăţi însoţitoare – Dacă P → Q1 şi P2 → Q2 atunci P ∧ P2 → Q1 ∧ Q2 .

precondiţia P şi postcondiţia Q. Dacă a < b atunci m = a < b deci m = min{a. În caz contrar (a > b) iar prelucrarea de pe ramura ELSE conduce la m = b < a deci din nou m = min{a.. Elementul esenţial în demonstrarea corectitudinii unei prelucrări repetitive îl reprezintă găsirea proprietăţii invariante. b}. Considerăm algoritmul: A ( ) A1: A2: A3: A4: A5: A6: minim(n.i} {min ≤ aj.. Întrucât toate structurile repetitive pot fi reorganizate astfel încât să conţină o structură condiţionată anterior o vom analiza doar pe aceasta..n} . j=1.. Dacă se demonstrează doar faptul că algoritmul produce rezultatul dorit fără a se analiza şi terminarea acestuia atunci despre algoritm se spune că este parţial corect. i=2} {min ≤ aj. C. (b) Aserţiunea I este invariantă: dacă I este adevărată înainte de efectuarea lui A iar c este adevărată atunci I rămâne adevărată şi după efectuarea lui A ( I ∧ c → I ). Exemplul 1. j=1. Condiţia c este a < b. Găsirea unui invariant elimină necesitatea demonstraţiei explicite prin inducţie matematică. rămâne adevărată după fiecare iteraţie iar când condiţia c devine falsă implică postcondiţiile. (c) La sfârşitul structurii repetitive (când c devine falsă) postcondiţia Q poate fi dedusă din I ∧ c → Q .2.. Regula structurii repetitive..28 - Verificării corectitudinii algoritmilor . b Є R. a ≠ b iar postcondiţia este m = min{a. Reluăm problema determinării minimului dintr-un şir finit de valori.2. Structura repetitivă este corectă dacă există o aserţiune I (numită invariant al prelucrării repetitive) asociată stării algoritmului şi o funcţie t : N → N (numită funcţie de terminare şi care depinde de numărul de ordine al iteraţiei) care satisfac proprietăţile: (a) Aserţiunea I este adevărată la începutul prelucrării repetitive (P → I). j=1. b}.. (d) După efectuarea prelucrării A valoarea lui t descreşte A ⎞ ⎛ ⎜ c ∧ t ( p ) = k → t ( p + 1) < k ⎟ .i-1} {min ≤ aj.Proiectarea algoritmilor Precondiţiile sunt a Є R. iar când valoarea lui t este 0 condiţia c devine falsă (algoritmul se termină după un număr finit de iteraţii).. b}..2. Considerăm structura: S: WHILE c DO A. Un algoritm este considerat complet corect atunci când se justifică şi faptul că produce rezultatul după un număr finit de operaţii.a) min← a1 i←2 WHILE i ≤ n DO IF min > ai THEN min ← ai i ← i+1 RETURN min {min=a1} {min=a1. Aceasta este o aserţiune particulară privind relaţiile dintre variabilele algoritmului care este adevărată înainte de intrarea în prelucrarea repetitivă. ⎟ ⎜ ⎠ ⎝ (e) Dacă c este adevărată atunci t(p) ≥ 1 (mai există cel puţin o iteraţie).

Proiectarea algoritmilor Precondiţia este reprezentată de n ≥ 1, iar postcondiţia este min ≤ xi, i = 1,2,.., n. Aserţiunile marcate după fiecare prelucrare sunt uşor de stabilit. Proprietatea invariantă este min ≤ aj, j =1,2,..,i-1. Într-adevăr, după prelucrarea A2 proprietatea este satisfăcută. Din aserţiunea specificată după A6 rezultă că proprietatea rămâne adevărată după fiecare iteraţie. Condiţia de oprire este i = n + 1 şi se observă că atunci când este satisfăcută, aserţiunea finală implică postcondiţia. Funcţia de terminare este t(p) = n + 1 - ip, unde ip este valoarea indicelui i corespunzător iteraţiei p. Cum ip+1 = ip + 1 rezultă că t(p + 1) < t(p), iar t(p) = 0 implică i = n + 1 adică condiţia de oprire a algoritmului. Exemplul 2. Analizăm algoritmul lui Euclid pentru determinarea celui mai mare divizor comun a două numere naturale nenule: Cmmd(a,b) d←a i←b r ← d MOD i {restul împărţirii lui d la i} WHILE r ≠ 0 DO d←i i← r r ← d MOD i RETURN i Precondiţiile sunt: a, b Є N*, iar postcondiţia este: i = cmmdc(a,b). Considerăm proprietatea I ca fiind cmmdc(a, b) = cmmdc(d, i) şi funcţia t definită prin t(p) = rp unde rp este restul obţinut la iteraţia p. Pentru a arăta că I este o proprietate invariantă este suficient să arătăm că dacă r ≠ 0 atunci cmmdc(d, i) = cmmdc(i, r). Notăm d1 = cmmdc(d, i) şi d2 = cmmdc(i, r). Pe de altă parte d = i· q + r. Se pot verifica uşor următoarele implicaţii: d1|d şi d1|i → d1|d-i·q = r → d1|i şi d1|r → d1 ≤ d2 d2|i şi d2|r → d2|i·q+r = d → d2|i şi d2|d → d2 ≤ d1 Rezultă că d1 = d2, deci I satisface proprietăţile (a) şi (b). Când ipoteza c devine falsă (r = 0) se obţine că cmmdc(i,r) = i adică este satisfăcută şi proprietatea (c). Cum funcţia de terminare este chiar valoarea restului, iar acesta descreşte de la o iteraţie la alta până devine nul rezultă că sunt satisfăcute şi proprietăţile (d) şi (e). Observaţie. Invarianţii pot fi utilizaţi nu numai pentru a determina corectitudinea unui algoritm ci şi ca instrument de proiectare a algoritmilor, în sensul că identificarea unei proprietăţi invariante poate fi văzută ca o etapă preliminară elaborării unui ciclu. Invariantul poate fi considerat ca o specificaţie pentru ciclul respectiv şi poate fi utilizat în identificarea prelucrărilor necesare pentru iniţializare, pentru corpul ciclului şi în identificarea condiţiei de oprire (continuare) a ciclului. Exemplul 3. Să considerăm calculul sumei, S, a primelor n numere naturale (n ≥ 1). Precondiţia este P ={ n ≥ 1 } iar postcondiţia este Q = {S = 1 + 2 + ::: + n}. Întrucât suma va fi calculată adăugând succesiv termenul curent, i, un invariant adecvat ar fi S = 1 + 2 + .. + i. Pentru a asigura validitatea acestui invariant, termenul curent trebuie pregătit chiar înainte de a fi adăugat. Pe de altă parte pentru a ne asigura că la finalul ciclului postcondiţia este satisfăcută rezultă că la ieşirea din ciclu variabila i trebuie să Verificării corectitudinii algoritmilor - 29 -

Proiectarea algoritmilor aibă valoarea n. Astfel condiţia de continuare a ciclului WHILE ar trebui să fie i < n. Toate aceste observaţii conduc la algoritmul: Sum(n) i←1 S←1 WHILE i < n DO i ← i+1 S←S+i RETURN S Este uşor de remarcat faptul că există şi alte variante corecte de calcul a sumei. Una dintre acestea este: Sum(n) i←1 S←0 WHILE i ≤ n DO S←S+i i ← i+1 RETURN S Corectitudinea acestui algoritm poate fi demonstrată folosind invariantul: S = 1+2+...+(i-1). 3.3. Exerciţii Să se demonstreze corectitudinea următorilor algoritmi: 1. Algoritmul lui Euclid (varianta fără variabile ajutătoare): Cmmd2(a,b) WHILE a≠0 and b ≠ 0 DO a ← a mod b IF a ≠ 0 THEN b ← b mod a IF a ≠ 0 THEN r←a ELSE r←b RETURN r 2. Algoritmul lui Euclid (varianta bazată pe scăderi succesive):

Verificării corectitudinii algoritmilor - 30 -

Proiectarea algoritmilor Cmmd3(a,b) WHILE a≠b DO IF a > b THEN a←a–b ELSE b←b–a RETURN a 3. Calculul mediei aritmetice a unui şir finit de valori: Medie(n,x) S←0 i←1 WHILE i ≤ n DO S ← S+xi i ← i+1 S ← S/n RETURN S 4. Determinarea părţii întregi a unui număr real: partintr(x) a←x IF x ≥ 0 THEN WHILE a ≥ 1 DO a ← a –1 ELSE WHILE a < 0 DO a ← a +1 RETURN x-a 5. Căutare secvenţială. Se consideră un tablou x1, x2,..,xn care conţine valoarea (a) Să se afle prima poziţie pe care se află valoarea x0; (b) Să se afle toate poziţiile pe care se află x0 în tabloul x. Cauta1(n,x,x0) i←1 WHILE xi ≠ x0 DO i ← i+1 RETURN i b) Cauta2(n,x,x0) i←1 j←0 WHILE i ≤ n DO IF xi = x0 THEN j ← j+1 pozj ← i i ← i+1 RETURN j,poz

x0.

a)

Verificării corectitudinii algoritmilor - 31 -

De asemenea calculul unui polinom de grad n. Dacă se prelucrează o valoare numerică. În majoritatea situaţiilor. În cazul prelucrării unei matrice de dimensiune m x n. De exemplu o matrice 100 x 100 care are numai 50 de elemente nenule (matrice rară) poate fi memorată în mai multe feluri: • Tablou 100 x 100. Aceasta este determinată. Dacă prelucrările se fac la nivel de caracter atunci dimensiunea problemei este dată de numărul de caractere. în principal. Prin resurse necesare înţelegem: • Spaţiul maxim de memorie necesar pentru execuţia algoritmului. ţinând seama şi de situaţia concretă. Trebuie luată în considerare situaţia alocării dinamice a memoriei. De exemplu. când aceasta poate avea valori diferite în puncte diferite ale algoritmului. Dacă un algoritm necesită resurse foarte mari. dimensiunea problemei poate fi dată de mai mulţi parametri care o caracterizează. cu trei coloane. Uneori dimensiunea problemei depinde de tipul prelucrării. ANALIZA COMPLEXITĂTII ALGORITMILOR 4. determinarea elementului minim dintr-un tablou cu n elemente. • Timpul necesar pentru execuţia tuturor operaţiilor cuprinse în algoritm. De exemplu. atunci dimensiunea problemei este dată de numărul componentelor din tablou. dimensiunea problemei este m·n. • Tablou 50 x 3. conduce tot la o problemă de dimensiune n. adică [lg2n]+1. În alte cazuri. De asemenea printr-o asemenea analiză se pot compara doi sau mai mulţi algoritmi din punct de vedere al eficienţei. dimensiunea problemei este dată de numărul de cuvinte. de volumul datelor de intrare. În general un algoritm eficient solicită mai multă memorie. cu 10000 locaţii de memorie. Scopul analizei complexităţii Analiza complexităţii are drept scop aprecierea calităţii unui algoritm. este evident că utilizarea lui este ineficientă. Analiza complexităţii algoritmilor . volumul de resurse necesar pentru execuţia unui algoritm depind de dimensiunea problemei de rezolvat. coloana şi valoarea. Această analiză este utilă pentru a aprecia dacă algoritmul respectiv utilizează un volum de resurse acceptabile. dacă prelucrările se fac la nivel de cuvânt. Dacă datele care se prelucrează sunt forma unor tablouri. al căror cost depăşesc valoarea beneficiilor obţinute prin aplicarea respectivului algoritm. De exemplu la prelucrarea unui text. iar utilizarea unui volum de memorie mic necesită algoritmi mai complicaţi. modul de reprezentare influenţează rapiditatea calculelor. Rezultă 150 de locaţii de memorie. prin determinarea resurselor necesare pentru execuţia algoritmului pe o maşină de calcul. Spaţiul de memorie necesar pentru memorarea datelor este influenţat de modul de reprezentarea datelor.32 - . În cazul cel mai general acest lucru este dat numărul de biţi necesari pentru memorarea datelor.Proiectarea algoritmilor 4. adunarea a două matrice reprezentate în varianta a II-a (cu trei coloane) este mai complicată decât în situaţia reprezentării normale. În general se alege o soluţie de compromis. indicând linia. n (de exemplu dacă se verifică că numărul n este prim) atunci ca dimensiune a problemei se consideră numărul de biţi necesari pentru reprezentarea lui n. conduce la o problemă de dimensiune n.1. Pe de altă parte.

Proiectarea algoritmilor În continuare vom analiza dependenţa dintre timpul de execuţie. 2. numite operaţii de bază (de exemplu în operaţii de sortare se pot considera doar operaţiile de comparare şi mutare a elementelor) şi/sau să se considere că timpul de execuţie a acestora este unitar (este acelaşi pentru toate operaţiile. operaţiile logice (AND . comparaţiile între două valori. În acest fel timpul total de execuţie va fi dat de numărul operaţiilor elementare. înmulţire. Operaţiile elementare sunt cele aritmetice (adunare. Timpul de execuţie al întregului algoritm se obţine însumând timpii de execuţie a prelucrărilor componente.33 - .prelucrările se efectuează în mod secvenţial . Vom considera un model de calcul (numit şi maşină de calcul cu acces aleator) caracterizat prin: . Exemplul 1. uneori este suficient să se contorizeze doar anumite tipuri de operaţii elementare. Algoritmul de rezolvare poate fi descris prin: Suma(n) 1: S ← 0 2: i ← 1 3: WHILE i ≤ n DO 4: || S ← S + i 5: || i ← i+ 1 RETURN S În algoritmul de mai sus operaţiile care sunt contorizate sunt numerotate. împărţire). scădere.operaţiile elementare se execută în acelaşi timp indiferent de valoarea operanzilor . i =1 n Dimensiunea acestei probleme este n. şi dimensiunea problemei. întrun şir de caractere timpul de acces este acelaşi pentru orice element din şir) A stabili o unitate de măsură înseamnă a stabili care sunt operaţiile elementare şi a considera ca unitate de măsură timpul de execuţie a acestora. Timpi de execuţie În continuare vom nota cu T(n) timpul de execuţie al unui algoritm pentru rezolvarea unei probleme de dimensiune n. reflectat prin numărul de operaţii. NOT). Pentru a stabili timpul de execuţie trebuie stabilit un model de calcul şi o unitate de măsură. Considerăm problema calculului ∑i . de exemplu. Timpul de execuţie al algoritmului poate fi determinat folosind tabelul de costuri: Analiza complexităţii algoritmilor . deşi.timpul de acces la o informaţie nu depinde de poziţia acesteia (de exemplu. Cum scopul calculului timpului de execuţie este acela de a compara calitatea algoritmilor. 4. operaţiile de înmulţire şi împărţire sunt mai costisitoare ca cele de adunare sau scădere). OR .

În practică nu este necesară o analiză atât de detaliată. Prin operaţia de bază se înţelege operaţia care contribuie cel mai mult la timpul de execuţie Analiza complexităţii algoritmilor .p) 1: FOR i= 1. Să considerăm problema calculului produsului a două matrici: A de dimensiune m x n şi B de dimensiune n x p. adică timpul de execuţie este proporţional cu dimensiunea problemei.n. Presupunând că toate operaţiile aritmetice şi de comparare au acelaşi cost unitar. p DO 3: cij ← 0 4: FOR k= 1. Prelucrarea repetitivă de mai sus poate fi înlocuită cu FOR i ← 1.Proiectarea algoritmilor Operaţie 1 2 3 4 5 Cost Nr. Dacă incrementarea lui i şi controlul depăşirii valorii n au acelaşi cost (= 1). n DO S ← S+i. datorită controlului limitelor pentru contor. Exemplul 2. Se observă că valoarea costurilor operaţiilor elementare influenţează doar constantele care intervin în T(n). De remarcat că instrucţiunea FOR se repetă de n+1 ori. T(n) = c1+ c2+(n+1)· c3+n· c5.p)=4·m·n·p+5·m·p+4·m+2. În acest caz dimensiunea problemei este dată de trei valori (m. tabelul costurilor este: Operaţie 1 2 3 4 5 Cost Nr. Algoritmul de calcul poate fi descris prin: Produs(a.b. ci este suficient să se identifice operaţia de bază şi să se estimeze numărul de repetări ale acestuia. repetări c1 1 c2 1 c3 n+1 c4 n c5 n Însumând timpii de execuţie se obţine T(n) = c1+ c2+n·( c3+ c4+ c5)+ c3 = =k1·n+k2. n DO 5: cij ←cij + aik · bkj RETURN c Costul prelucrărilor de pe liniile 1.2 şi 4 reprezintă costul gestiunii contorului şi va fi tratat global.p). repetări 2·(m+1) 1 2·(p+1) m 1 m·p 2·(n+1) m·p 2 m·p·n Rezultă timpul de execuţie în acest caz: T(m.n.m.34 - . În acest caz. atunci ciclul FOR costă 2·(n+1).n. n DO 2: FOR j= 1. pentru o buclă care se repetă de n ori.

Exemplul 3. atunci prelucrarea 4 se va efectua de fiecare dată. În exemplul de mai sus se poate considera ca operaţie de bază operaţia de înmulţire. iar algoritmul de rezolvare este: Cautare(n.m...35 - . Dacă cea mai mică valoare se află pe prima poziţie atunci prelucrarea 4 nu se efectua niciodată.Proiectarea algoritmilor al algoritmului şi este operaţia ce apare în ciclul cel mai interior.xn. în acest caz. În acest caz costul execuţiei algoritmului ar fi T(n.. iar T(n) = 4·n – 1...p)=m·n·p.n) 1: m ← x1 2: FOR i = 2.x) 1: gasit ← false 2: i ← 1 3: WHILE (gasit = false) and (i ≤ n) DO 4: || IF v = xi THEN 5: || gasit ← true 6: || ELSE 7: || i←i+1 RETURN gasit Considerând prelucrările de cost unitar rezultă: Analiza complexităţii algoritmilor . Algoritmul este: Minim(x. x2.xn... putem considera ca operaţie de bază comparaţia efectuată în prelucrarea 3. Considerăm algoritmul pentru determinarea minimului dintr-un şir x1. Acesta este cazul cel mai defavorabil. repetări 1 1 n-1 τ(n) Spre deosebire de exemplele anterioare. rezultând T(n) = n -1. x2. în exemplul de mai sus. Acesta este cazul cel mai favorabil. iar τ(n)=0. De remarcat că. nu putem stabili apriori de câte ori se repetă operaţia 4. iar T(n) = 3·n. Numărul de prelucrări depinde valorile din şir.. Exemplul 4. adică τ(n) = n – 1. Dimensiunea problemei este dată de numărul n de elemente din şir. Considerăm problema căutării unei valori v în şirul x1. Dacă însă şirul este ordonat descrescător. Dimensiunea problemei este n.. n DO 3: IF m > xi THEN 4: m ← xi RETURN m Tabelul costurilor pe prelucrări este: Operaţie 1 2 3 4 Cost 1 2n 1 1 Nr..

τ3(n). trebuie apreciat. iar T(n)= 1 + 1 + 3·(n+1)+n+n=5·(n+1).7 Cost 1 1 3 1 1 1 Nr.. iar Tk(n) reprezintă timpul de execuţie corespunzător variantei k. Cazul cel mai defavorabil este acela în care valoarea v nu se află în şir şi atunci τ1(n)=n. În ceea ce priveşte τ1(n). atunci este clar că el este ineficient. care este frecvenţa de apariţie a celui mai defavorabil caz. Cel mai defavorabil caz este prezintă interes întrucât dă cel mai mare timp de execuţie pentru orice set de date de intrare. acestea iau următoarele valori: ⎧k valoarea se afla in sir τ 1 (n) = ⎨ deci 1 ≤ τ1(n) ≤ n ⎩n valoarea nu se afla in sir unde k reprezintă prima poziţie în care este găsită valoarea v ⎧1 valoarea se afla in sir τ 2 ( n) = ⎨ ⎩0 valoarea nu se afla in sir ⎧k − 1 valoarea se afla in sir τ 3 ( n) = ⎨ deci 0 ≤ τ3(n) ≤ n ⎩n valoarea nu se afla in sir Cel mai favorabil caz este acela în care valoarea v se află pe prima poziţie din şir şi τ1(n)=1.2. iar T(n)= 1 + 1 + 3·2+1+1=10. pentru o problemă dată. Timp mediu de execuţie reprezintă valoarea medie a timpul de execuţie al unui algoritm atunci când datele de intrare sunt repartizate probabilistic pe domeniul lor de existenţă. chiar pentru cazul cel mai favorabil. timpii de execuţie sunt mari. τ2(n). υ (n) υ ( n) Analiza complexităţii algoritmilor . atunci timpul mediu de execuţie este dat de relaţia: Tm (n) = ∑ Tk (n) ⋅ Pk k =1 υ (n) Dacă toate cazurile sunt echiprobabile. Dacă υ(n) reprezintă numărul variatelor posibile pentru datele de intrare. Dacă pentru un algoritm oarecare. τ2(n)=0. k = 1. τ3(n)=0.. Pk reprezintă probabilitatea de apariţie a variantei k.. repetări 1 1 τ1(n) + 1 τ1(n) τ2(n) τ3(n) Am alocat costul egal cu 3 pentru instrucţiunea WHILE deoarece conţine trei verificări ale unei expresii logice.36 - . τ3(n)=n. τ2(n)=1. atunci: 1 Pk = .Proiectarea algoritmilor Operaţie 1 2 3 4 5 6. Pe de altă parte. Cel mai favorabil caz ne indică în ce situaţie timpii de execuţie sunt cei mai mici.

.5 – valoarea v nu se află în tablou În acest caz..5 – valoarea v se află în tablou.p=0. Cum avem n cazuri pentru poziţionarea în şir şi încă un caz în care valoarea nu se află în şir.2. Datorită dificultăţilor de estimare a timpului mediu.p=0.. n + 1 n +1 Timpul corespunzător cazului în care valoarea v se află pe poziţia k este: Tk (n) = 5 ⋅ (k + 1) iar timpul pentru situaţia în care valoarea v nu se află în şir este: Tn+1 (n) = 5 ⋅ (n + 1) υ (n) Tm (n) = ∑ T ( n) k =1 k υ (n) = 5 n+1 5 ⎡ (n + 1) ⋅ (n + 2 ) ⎤ ⋅ ∑ (k + 1) = ⋅⎢ + n + 1⎥ 2 n + 1 k =1 n +1 ⎣ ⎦ 5 ⋅ (n + 4) 2 Problema principală în asemenea situaţii o constituie stabilirea distribuţiei datelor de intrare. în practică se estimează timpul pentru cazul cel mai defavorabil. pentru problema de mai sus s-ar putea considera şi ipoteza: . Rezultă: 1 Pk = . Tm (n) = 4. timpul mediu de execuţie este: 1 1 n 1 5 Tm (n) = ⋅ ⋅ ∑ 5 ⋅ (k + 1) + ⋅ 5 ⋅ (n + 1) = ⋅ (3 ⋅ n + 5) 2 n k =1 2 4 Se constată că timpul mediu de execuţie depinde de ipotezele acceptate pentru datele de intrare şi nu este o medie aritmetică între timpul corespunzător cazului cel mai nefavorabil şi cel corespunzător cazului cel mai favorabil.37 - . x2. Considerăm că elementele şirului sunt distincte... O măsură utilă în acest sens este Analiza complexităţii algoritmilor . Vom calcula timpul mediu în ipoteza că valoarea v se poate afla în oricare din poziţiile din şir cu aceeaşi probabilitate. atunci υ(n) = n + 1. Ordin de creştere Pentru a aprecia eficienţa unui algoritm nu este necesară cunoaşterea exactă a expresiei timpului de execuţie.3... Mai degrabă interesează modul în care variază timpul de execuţie o dată cu creşterea dimensiunii problemei. întrucât acesta diferă de timpul corespunzător cazului cel mai defavorabil printr-o constantă.xn (exemplul 4). iar probabilitatea de a se afla pe oricare din poziţiile din şir este aceeaşi – 1/n .. k = 1. Considerăm problema căutării unei valori într-un şir x1.Proiectarea algoritmilor υ (n) Tm (n) = ∑ T ( n) k =1 k υ ( n) Exemplu. Timpul mediu de execuţie are relevanţă în situaţiile în care cazul cel mai defavorabil este puţin probabil să apară. De exemplu.

a) Notaţia Θ. termenii diferiţi de cel dominant sunt neglijabili. T(n).Proiectarea algoritmilor ordinul de creştere. spunem că este Θ(g(n) dacă T(n) Є Θ(g(n). Notaţii asimptotice Pentru a uşura analiza asimptotică şi pentru a permite gruparea algoritmilor în clase în funcţie de ordinul de creştere a timpului de execuţie (făcând abstracţie de eventualele constante ce intervin în expresiile detaliate ale timpilor de execuţie) s-au introdus nişte clase de funcţii şi notaţii asociate. c) Dacă T(n) = a·lgn. Practic.1) ⎬ ⎭ ⎩ 0 ≤ c1 ⋅ g (n) ≤ f (n) ≤ c2 ⋅ g (n) ∀n > n0 Despre timpul de execuţie al unui algoritm. b) Dacă T(n) = a·n2 + b·n+c. k > 0 n→∞ g ( n) Analiza complexităţii algoritmilor . Dacă T(n) = a·n + b. În acest caz avem o dependenţă pătratică a ordinului de creştere. d) Dacă T(n) = a·2n atunci T(k·n) = a·2k·2n= a·(2n)k. Dacă considerăm timpii T1(n) = 10·n + 10 şi T2(n) = n2.4. c2 ∈ R+ . adică termenul dominant creşte exponenţial. 4. În practică se mai foloseşte notaţia abuzivă T(n)= Θ(g(n). Să precizăm că prin lg înţelegem logaritm în baza 2. Matematic. În acest caz avem o dependenţă liniară a ordinului de creştere. Pentru o funcţie g: N → R+. timpul de execuţie crescând cu o constantă. adică în acest caz termenul dominant nu se modifică. termenul dominant creşte de k2 ori. prin notaţia f(n) Є g(n) înseamnă că f(n) şi g(n) sunt asimptotic echivalente. Θ(g(n)) reprezintă mulţimea de funcţii: * ⎧ f : N → R. T(k·n) = a·k2·n2 + b·k·n+c. acest lucru se traduce prin: f ( n) lim = k. Acesta este determinat de termenul dominant din expresia T(n) în funcţie de dimensiunea n a problemei. Exemple. Acest tip de analiză se mai numeşte şi analiză asimptotică. Întrucât problema eficienţei este importantă la valori mari ale lui n (teoretic n → ∞).38 - . atunci T(k·n) = a·lgn +a·lgk. ∃c1 . n0 ∈ N astfel incat ⎫ Θ( g (n )) = ⎨ (4. (a > 0) atunci la creşterea lui n de k ori. termenul a) dominant creşte şi el de k ori. (a > 0) atunci la creşterea lui n de k ori. În cadrul analizei asimptotice se consideră că un algoritm este mai eficient decât altul dacă ordinul de creştere al timpului de execuţie al primului este mai mic decât ordinul de creştere al celui de-al doilea. analiza complexităţii interesează doar în asemenea situaţii. atunci se observă cu uşurinţă ca T1(n) > T2(n) pentru n ≤ 10. Relaţia între ordinele de creştere are semnificaţie doar pentru dimensiuni mari ale problemei. Acest lucru justifică considerarea numai a termenului dominant. Prin urmare un algoritm asimptotic mai eficient decât altul reprezintă varianta cea mai bună doar în cazul problemelor de dimensiuni mari. T(k·n) = a·k·n + b. deşi ordinul de creştere al lui T1 este mai mic decât al lui T2. Acest lucru este justificat de faptul că pentru n mare.

deci T(n) Є Θ(n) (este suficient să alegem c1=3. Figura 4. iar în figura 4. aşa cum rezultă din figura 4. n0=1). c1·n ≤ T(n) ≤ c2·n. pentru n ≤ 50 pentru exemplul 3 (determinare minim din şir) – 3·n ≤ T(n) ≤ 4·n-1. deci T(n) Є Θ (n).Proiectarea algoritmilor Să considerăm funcţia f(n)=n2+5·n·lgn+10 şi g(n)=n2.. c1·g(n) şi c2·g(n). c1·g(n) şi c2·g(n). condiţia este respectată.2.+ a1·x+a0. atunci T(n) Є Θ (nk)..39 - .1 se poate vedea că este suficient să considerăm n > n0= 4 pentru ca relaţia 0 ≤ c1 ⋅ g (n) ≤ f (n) ≤ c2 ⋅ g ( n) să fie respectată. În general se poate demonstra că dacă T(n) = ak·xk+ ak-1·xk-1+. pentru n ≤ 50. Cu constantele c1=1 şi c2=4 vom verifica grafic pentru ce valori ale lui n. pentru n ≥ n0. Figura 4.2.2 Reprezentarea funcţiilor f(n). pentru n ≤ 10 Din figura 4. Pentru valori mari. c2=4. din Analiza complexităţii algoritmilor . 4. Putem stabili forma funcţiei g . are loc inegalitatea 0 ≤ c1 ⋅ g (n) ≤ f (n) ≤ c2 ⋅ g ( n) . În figura 4. c1.exemplul 1 (calcul sumă) – T(n) = k1·n + k2 – putem lua c1=k1 şi c2=k1+1 şi n0 > k2.1 sunt reprezentate cele 3 funcţii pentru n ≤ 10. Într-adevăr. c2 şi valorile lui n0 şi în cazul exemplelor analizate mai sus (pct.2): .1 Reprezentarea funcţiilor f(n).

k n Dacă notăm cu c1 = ak-ε şi c2 = ak+ε atunci relaţia de mai sus se scrie: c1 ⋅ n k ≤ T (n) ≤ c2 ⋅ n k . dacă T(n)=O(n) atunci T(n)=O(nd) d ≥ 1.+ a1·x+a0.. ak > 0 atunci T(n)= O(nd) pentru orice d ≥ k. În astfel de situaţii se analizează comportarea asimptotică a timpului de execuţie în cazul cel mai defavorabil. b) Notaţia O. în exemplul 4. Ω(g(n)) reprezintă mulţimea de funcţii: * ⎧ f : N → R. incluziunea fiind strictă.40 - . sau lim T ( n) ≤ ak + ε . k fiind o valoare strict pozitivă n →∞ g ( n ) Din definiţiile lui Θ şi O rezultă că Θ( g (n)) ⊂ O( g (n)) . n0 ∈ N astfel incat ⎫ O( g (n )) = ⎨ (4. ∃c ∈ R+ . pentru n > n0. Astfel. . vom spune că algoritmul are ordinul de complexitate O(n) şi nu O(n2). ∃c ∈ R+ . Evident. n0 ∈ N astfel incat ⎫ Ω(g (n )) = ⎨ (4. c) Notaţia Ω – Pentru o funcţie g: N → R+.în situaţia în care timpul de execuţie nu depinde de volumul acestora.2) ⎬ ⎩ 0 ≤ f (n) ≤ c ⋅ g (n) ∀n > n0 ⎭ Această clasă de funcţii permite descrierea comportării unui algoritm în cazul cel mai defavorabil. pentru orice set de date de intrare. În general. Întrucât interesează comportarea algoritmului pentru date arbitrare. adică timp de execuţie constant.3) ⎬ ⎩ 0 ≤ c ⋅ g (n) ≤ f (n) ∀n > n0 ⎭ altfel a k − ε ≤ Analiza complexităţii algoritmilor . Dacă f(n) Є O(g(n)) înseamnă că f(n) creşte asimptotic la fel de repede ca g(n). în analiza algoritmilor este util să se pună în evidenţă cea mai mică margine superioară. fără a se face referire la celelalte situaţii. Astfel spus: f ( n) lim ≤ k . vom nota T(n)=Θ(1).Proiectarea algoritmilor T ( n) = ak n→∞ n k Rezultă că ∃ ε > 0 şi n0(ε) astfel încât T (n) / n k − a k < ε pentru n > n0(ε). dacă T(n) = ak·xk+ ak-1·xk-1+. chiar dacă afirmaţia este corectă din punct de vedere al definiţiei. Pentru o funcţie g: N → R+. Prin urmare dacă T(n)=Θ(g(n)) atunci T(n) = O(g(n)). Folosind definiţia lui O se verifică uşor că dacă g1(n) < g2(n) pentru n > n0.. O(g(n)) reprezintă mulţimea de funcţii: * ⎧ f : N → R.în cazul exemplului 4 (căutarea unei valori în şir) s-a obţinut 10 ≤ T(n) ≤ 5·(n+1) ceea ce sugerează că există cazuri în care numărul de operaţii nu depinde de dimensiunea problemei (valoarea căutată se află pe prima poziţie din şir). Prin urmare. iar f ( n) ∈ O ( g1 ( n)) atunci f (n) ∈ O ( g 2 (n)) . este suficient să specificăm o margine superioară pentru timpul de execuţie. În această situaţie T (n) ≠ Θ(n) deoarece nu poate fi găsit c1·n ≤ T(n).

Dacă numărul de repetări este n. atunci costul structurii alternative va fi: O(max { g1(n). adică f ( n) lim ≥ k . Dacă f (n) ∈ Ω( g (n)) înseamnă că f(n) creşte asimptotic cel puţin la fel ca g(n)..2. De exemplu să considerăm următoarea prelucrare: m←1 FOR i ← 1. n →∞ g ( n ) Din definiţii se observă că Θ( g (n)) ⊂ Ω( g (n)) incluziunea fiind strictă. g2(n).. g2(n). g2(n)}). determinarea ordinului de complexitate în cazul cel mai defavorabil se consideră numărul maxim de iteraţii. În exemplul 4 avem T(n) = Ω(1) atunci când valoarea căutată se află pe prima poziţie.41 - .An şi fiecare din acestea au ordinul de complexitate O(gi(n)).n.... n i =1 Clase de complexitate. iar dacă în interiorul buclei prelucrările sunt de cost constant atunci de obţine ordinul de complexitate O(n) sau Θ(n).. în care indicii variază între 1 şi n. gn(n)}).. lim n k = 0. m DO Θ(1) Cum pentru fiecare i se obţine m = 3i rezultă că timpul de execuţie este de forma: T (n) = ∑ (3i + 1)∈ Θ(3n ) . limita putând să fie şi infinită. lim a n = 0. atunci obţinem un ordin de complexitate O(n2) sau Θ(n2). Dacă avem o structură secvenţială formată din prelucrările A1. lim a n = 0... Relaţia dintre cele 3 mari clase de funcţii este: Θ( g (n)) = O( g (n)) I Ω( g (n)) Analiza asimptotică a structurilor fundamentale prezintă interes. a > 1 lim n→∞ n! n →∞ n n n →∞ n →∞ a n nk Clasa de complexitate Ordin Exemplu (cazul cel mai defavorabil) logaritmică O(lgn) Căutarea binară radical Căutarea numerelor prime O n ( ) Analiza complexităţii algoritmilor .Proiectarea algoritmilor Această funcţie este o măsură a ordinului de creştere a timpului de execuţie în cazul cel mai favorabil. Dacă avem un ciclu dublu.. n DO m←3*m FOR j ← 1. k fiind o valoare strict pozitivă.. Dacă limitele ciclului interior se modifică dinamic atunci se poate obţine un alt ordin de complexitate. În cazul structurilor repetitive. respectiv. Structura secvenţială va avea ordinul de complexitate: O(max { g1(n). În ierarhizarea algoritmilor după ordinul de complexitate se ţine cont de următoarele proprietăţi ale funcţiilor ce intervin cel mai frecvent în analiză: (lg n )b = 0. i=1. însă T (n) ≠ Θ(1) întrucât în cazul cel mai defavorabil timpul de execuţie depinde de n. În cazul unei structuri alternative cu cele două prelucrări având costurile g1(n). A2.

compararea eficienţei a doi sau mai mulţi algoritmi destinaţi rezolvării aceleiaşi probleme. se analizează cazul cel mai favorabil. 4. Analiza complexităţii algoritmilor . În analiza empirică a eficienţei unui algoritm se parcurg următoarele etape: 1.a obţine informaţii preliminare privind clasa de complexitate a unui algoritm. Se stabileşte clasa de complexitate a algoritmului.obţinerea de informaţii privind eficienţa implementării unui algoritm pe un anume calculator. Se stabileşte dimensiunea problemei 2. . Dacă nu. 4. Se stabileşte scopul analizei 2. Analiza empirică a complexităţii algoritmilor Analiza matematică a complexităţii algoritmilor poate fi dificilă în cazul unor algoritmi care nu sunt simpli. O alternativă la analiza matematică a complexităţii algoritmilor o reprezintă analiza empirică.compararea eficienţei mai multor implementări ale aceluiaşi algoritm. Dacă da. Aceasta poate fi utilă pentru: . se determină acest număr. 3. Etapele analizei complexităţii În analiza complexităţii unui algoritm se parcurg următoarele etape: 1. Se stabilesc proprietăţile datelor de intrare în raport cu care se face analiza (dimensiunea acestora sau ale proprietăţi specifice). Se stabileşte operaţia de bază 3.5. cazul cel mai defavorabil şi (dacă este posibil) cazul mediu. Se verifică dacă numărul de execuţii ale operaţiei de bază depinde doar de dimensiunea problemei. .42 - . 4.6. mai ales dacă este vorba de analiza cazului mediu. . Se stabileşte metoda de apreciere a eficienţei: număr de execuţii ale unei/unor operaţii sau timp de execuţie a întregului algoritm sau porţiune de algoritm.Proiectarea algoritmilor liniară pătratică cubică exponenţială factorială O(n) O(nlgn) O(n2) O(n3) O(2n) O(n!) Căutarea secvenţială Sortarea prin interclasare Sortarea prin inserţie Produsul a două matrice pătrate de ordin n Prelucrarea tuturor submulţimilor unei mulţimi cu n elemente Prelucrarea tuturor permutărilor unei mulţimi cu n elemente Algoritmii din clasele exponenţială şi factorială pot fi utilizaţi doar pentru probleme de dimensiune mică.

43 - . În general este bine să se aleagă date de diferite dimensiuni astfel încât să fie acoperită plaja tuturor dimensiunilor care vor apare în practică. Dacă scopul evaluării este analiza comportării unui algoritm. Se recomandă să fie executat programul de mai multe ori şi să se facă media timpului de execuţie. La generarea seturilor de date de intrare scopul urmărit este acela de a se obţine date tipice rulărilor uzuale (să nu fie cazuri extreme sau excepţii). Este important ca în sistem să nu fie mai multe taskuri active sau să fie contorizat numai timpul afectat execuţiei programului analizat. Să se stabilească ordinul de complexitate pentru următorul algoritm care prelucrează date de volum n: Analiza complexităţii algoritmilor . Majoritatea limbajelor de programare oferă funcţii care calculează timpul scurs între două momente. Rezultatele înregistrate în urma testelor efectuate se înregistrează şi se fac prelucrări statistice (media. vor fi introduse secvenţe de cod al cărui scop o reprezintă monitorizarea execuţiei. 5. care să pună în evidenţă diferitele caracteristici ale algoritmului. Dacă metrica este timpul de execuţie atunci trebuie înregistrate momentul începerii secvenţei monitorizate şi momentul încheierii acesteia. Dacă metrica de eficienţă o reprezintă numărul de execuţii ale unei operaţii atunci se utilizează un contor care se incrementează după fiecare execuţie a operaţiei respective. Se analizează rezultatele obţinute. 7. de exemplu. Dacă se analizează un algoritm care verifică dacă un număr este prim sau nu şi testarea se face doar pentru numere prime sau numai pentru numere care nu sunt prime atunci nu se va obţine un rezultat relevant. Se generează mai multe seturi de date de intrare. Se execută programul pentru fiecare set de date de intrare. se urmăreşte obţinerea unor informaţii privind clasa de complexitate sau chiar verificarea acurateţei unei estimări teoretice atunci este adecvată utilizarea numărului de opearţii efectuate (numărarea prin program a numărului de operaţii). Pe de altă parte are importanţă şi analiza diferitelor valori sau configuraţii ale datelor de intrare. etc). În vederea analizei empirice. Pentru a efectua o analiză empirică nu este suficient un singur set de date de intrare ci mai multe. Se transcrie algoritmul într-un limbaj de programare. atunci este potrivit timpul de execuţie (măsurarea timpului de execuţie prin program).7. Dacă. Alegerea măsurii de eficienţă depinde de scopul analizei.Proiectarea algoritmilor 4. Exerciţii 1. În realitate este vorba de generare pseudo-aleatorie întrucât este generată prin tehnici cu caracter determinist. abaterea standard. 4. Este interesantă de asemenea reprezentarea grafică a timpului de execuţie în funcţie de dimensiunea problemei. la implementarea algoritmului într-un limbaj de programare. În acest scop datele se generează în manieră aleatoare. Acelaşi lucru se poate întâmpla pentru un algoritm a cărui comportare depinde de gradul de sortare a unui tablou (dacă se utilizează fie tablouri aproape sortate sau ordonate în sens invers atunci analiza nu va fi relevantă). 6.

Θ(1) h ← 2*h Indicaţie: Numărul de repetări k ale buclei WHILE rezultă din ecuaţia: 2 k −1 ≤ n ⇒ k = 1 + [lg n] 3. Să se stabilească ordinul de complexitate al algoritmului h←1 WHILE h ≤ n DO …..Θ(1) k←j WHILE k ≥ 0 DO …. Se consideră următorii doi algoritmi pentru calculul puterii unui număr: Analiza complexităţii algoritmilor . Să se stabilească ordinul de complexitate al algoritmului Calcul(n.x) k←0 FOR i ← 0.n DO …. Rezultă numărul de repetări ale operaţiei de bază: n 2i n n n ⋅ (n + 1) ⋅ (2n + 1) 1 T (n) = ∑ ∑ j = ∑ ⋅ (2i ) ⋅ (2i + 1) = ∑ (2i 2 + i ) = 2 + 6 i =1 j =1 i =1 2 i =1 n ⋅ (n + 1) 2 3 3 2 5 = ⋅n + ⋅n + ⋅n 2 3 2 6 3 T ( n) ∈ Θ n + ( ) 2.n-1 DO yk ← xi * yk k← k + 1 RETURN y 4. 2i DO ….Θ(1) FOR j ←1.Θ(1) k←k-1 Indicaţie: Operaţia de bază este operaţia de timp constant care se realizează sub bucla WHILE.Proiectarea algoritmilor FOR i ← 1.n-1 DO FOR j ← 0. De remarcat că numărul de repetări ale buclei este j.44 - .

n) p←1 FOR i ← 1.x DO np ← np +p p ← np RETURN p Putere2(x. 6. Propuneţi un algoritm de complexitate Θ(n2) şi unul de complexitate Θ(n) pentru evaluarea unui polinom de gradul n: P(x)=an·xn + an-1·xn-1 + a1·x + a0.n) p←1 FOR i ← 1.Proiectarea algoritmilor Putere1(x.n DO p ← p*x RETURN p Să se stabilească ordinele de complexitate considerând că toate operaţiile au acelaşi cost. Ce relaţie există între Θ(logan) şi Θ(logbn) dacă a > b > 0.45 - . Analiza complexităţii algoritmilor .n DO np ← 0 FOR j ← 1. 5.

8). METODE ELEMENTARE DE SORTARE 5.8.1. Din punctul de vedere al spaţiului de memorie o metodă in situ este mai eficientă decât una decât una bazată pe o zonă de manevră de dimensiunea tabloului.9).1).3.(Adam.6.(Adam. x2. Pentru a simplifica prezentarea în continuare vom considera că setul prelucrat este constituit din valori scalare care reprezintă chiar cheile de sortare şi că scopul urmărit este ordonarea crescătoare a acestora. în funcţie de spaţiul de manevră necesar pentru efectuarea sortării există: • Sortare ce foloseşte o zonă de manevră de dimensiunea setului de date...9)).xn îşi schimbă poziţiile astfel încât după încheierea procesului să fie ordonate.. p(2).≤ xp(n)... O metodă este considerată eficientă dacă nu necesită un volum mare de resurse.y2.5. Prin sortare crescătoare se obţine setul (1.yn.9).. (p(1). care ia valori într-o mulţime pe care este definită o relaţie de ordine. numită cheie. fiecare având asociată o caracteristică. O metodă este considerată simplă dacă este intuitivă şi uşor de înţeles. x2...8)) iar prin ordonare descrescătoare după notă se obţine ((Ionescu.. Este posibil ca şi în acest caz să se folosească o zonă de memorie însă aceasta este cel mult de dimensiunea unui element şi nu de dimensiunea întregului tablou. În acest caz cheia de sortare coincide cu valoarea elementului.. (Voinescu.9)..46 - .6). Considerăm setul de valori întregi: (5..3. În acest caz cheia de sortare poate fi numele sau nota.(Popescu..10). Problematica sortării Se consideră un set finit de obiecte. Dacă setul iniţial de date este reprezentat de tabloul x1.. Prin ordonare crescătoare după nume se obţine ((Adam.8) iar prin sortare descrescătoare se obţine (8. • Sortare în aceeaşi zonă de memorie (sortare pe loc .10).in situ).Proiectarea algoritmilor 5. Metodele de sortare pot fi caracterizate prin: • Simplitate. a ordona setul (x1.xn cel sortat se va obţine într-un alt tablou y1. Din punct de vedere al timpului de execuţie este important să fie Algoritmi de sortare . p(n)) astfel încât xp(1) ≤ xp(2) ≤. De asemenea vom considera că elementele setului sunt stocate pe un suport de informaţie care permite accesul aleator la date... (Voinescu.1. În cazul în care suportul de informaţie permite doar accesul secvenţial la date trebuie folosite metode specifice încadrate în categoria metodelor de sortare externă. În continuare vom analiza doar metode de sortare internă în aceeaşi zonă de memorie.8)).(Ionescu.9). (Ionescu..(Voinescu. Exemplul 2. Exemplul 1. Elementele tabloului x1. Considerăm un tabel constând din nume ale studenţilor şi note: ((Popescu. • Eficienţă..10).3. xn) este echivalent cu a găsi o permutare de ordin n.(Popescu.6...5. În acest caz este vorba despre sortare internă. x2. Astfel. Sortarea este procesul prin care elementele setului sunt rearanjate astfel încât cheile lor să se afle într-o anumită ordine. Pe de altă parte.9).

fiecare este înserat pe poziţia adecvată în subşirul care îl precede.10). • Stabilitate.9).. • Naturaleţe.xi să fie ordonat> Algoritmul detaliat este: Inserţie1(n.xi-1 începând cu xi-1 şi creând spaţiu prin deplasarea spre dreapta a elementelor mai mari decât xi (figura 5. O măsură a acestei distanţe poate fi numărul de inversiuni al permutării corespunzătoare tabloului iniţial. O metodă de sortare este considerată naturală dacă numărul de operaţii scade odată cu distanţa dintre tabloul iniţial şi cel sortat. x2. (Adam..xi-1. elementului xi i se caută poziţia adecvată în subşirul destinaţie x1. De exemplu dacă asupra tabelului cu note se aplică o metodă stabilă de ordonare descrescătoare după notă se obţine ((Ionescu.Proiectarea algoritmilor efectuate cât mai puţine operaţii... Sortare prin inserţie Principiul acestei metode este: Începând cu al doilea element. verificarea corectitudinii şi analiza complexităţii.47 - ..n DO j←i-1 aux ← xi {i -1 este indicele de la care se porneşte căutarea } { salvarea valorii lui xi} WHILE aux < xj ∧ j ≥ 1 DO { căutarea poziţiei pentru inserţie } {deplasarea lui xj cu o poziţie la dreapta } xj + 1 ← xj j← j-1 xj + 1 ← aux {înserarea valorii analizate pe poziţia adecvată } RETURN x Algoritmi de sortare . x2. (Adam.. x2. O metodă de sortare este considerată stabilă dacă ordinea relativă a elementelor ce au aceeaşi valoare a cheii nu se modifică în procesul de sortare.x) FOR i ← 2.9). Astfel structura generală a algoritmului este: Inserţie(n. (Voinescu.9).xi-1(care este deja ordonat) comparând pe xi cu elementele x1.9). (Popescu.8)) pe când dacă se aplică una care nu este stabilă se va putea obţine ((Ionescu.….2.. (Voinescu.8)).…. La fiecare etapă a sortării.. (Popescu.10). Pentru fiecare dintre aceste metode se va prezenta: principiul. În continuare vom considera câteva metode elementare de sortare caracterizate prin faptul că sunt simple.x) FOR i ← 2. În general în analiză se iau în considerare doar operaţiile efectuate asupra elementelor tabloului (comparaţii şi mutări).n DO <înserează xi în subşirul x1.1). x2. nu sunt cele mai eficiente metode dar reprezintă punct de pornire pentru metode avansate. astfel încât şirul x1. 5.

Rămâne doar să justificăm invariantul ciclului WHILE.. Precondiţia problemei este {n ≥ 1}. La sfârşitul ciclului WHILE aceasta proprietate ar implica una dintre relaţiile: • x1 ≤ . x2.≤ xi iar prin trecerea la următoarea valoare a contorului (i← i + 1) la faptul că x1. La începutul ciclului i = 2 deci x1 este implicit crescător. Această variantă poate fi descrisă după cum urmează: Inserţie2(n.. această poziţie jucând rolul unui fanion. xi-1 este crescător rezultă că proprietatea invariantă propusă pentru WHILE este satisfăcută. prin atribuirea xj + 1← xj Algoritmi de sortare . xi-1 este crescător. xi-1 este ordonat crescător}. Astfel cel mai târziu când j = 0 se ajunge la xj = xi.. iar postcondiţia este {x1... ≤ xi în cazul în care condiţia de ieşire din ciclu este aux ≤ xj..1 Sortarea prin inserţie Verificarea corectitudinii..x) FOR i ← 2.. x2.. Arătăm că ea nu este alterată de prelucrările din cadrul ciclului: dacă aux < xj. xj este crescător şi aux ≤ xj + 1 = xj + 2 ≤ . xn este ordonat crescător}.....≤ xi} este invariantă.. x2.. Pentru aceasta este suficient să arătăm că pentru ciclul interior (după j) aserţiunea {x1..48 - . Pentru ciclul exterior (după i) demonstrăm că proprietatea invariantă este {x1........ pentru a evita efectuarea comparaţiei j ≥ 1 la fiecare iteraţie interioară.. La intrarea în ciclu au loc relaţiile: j = i -1... ≤ xi în cazul în care condiţia de ieşire din ciclu este j = 0. Astfel.≤ xj ≤ xj + 1 ≤ xj + 2 ≤... x2. La sfârşitul prelucrării (i = n + 1) invariantul implică evident postcondiţia. ≤ xj ≤ aux ≤ xj + 1 = xj + 2 ≤ .Proiectarea algoritmilor Există şi alte metode de implementare a metodei.. Oricare dintre aceste două relaţii ar conduce prin atribuirea xj + 1 ← aux la x1 ≤. • aux ≤ x1 = x2 ≤ . se plasează pe poziţia 0 în tabloul x valoarea lui xi. Rămâne să arătăm că proprietatea rămâne adevărată şi după efectuarea prelucrărilor din cadrul ciclului.. x2...... aux = xi deci aux = xj + 1 = xi iar cum x1.n DO x0 ← xi j←i-1 WHILE x0 < xj DO xj + 1 ← xj j← j-1 xj + 1 ← x0 { salvarea valorii lui xi pe poziţia x0} {înserarea valorii fanion pe poziţia adecvată } RETURN x Figura 5..

2): Selecţie(n.Proiectarea algoritmilor se obţine: aux < xj = xj +1 ≤ ...... Fie TC(i) şi TM(i) numărul comparaţiilor respectiv al deplasărilor (mutărilor) efectuate asupra elementelor tabloului pentru fiecare i = 2. i =2 n n În cazul cel mai defavorabil TC(i) = i.xn şi se interschimbă cu xi > i =2 i =2 n Figura 5. x2. Dacă însă se foloseşte aux ≤ xj metoda nu mai este stabilă. Vom lua în considerare doar operaţiile de comparare şi mutare asupra elementelor tabloului.n-1 DO < se determină valoarea minimă din xi. În cazul cel mai favorabil: TC(i) = 1 iar TM(i) = 2 (este vorba de operaţiile care implică variabila ajutătoare aux şi care dealtfel în acest caz nu au nici un efect) deci T (n) = ∑ [TC (i ) + TM (i )] = 3 ⋅ (n − 1) . Alte proprietăţi. începând cu prima..2..... Sortare prin selecţie Principiul acestei metode este: Pentru fiecare poziţie i. Cum xj + 1 = xj + 2 prin xj + 1 ← xj nu se pierde informaţie din tablou.. Sortarea prin selecţie Algoritmi de sortare . Algoritmul sortării prin inserţie este natural şi atât timp cât condiţia de continuare a ciclului interior este aux < xj este şi stabil.. obţinându-se că T (n) = ∑ [TC (i ) + TM (i )] = ∑ (i + i + 1) = n 2 + 2 ⋅ n − 3 . Oprirea algoritmului este asigurată de utilizarea câte unui contor pentru fiecare dintre cele două cicluri.49 - . Cazul cel mai favorabil corespunde şirului ordonat crescător.... Prin urmare 3(n-1) ≤ T(n) ≤ n2 +2·n-3 adică algoritmul sortării prin inserţie se încadrează în clasele Ω(n) şi O(n2). xj crescător şi aux < xj + 1 = xj + 2 ≤ ..1 + 2 = i + 1.n. ≤ xi iar după j← j -1 va fi adevărată aserţiunea: {x1. se selectează din subşirul ce începe cu acea poziţie cel mai mic element şi se amplasează pe locul respectiv (prin interschimbare cu elementul curent de pe poziţia i) Structura generală a algoritmului este (vezi şi figura 5. 5. iar cel mai defavorabil celui ordonat descrescător. ≤ xi.x) FOR i ← 1. iar TM(i) = i .3. Analiza complexităţii.

..xk-1 la dreapta cu o poziţie (ca în algoritmul inserţiei) iar xk (salvat în prealabil într-o variabilă auxiliară) s-ar transfera în xi.. Ciclul FOR interior (după j) determină valoarea minimă din xi. Indiferent de aranjarea iniţială a elementelor.. Se obţine astfel că x1..... Arătăm că un invariant al ciclului exterior (după i) este: {x1.... Alte proprietăţi.Proiectarea algoritmilor Ciclul FOR continuă până la n-1 deoarece subşirul xn..x) FOR i ← 1. Dacă însă în locul unei singure interschimbări s-ar realiza deplasarea elementelor subtabloului xi. Astfel algoritmul sortării prin selecţie aparţine clasei Θ(n2). La început i = 1 deci x1. algoritmul ar deveni stabil..... n}.xi este ordonat crescător şi că xi ≤ xj pentru j = i + 1. Analiza complexităţii.n.xn-1 crescător şi xn-1 ≤ xn adică x1..xn este ordonat crescător... numărul de comparaţii efectuate este: n −1 n n −1 1 1 TC (n) = ∑ ∑ 1 = ∑ (n − i ) = n ⋅ (n − 1) − ⋅ (n − 1) ⋅ n = ⋅ (n − 1) ⋅ n 2 2 i =1 j =i +1 i =1 În cazul cel mai favorabil (şir ordonat crescător) numărul interschimbărilor este TM(n) = 0.xi-1 este ordonat crescător şi xi-1 ≤ xj pentru j = i.. x2..4. deci costul interschimbărilor este TM(n) = 3·(n..xn conţine un singur element care este plasat chiar pe poziţia potrivită.1). La final.. ca urmare a interschimbărilor efectuate anterior. În varianta prezentată (când minimul este interschimbat cu poziţia curentă) algoritmul nu este stabil.50 - . După incrementarea lui i (la sfârşitul ciclului după i) se reobţine proprietatea invariantă...xi-1 este şir vid..xn Aceasta este plasată prin interschimbare pe poziţia i..n-1 DO k← i FOR j ← i+1.. În cazul cel mai defavorabil (şir ordonat descrescător) pentru fiecare i se efectuează o interschimbare (trei atribuiri). 5.. Sortare prin interschimbarea elementelor vecine Principiul acestei metode de sortare este: Algoritmi de sortare .n DO IF xk > xj THEN k ← j IF k ≠ i THEN x k ⇔ xi RETURN x {indicele curent al minimului} {ciclu pentru căutarea minimului} {noul indice al minimului} {plasarea pe poziţia adecvată} Verificarea corectitudinii. i = n iar invariantul conduce la x1. Descrierea detaliată a algoritmului este: Selecţie(n.. Algoritmul este parţial natural (numărul de comparaţii nu depinde de gradul de sortare al şirului).

Dacă xi ≤ xi + 1 atunci nu se efectuează nici o prelucrare şi rămâne adevărată şi pentru i+1. Parcurgerea se reia până când nu mai este necesară nici o interschimbare.. Figura 5..x2.Proiectarea algoritmilor Se parcurge şirul şi se compară elementele vecine iar dacă acestea nu se află în ordinea corectă se interschimbă. Rezultă că algoritmul poate fi descris prin: Algoritmi de sortare .xn-1..3 Sortarea prin interschibarea elementelor vecine (bubble sort) Să considerăm secvenţa interschimbării elementelor vecine în cazul în care nu sunt în ordinea corectă: FOR i ← 1. n-1 DO IF xi > xi+1 THEN xi ⇔ xi +1 Folosind ca invariant al prelucrării repetitive proprietatea {xi ≥ xj. Presupunem că proprietatea este adevărată pentru i. Pe baza acestei proprietăţi a secvenţei de interschimbări se deduce că este suficient să aplicăm această prelucrare succesiv pentru x1. x1.. la sfârşitul şirului se generează un şir sortat. .....2. Pentru i = 1 proprietatea invariantă este adevărată întrucât x1 ≥ x1..3). Structura generala a algoritmului este: Interschimbări(n....x) REPEAT < se parcurge şirul şi dacă două elemente vecine nu sunt în ordinea corectă sunt interschimbate > UNTIL < nu mai este necesară nici o interschimbare > După cum se observă din figura (5.51 - .xn. j = 1. Dacă în schimb xi > xi+1 atunci se efectuează interschimbarea astfel că xi < xi + 1 deci proprietatea devine adevărată şi pentru i + 1. x1.i} se poate arăta că prelucrarea de mai sus conduce la satisfacerea postcondiţiei: {xn ≥ xi.. i = 1.. n}.

i}. Întrucât s-a demonstrat că efectul ciclului interior este că plasează valoarea maximă pe poziţia i rezultă că pentru ciclul exterior poate fi considerată ca invariantă proprietatea {xi + 1. iar în cazul cel mai defavorabil (şir sortat descrescător) TM(n)=3n(n-1)/2 (o interschimbare presupune 3 atribuiri)..52 - . n – 1 DO IF xi > xi+1 THEN xi ⇔ xi +1 inter ← TRUE UNTIL inter = FALSE RETURN x Pentru acest algoritm numărul de comparaţii efectuate în cazul cel mai favorabil este TC(n)=n-1.x) REPEAT inter ← FALSE FOR i ← 1. 2.xn este crescător iar xi + 1 ≥ xj pentru j = 1. iar în cazul cel mai defavorabil este: TC (n) = ∑ (n − 1) = n ⋅ (n − 1) j =1 n În ceea ce priveşte numărul de interschimbări acesta este acelaşi ca pentru prima variantă a algoritmului şi anume Algoritmi de sortare . Astfel numărul de prelucrări analizate satisface: n(n . Numărul de comparaţii efectuate nu depinde de gradul de sortare al şirului iniţial fiind în orice situaţie: n i −1 n n −1 n ⋅ (n − 1) TC ( n) = ∑ ∑ 1 = ∑ (i − 1) = ∑ i = 2 i = 2 j =1 i =2 i =1 În schimb. Algoritmul poate fi însă îmbunătăţit prin reducerea numărului de comparaţii efectuate.2.. -1 DO FOR j ← 1.3.x) FOR i ← n...Proiectarea algoritmilor Interschimbări1(n..n...1)/2 ≤ T(n) ≤ 2n(n . De exemplu.. i – 1 DO IF xj > xj+1 THEN x j ⇔ x j +1 RETURN x Verificarea corectitudinii. dacă tabloul este de la început ordonat ar fi suficientă o singură parcurgere care să verifice că nu este necesară efectuarea nici unei interschimbări. Pornind de la această idee se ajunge la algoritmul: Interschimbări2(n. numărul de interschimbări depinde de proprietăţile şirului astfel: în cazul cel mai favorabil (şir sortat crescător) se obţine TM(n)=0..1) adică algoritmul prezentat mai sus aparţine clasei Θ(n2). în sensul că nu este necesară întotdeauna parcurgerea tabloului pentru i = 2. Analiza complexităţii.

Proiectarea algoritmilor

3 ⋅ n ⋅ (n − 1) 2 Prin urmare numărul total de repetări ale prelucrărilor analizate satisface: 5 n − 1 ≤ T (n) ≤ ⋅ n ⋅ (n − 1) 2 adică algoritmul este din clasa Ω(n) şi O(n2). Întrucât la sfârşitul şirului se formează un subşir crescător rezultă că nu mai este necesar să se facă comparaţii în acea porţiune. Această porţiune este limitată inferior de cel mai mare indice pentru care s-a efectuat interschimbare. Astfel algoritmul poate fi rescris astfel (a se vedea mai jos). 0 ≤ TM (n) ≤
Atâta timp cât condiţia pentru interschimbare este specificată prin inegalitate strictă (xi > xi + 1) oricare dintre variantele algoritmului este stabilă. Valorile comparative ale numărului de prelucrări (comparaţii şi mutări asupra elementelor tabloului) pentru algoritmii de sortare descrişi sunt prezentate în tabelul următor. Interschimbări3(n,x) m←n REPEAT t←0 FOR i ← 1, m – 1 DO IF xi > xi+1 THEN xi ⇔ xi +1 t←i m←t UNTIL t ≤ 1 RETURN x

{ la început se va parcurge tot şirul} { cel mai mare indice pentru care se face interschimbarea}

{indicele ultimei interschimbări}

Algoritmi de sortare - 53 -

Proiectarea algoritmilor
5.5. Exerciţii 1. Să se propună un algoritm care construieşte tabloul sortat crescător y1,...,yn pornind de la tabloul x1,...,xn. Indicaţie: Se construieşte şirul sortat pe principiul metodei inserţiei. Sortsirnou(n,x,y) y1 ← x1 FOR i ← 2, n DO k← i-1 WHILE (xi <yk) AND (k > 0) DO yk+1 ← yk k ← k-1 yk+1 ← xi RETURN y 2. Se consideră un tabloul ale cărui elemente conţin două informaţii: nume şi nota. Să se ordoneze descrescător după notă, iar pentru aceeaşi notă crescător după nume. Indicaţie: Se va realiza sortarea după notă descrescător, după care pentru fiecare notă se realizează sortarea crescătoare după nume. Sortnotanum(n,x) {sortare după nota descrescător} FOR i ← 2, n DO x0 ← xi k ← i-1 WHILE (x0.nota > xk.nota) DO xk+1 ← xk k ← k-1 xk+1 ← x0 {sortare după nume crescător} k←1 WHILE k ≤ n -1 DO i ← k+1 WHILE (xi.nota = xi-1.nota) and (i ≤ n) DO i ← i+1 if i > k+1 then sortnum(k,i-1,x) k←i RETURN x

Algoritmi de sortare - 54 -

Proiectarea algoritmilor
Sortnum(k,i,x) FOR m ← k+1,i DO x0 ← xm j ← m-1 while (x0.nume < xj.nume) AND (j ≥ k) DO xj+1 ← xn j←j-1 xj+1 ← x0 RETURN x 3. Să se analizeze complexitatea algoritmului interschimbări3. 4. Se consideră o matrice cu m linii şi n coloane de elemente reale. Să se reorganizeze matricea prin interschimbări de linii şi coloane astfel încât elementele diagonalei principale să fie ordonate crescător.

Algoritmi de sortare - 55 -

d. Descompunerea poate continua până se ajunge la x2 al cărui calcul este simplu. n DO p ← p*x RETURN p are complexitatea Θ(n). O descriere a acestei metode de rezolvare care ilustrează mai bine ideea reducerii dimensiunii este: Putere3(x. Algoritmul general pentru calculul lui xn (pentru un n natural arbitrar): Putere1(x. Reducerea complexităţii derivă din faptul că la fiecare etapă se calculează valoarea unui singur factor din cei doi.n) p←1 FOR i ← 1. Algoritmul poate fi descris prin: Putere2(x. Motivaţie Considerăm problema calculului lui xn pentru x > 0 şi n = 2m. La rândul său calculul lui xn/2 poate fi redus la calculul lui xn/4 şi la o ridicare la pătrat ş.56 - .a.Proiectarea algoritmilor 6. m DO p ← p*p RETURN p Folosind ca invariant pentru prelucrarea repetitivă afirmaţia: { p = x2(i-1)} se m poate demonstra cu uşurinţă că algoritmul putere2 calculează x 2 .m) p←x FOR i ← 1. TEHNICI DE ELABORARE A ALGORITMILOR: REDUCERE ŞI DIVIZARE 6.1. Reducerea dimensiunii continuă până când se ajunge la o problemă de dimensiune suficient de mică pentru a putea fi rezolvată direct (de exemplu n = 2 sau m = 1).n) IF n = 2 THEN RETURN x*x ELSE p ← putere3(x. Dacă se foloseşte ipoteza n = 2m se observă că xn = xn/2· xn/2 căci x2m = x2(m-1)· x2(m-1) . m ≥ 1 fiind un număr natural. Ideea de rezolvare a acestei probleme este comună tehnicilor de reducere şi divizare care se bazează pe înlocuirea rezolvării unei probleme de dimensiune n pe rezolvarea uneia sau mai multor probleme similare dar de dimensiune mai mică. întrucât sunt identici.n/2) RETURN p*p Reducere şi divizare .m. Pe de altă parte se observă că prelucrarea este de complexitate Θ(m) = Θ(lg(n)). Prin urmare pentru a calcula xn este suficient să se calculeze xn/2 şi să se ridice la pătrat.

. x2. Un exemplu în acest sens îl reprezintă calculul factorialului (după cum se va demonstra mai târziu.57 m .m) IF m = 1 THEN RETURN x*x ELSE p ← putere4(x.s.. Exemplul de mai sus ilustrează faptul că folosind ideea reducerii rezolvării unei probleme la rezolvarea unei probleme similare dar de dimensiune mai mică poate conduce la reducerea complexităţii. Algoritmul poate fi descris în manieră recursivă după cum urmează: Maxim(x. x2. Astfel de algoritmi se numesc recursivi. Considerăm problema determinării maximului dintr-o secvenţă finită de valori reale stocate în tabloul x1. aplicând tehnica reducerii se obţine un algoritm de complexitate Θ(n) la fel ca prin aplicarea tehnicii forţei brute).d) IF max1 < max2 THEN max ← max2 ELSE max ← max1 RETURN max Nu este dificil de observat că ordinul de complexitate al acestui algoritm este tot Θ(n) ca şi în cazul algoritmului clasic (afirmaţia va fi justificată în secţiunea dedicată analizei algoritmilor recursivi).x[n/2] şi maximul din subtabloul x[n/2]+1.m-1) RETURN p*p Ultimii doi algoritmi prezintă o particularitate: în cadrul prelucrărilor pe care le efectuează există şi un auto-apel (în cadrul funcţiei se apelează aceeaşi funcţie). Pe de altă parte există probleme pentru care abordarea rezolvării în această manieră este mai uşoară conducând la algoritmi intuitivi.....s..xn. Acest lucru este adevărat în cazul în care maşina pe care Reducere şi divizare .Proiectarea algoritmilor Dacă se transmit ca parametri valorile x şi m.d) IF s = d THEN max ← xs ELSE m ← [(s+d)/2] max1 ← maxim (x. Rezultatul va fi cea mai mare dintre valorile obţinute. x[n/2]+2.. Aplicând ideea divizării rezultă că este suficient să determinăm maximul din subtabloul x1.. algoritmul pentru calculul lui x 2 poate fi descris prin: Putere4(x.m) max2 ← maxim (x.m+1. Trebuie menţionat totodată că nu întotdeauna tehnicile din această categorie conduc la o reducere a complexiţaţii în cazul în care algoritmul este implementat pe o maşină secvenţială.xn.

b) IF b = 0 THEN rez ← a ELSE rez ← cmmdr1(b. • Auto-apel. Algoritmi recursivi Ultimii algoritmi prezentaţi în secţiunea anterioară fac parte din categoria algoritmilor recursivi. Aceştia sunt utilizaţi pentru a descrie prelucrări ce se pot specifica prin ele însele. 6. Algoritmul bazat pe operaţia de împărţire poate fi descris prin: Cmmdr1(a. Un exemplu simplu de prelucrare repetitivă descrisă recursiv este cea corespunzătoare determinării cmmdc a două numere naturale nenule. Un algoritm recursiv este caracterizat prin: • Condiţie de oprire. Un algoritm recursiv este considerat simplu recursiv dacă conţine un singur auto-apel şi multiplu recursiv dacă conţine două sau mai multe auto-apeluri (de exemplu. Dacă însă maşina este paralelă (la un moment dat pot fi efectuate simultan mai multe prelucrări) atunci printr-o astfel de abordare se poate ajunge la câştig de timp. Ca urmare a cascadei de auto-apeluri un algoritm recursiv realizează de fapt o prelucrare repetitivă. a ≥ b > 0.a-b) ELSE rez ← cmmdr2(a. algoritmul maxim din secţiunea anterioară).b) IF a = b THEN rez ← a ELSE IF a > b THEN rez ← cmmdr2(b. chiar dacă aceasta nu este explicită. Valorile parametrilor corespunzătoare succesiunii de apeluri trebuie să asigure apropierea de satisfacerea condiţiei de oprire.Proiectarea algoritmilor va fi executat algoritmul este una secvenţială.b-a) RETURN rez Exemplele de mai sus se caracterizează prin recursivitate simplă şi directă. Specifică situaţia în care rezultatul se poate obţine prin calcul direct fără a mai fi necesară apelarea aceluiaşi algoritm.58 - .a MOD b) RETURN rez iar cel bazat pe operaţia de scădere: Cmmdr2(a. Reducere şi divizare .2. Se apelează cel puţin o dată pentru alte valori ale parametrilor.

Dacă rez = cmmdc(a. Arbori de apel. Descrierea recursivă permite specificarea unor structuri infinite folosind un set finit de reguli. Pentru cazul particular b = 0 avem rez = a = cmmdc(a. b) = cmmdc(b. 0) = cmmdc(a. Pentru a ilustra modul de lucru al unui algoritm iterativ poate fi util să se reprezintă grafic structura de apeluri şi reveniri cu returnarea rezultatului obţinut. (iii) implică postcondiţia. În cazul recursivităţii simple arborele de apel degenerează într-o structură liniară (figura 6. Dacă relaţia de recurenţă care descrie legătura dintre soluţiilor corespunzătoare diferitelor instanţe ale problemei este corectă atunci şi algoritmul care o implementează este corect. De exemplu algoritmul A1 apelează algoritmul A2 iar acesta apelează algoritmul A1. Reducere şi divizare . b)}. Algoritmii recursivi sunt adecvaţi pentru rezolvarea problemelor sau prelucrarea datelor descrise în manieră recursivă. b). În cazul unui algoritm recursiv arbitrar structura de apeluri este una ierarhică conducând la un arbore de apel. Noţiunea de recursivitate poate fi utilizată şi în contextul definirii unor concepte. Figura 6.Proiectarea algoritmilor Există şi posibilitatea ca algoritmul să nu se auto-apeleze direct ci indirect prin intermediul altui algoritm. • Condiţia de oprire este satisfăcută după o succesiune finită de apeluri recursive.b) după apelul recursiv.59 - .1 Structura de apel pentru algoritmul cmmdr1 Verificarea corectitudinii algoritmilor recursivi.a MOD b) şi rez = cmmdc(a. o variabilă sau o expresie".1). În acest caz este vorba de recursivitate indirectă. Pentru algoritmul cmmdcr1 o aserţiune invariantă este {rez = cmmdc(a. un operand poate fi o constantă. (ii) este adevărată la revenirea din apelul recursiv şi efectuarea prelucrărilor locale. Pe de altă parte întrucât un algoritm recursiv specifică o prelucrare repetitivă implicită pentru a demonstra corectitudinea acestuia este suficient să se arate că: • Există o aserţiune referitoare la starea algoritmului care are proprietăţile: (i) este adevărată pentru cazul particular (când e satisfăcută condiţia de oprire). b) înainte de apelul recursiv putem deduce că cmmdc(a. De exemplu conceptul de expresie aritmetică poate fi definit astfel: "o expresie aritmetică este constituită din operanzi şi operatori.

h(n). Pornind de la relaţia de recurenţă se intuieşte forma generală a lui T(n) după care se demonstrează prin inducţie matematică validitatea expresiei lui T(n). Să considerăm h(n) = n – 1 Prin metoda iteraţiei se obţine: T(n) = T(n . b)}. Se scrie relaţia de recurenţă pentru n.2) + c …….m. • Metoda iteraţiei (substituţiei inverse). Analiza complexităţii algoritmilor recursivi. datorită proprietăţilor restului unei împărţiri întregi..60 - .1) + c T(n . Din relaţia obţinută. Exemplul 1. . Exemplul 2. pe baza unor calcule algebrice. Dacă notăm numărul înmulţirilor efectuate cu T(n) se obţine relaţia de recurenţă: T(n) = 1 dacă n = 2 T(n/2) + 1 dacă n > 2 Aplicând tehnica iteraţiei obţinem: 2m Reducere şi divizare . Dacă prelucrarea P1 are cost constant (c0) iar determinarea lui h(n) are costul c atunci costul algoritmului algrec poate fi descris prin: dacă n = n0 ⎧c0 T ( n) = ⎨ dacă n > n0 ⎩T (h( n)) + c Prin urmare timpul de execuţie al unui algoritm recursiv satisface o relaţie de recurenţă. rezultă expresia lui T(n). Pentru determinarea expresiei lui T(n) pornind de la relaţia de recurenţă se poate folosi una dintre metodele: • Metoda substituţiei (directe). Considerăm algoritmul recursiv (putere3) pentru calculul puterii x ... T(h(h(n))) ş.○ h)(n) = n0. Metoda mai este cunoscută şi ca metoda substituţiei inverse.a.d..Proiectarea algoritmilor Pentru algoritmul cmmdcr2 proprietatea invariantă este tot {rez = cmmdc(a.. n0 după care se substituie succesiv T(h(n)).1) = T(n . Considerăm o problemă de dimensiune n şi algoritmul recursiv de forma: Algrec(n) IF n = n0 THEN P1 ELSE Algrec(h(n)) cu h(n) o funcţie descrescătoare cu proprietatea că există k cu h(k)(n) = (h ○ h○. În ambele situaţii condiţia de oprire va fi satisfăcută după un număr finit de apeluri recursive. T(n0+1)= T(n0) + c T(n0)=c0 Prin însumarea tuturor relaţiilor şi reducerea termenilor corespunzători se obţine: T(n) = c(n -n0) + c0 pentru n > n0. h(h(n))..

+ 2m-1 = 2m . Analizăm algoritmul maxim descris în secţiunea anterioară (pct.1 = 0. De regulă reducerea dimensiunii se bazează pe scăderea unei constante (în majoritatea situaţiilor 1) din dimensiunea problemei. Tehnica reducerii se bazează pe relaţia care există între soluţia unei probleme şi soluţia unei instanţe de dimensiune redusă a aceleia şi probleme.. Pornim de la cazul particular n = 2m pentru care relaţia de recurenţă conduce la T(n) = 2T(n/2) + 1 pentru n ≥ 2 obţinându-se succesiunea: T(n) T(n/2) T(n/4) …. Relaţia de la care se porneşte este: Reducere şi divizare . însumând relaţiile şi efectuând reducerile se obţine: T(n) = 1+2+22+.1). 6. Cel mai simplu exemplu este cel al calculului factorialului. prin însumarea tuturor şi reducerea termenilor corespunzători se obţine T(n) = m = lgn. Observaţie. T(n) este crescătoare pentru argumente mari (n ≥ n0) iar f(n) are proprietatea f(cn) Є Θ(f(n)) pentru c o constantă (în acest caz se spune despre f că este netedă) atunci T(n) Є Θ(f(n)) pentru orice n.Proiectarea algoritmilor T(n) = T(n/2) + 1 T(n/2) = T(n/22) + 1 . Acest rezultat este valabil doar pentru n = 2m.. Notând cu T(n) numărul de comparaţii efectuate se obţine relaţia de recurenţă: dacă n = 1 ⎧0 T ( n) = ⎨ dacă n ≥ 2 ⎩T ([n / 2]) + T (n − [n / 2]) + 1 În cazul în care n nu este o putere a lui 2 metoda iteraţiei este mai dificil de aplicat. Pentru a arăta că este adevărat pentru orice n aplicăm inducţia matematică. = 2·T(1) + 1 = 0 ·21 ·22 ·2m-2 ·2m-1 Înmulţind relaţiile cu factorii din ultima coloană.61 - .. Tehnica reducerii Principiu. Exemplul 3. T(4) T(2) = 2·T(n/2) + 1 = 2·T(n/4) + 1 = 2·T(n/8) + 1 ……. Presupunem că T(k) = k-1 pentru orice k < n. Evident T(1) = 1 .1 = n -1. T(4) = T(2) + 1 T(2) = 1 Cum numărul relaţiilor de mai sus este m. Rezultă că T(n) = [n/2] -1 + n-[n/2] +1 – 1 = n-1. 6.3.. Se poate demonstra că dacă T(n) Є Θ(f(n)) pentru n = 2m. Condiţiile de mai sus (T(n) crescătoare pentru valori mari ale lui n şi f(cn) Є Θ(f(n)) sunt satisfăcute în marea majoritate a situaţiilor practice.. Calculul factorialului.

1 poziţii. 3) respectiv la (3.. Reducere şi divizare . Demonstrăm acest lucru prin inducţie matematică după n.. 1). 2).1) = T(n .2 până se ajunge la permutări de ordin 1 (o singură permutare care constă chiar din valoarea aflată pe poziţia 1).Proiectarea algoritmilor dacă n = 0 ⎧1 n! = ⎨ ⎩n ⋅ (n − 1)! dacă n > 0 Algoritmul poate fi descris în varianta recursivă astfel: Factorial(n) IF n = 0 THEN f←1 ELSE f ← n*factorial(n-1) RETURN f Notând cu T(n) numărul de operaţii de înmulţire efectuate se obţine relaţia de recurenţă: dacă n = 0 ⎧0 T ( n) = ⎨ ⎩T (n − 1) + 1 dacă n > 0 Din această relaţie se poate intui că T(n) = n. 1). 1. Pentru fiecare dintre acestea valoarea 3 poate fi înserată în fiecare dintre cele trei poziţii posibile: prima. (2. Astfel dacă n = 3 există două permutări de ordin n-1 = 2: (1. Generarea permutărilor. Pentru n = 1 se obţine T(1) = T(0)+1 = 1. 2. Pentru o abordare descendentă ("top-down") a problemei (o permutare de ordin n se specifică prin permutări de ordin n . (2. 3). Pentru a le genera pe acestea se folosesc permutările de ordin n . 2) şi (2.. .. 2. O variantă porneşte de la ideea că o permutare de ordin n se poate obţine dintr-o permutare de ordin n .. = T(0) + 1 T(1) =0 T(0) Prin însumarea tuturor relaţiilor şi efectuarea reducerilor se obţine: T(n) = n.. 2).1 prin plasarea valorii n pe toate cele n poziţii posibile. 3. Presupunem că T(n-1) = n-1.62 - .. Există mai multe moduri de a aplica tehnica reducerii.1) + 1 T(n . (1. (1. Acelaşi rezultat se obţine aplicând tehnica iteraţiei: T(n) = T(n .. Această idee ar corespunde unei abordări ascendente ("bottom-up" . Să considerăm problema generării permutărilor de ordin n. 2..pornind de la o permutare de ordin dat se construieşte o permutare de ordin imediat superior). 1). Din relaţia de recurenţă vom obţine T(n) = T(n .. Deci întradevăr T(n) = n. 1.1) + 1 = n.2) + 1 . a doua şi a treia conducând la (3.n}) şi pentru fiecare valoare astfel plasată să generăm toate permutările corespunzătoare valorilor aflate pe primele n .1) să observăm că pentru a genera toate permutările de ordin n este suficient să plasăm pe poziţia n succesiv toate valorile posibile (din {1. 3.

se transferă discul rămas pe s direct pe d. 1. Ideea rezolvării este: "se transferă n . Pe vergeaua s se află dispuse n discuri în ordinea descrescătoare a razelor (primul disc are raza maximă). Permutari(k) IF k = 1 THEN Write x ELSE FOR i ← 1.. 3). (3. permutările de ordin 3 se obţin în ordinea următoare: (2. T(2) T(1) = k·T(k-1)+2·k = (k-1)·T(k-2)+2·(k-1) = (k-2)·T(k-3)+2·(k-2) .k DO xi ⇔ xk Permutări(k-1) xi ⇔ xk Aplicând acest algoritm. 1)... 1. x2.. 1).+ k(k-1)+k). Pentru a analiza complexitatea algoritmului contorizăm numărul de interschimbări efectuate şi observăm că satisface: dacă k = 1 ⎧0 T (k ) = ⎨ dacă k > 1 ⎩k ⋅ (T (k − 1) + 2 ) Aplicăm tehnica iteraţiei şi obţinem: T(k) T(k-1) T(k-2) . Prin urmare pentru k = n se obţine T(n) ЄΘ(n!). (1. Se consideră trei vergele plasate vertical şi identificate prin s (sursă)... figura 6. d (destinaţie) şi i (intermediar). 2. = 2·T(1)+2 =0 ·k ·k·(k-1) . 3). 2).2. se transferă cele n-1 discuri de pe i pe d folosind s ca intermediar".. Turnurile din Hanoi..Proiectarea algoritmilor Pentru a descrie algoritmul să presupunem că permutările se vor obţine într-un tablou x1. (1. În momentul în care x conţine o permutare ea este afişată..... Se poate folosi vergeaua i ca intermediar cu restricţia că în orice moment peste un disc se află doar discuri de rază mai mică.63 - . 3. 2). ·k·(k-1) ····3 ·k·(k-1) ····3·2 Înmulţind fiecare relaţie cu factorii specificaţi în ultima coloană şi însumând toate relaţiile se obţine: T(k) = k!+2· (k· (k-1)··· 4+. (3.. 2. Această idee poate fi descrisă simplu în manieră recursivă: Reducere şi divizare .. Se cere să se transfere toate discurile pe vergeaua d astfel încât să fie plasate în aceeaşi ordine. (2.1 discuri de pe s pe i folosind d ca intermediar. 3. xn accesat în comun de către toate (auto)apelurile algoritmului şi iniţializat astfel încât xi = i.

n=3 Reducere şi divizare . d → i. Se observă că: Figura 6.3. i → s.3 Structura de apel pentru algoritmul hanoi.s. Succesiunea mutărilor este obţinută parcurgând blocurile haşurate de la stânga la dreapta: s → d.d.s. s → d. Prelucrarea s → d specifică faptul că va fi transferat discul de pe vergeaua s pe vergeaua d. s →! d.2 Turnurile din Hanoi In algoritmul hanoi primul argument specifică numărul de discuri ce vor fi transferate. Structura apelurilor recursive pentru n = 3 este ilustrată în figura 6.d) s→d Hanoi(n-1.d.Proiectarea algoritmilor hanoi(n.s) Figura 6.i) IF n = 1 THEN s→d ELSE Hanoi(n-1. s → i.i. al doilea indică vergeaua sursă. al treilea vergeaua destinaţie iar ultima pe cea folosită ca intermediar. i → d.64 - . Pentru a analiza complexitatea contorizăm numărul de mutări de discuri.i.

. . b) iar operaţia dominantă este împărţirea lui a la 2 (celelalte operaţii: înmulţirea lui b cu 2 şi adunarea nu se efectuează de mai multe ori). 2*b) ELSE RETURN produs((a-1) DIV 2. Regula de calcul în acest caz este: ⎧ ⎪0 dacă a = 0 ⎪ ⎪a a ⋅ b = ⎨ ⋅ 2b dacă a este par 2 ⎪ ⎪a −1 dacă a este impar ⎪ 2 ⋅ 2b + b ⎩ Pornind de la această relaţie algoritmul poate fi descris prin algoritmul de mai jos...Proiectarea algoritmilor dacă n = 1 ⎧1 T ( n) = ⎨ dacă n > 1 ⎩2 ⋅ T (n − 1) + 1 Prin metoda iteraţiei se obţine: T(n) = 2·T(n-1)+1 T(n-1) = 2·T(n-2)+1 T(n-2) = 2·T(n-3)+1 .. Reducerea dimensiunii se poate realiza nu doar prin scăderea unei constante ci şi prin împărţirea la o constantă. 2*b)+b ⎧0 T ( a... Înmulţirea "à la russe".65 dacă a = 0 dacă a > 0 .b) IF a = 0 THEN RETURN 0 ELSE IF a MOD 2 = 0 THEN RETURN produs(a DIV 2. 2 ⋅ b) + 1 Reducere şi divizare . Pentru a analiza complexitatea algoritmului considerăm că dimensiunea problemei este reprezentată de perechea (a.. b) = ⎨ ⎩T (a / 2. T(2) = 2·T(1)+2 T(1) =1 Însumând relaţiile rezultă T(n) = 1+2 +2 +.b) se poate scrie relaţia de recurenţă: Produs(a. ·2n-2 ·2n-1 = 2n -1 adică algoritmul are ordinul de complexitate Θ(2n). Astfel pentru timpul de execuţie T(a... Cazul cel mai frecvent este acela al împărţirii dimensiunii problemei la 2.+2 1 2 n-1 ·21 ·22 . Un exemplu simplu în acest sens este cel al înmulţirii " à la russe".

• Combinarea rezultatelor.23b)+1 .. k-1 T(2. Cazul clasic este acela când subproblemele au aceeaşi natura ca şi problema iniţială. Pentru a obţine răspunsul la problema iniţială uneori trebuie combinate rezultatele obţinute pentru subprobleme. Tehnica divizării (denumită şi "divide et impera" sau "divide and conquer") constă în: • Descompunerea în subprobleme. Pk(nk)> FOR i ← 1. .b) = T(2k-1. nc) pentru a fi rezolvate direct.66 - .2kb)+1 T(1. • Rezolvarea subproblemelor. Întrucât T(a) este crescătoare pentru valori mari ale lui a iar lgca = lga + lgc Є Θ(lga) rezultă că rezultatul este valabil şi pentru cazul general. 6.. Pentru ca această tehnică să fie efectivă (să conducă de exemplu la reducerea costului calculului) trebuie ca subproblemele care se rezolvă să fie independente (o aceeaşi subproblemă să nu fie rezolvată de mai multe ori). O problemă de dimensiune n este descompusă în două sau mai multe subprobleme de dimensiune mai mică. Structura generală a unui algoritm elaborat folosind tehnica divizării este: Divizare(P(n)) IF n ≤ nc THEN <rezolvare directă> ELSE <descompune P(n) în k subprobleme P1(n1)...4.2kb) = T(0. Fiecare dintre subproblemele independente obţinute prin divizare se rezolvă... b) = k+1 = lga+1. Tehnica divizării Principiu.k DO Divizare(Pi(ni) <compunere rezultate> Reducere şi divizare .2 b) = T(1.22b)+1 k-2 2 T(2 ..2 b) = T(2k-3.2b) = T(2k-2.Proiectarea algoritmilor Aplicăm metoda iteraţiei pentru cazul particular a = 2k: T(2k. Dacă ele sunt similare problemei iniţiale atunci se aplică din nou tehnica divizării. Se observă că timpul de execuţie depinde doar de valoarea lui a şi pentru a = 2k avem T(a) Є Θ(lga)..2 b) =0 Însumând relaţiile rezultă T(a. Procesul de divizare continuă până când se ajunge la subprobleme de dimensiune suficient de mică (dimensiunea critică. Ideal este ca dimensiunile subproblemelor să fie cât mai apropiate (dacă problema de dimensiune n se descompune în k subprobleme e de preferat ca acestea să aibă dimensiuni apropiate de n/k).2k+1b)+1 k+1 T(1.2b)+1 T(2k-1.

.s. poate fi descris astfel: Cautbin1(a. Algoritmul poate fi descris şi în variantă iterativă: Reducere şi divizare ..an care se compară cu v.. Subproblemele sunt independente iar compunerea rezultatelor constă în prelucrarea "IF max1 < max2 THEN max← max2 ELSE max← max1". Alegerea cea mai naturală pentru j este să fie cât mai aproape de mijlocul tabloului...v) cu s şi d delimitând zona din tablou unde se concentrează la un moment dat căutarea. • dacă v < aj atunci căutarea continuă în subtabloul a1.v) IF s > d THEN RETURN FALSE ELSE m ← (s+d) DIV 2 IF am = v THEN RETURN TRUE ELSE IF v < am THEN RETURN cautbin1(a.m-1. Dimensiunea critică este în acest caz nc = 1 (tablou constituit dintr-un singur element)... În practică cel mai adesea se utilizează k = 2 şi n1 = [n/2].. • dacă v = aj atunci a fost găsit elementul căutat..v) ELSE RETURN cautbin1(a.m+1...s.. Algoritmul elaborat în acest mod. n2 = n-[n/2]. Algoritmul pentru determinarea maximului prezentat în prima secţiune se bazează pe tehnica divizării pentru k = 2 şi dimensiunea critică nc = 1. Pe de altă parte. Tehnica divizării se poate aplica aici astfel: • se alege un element aj din a1.d... se observă că pentru această problemă doar una dintre cele două subprobleme trebuie rezolvată.an.67 - .d. La început se caută în întreg tabloul astfel că la primul apel avem s = 1 şi d = n.aj altfel ea continuă în subtabloul aj+1. Să considerăm problema căutării unei valori v într-un tablou a1.Proiectarea algoritmilor Exemple... numit algoritmul căutării binare.an ordonat crescător.

când v nu se află în tablou).v) s←1 d←n gasit ← FALSE WHILE (s ≤ d) AND (gasit=FALSE) DO m ← [(s+d)/s] IF am = v THEN gasit = TRUE ELSE IF v < am THEN d ← m-1 ELSE s ← m+1 RETURN gasit Pentru a evita compararea de două ori a valorii căutate cu elemente ale tabloului (am = v şi v < am) algoritmul poate fi rescris în forma următoare: Cautbin3(a.n.n.v) s←1 d←n WHILE (s < d) DO m ← [(s+d)/s] IF v ≤ am THEN d←m ELSE s ← m+1 IF v = as THEN RETURN TRUE ELSE RETURN FALSE Pentru a analiza algoritmul căutării binare să considerăm că T(n) reprezintă numărul maxim de comparaţii efectuate asupra elementelor tabloului (se atinge în cazul cel mai defavorabil. Aplicând metoda iteraţiei obţinem: T(2m) T(2m-1) Reducere şi divizare . Relaţia de recurenţă corespunzătoare este: dacă n = 1 ⎧1 T ( n) = ⎨ dacă n > 1 ⎩T ([n / 2]) + 1 Pentru stabili valoarea lui T(n) să analizăm pentru început cazul particular n = 2m.Proiectarea algoritmilor Cautbin2(a.68 = T(n) = T(n/2) = T(n/2) + 1 = T(n/4) + 1 .

În concluzie căutarea binară este de complexitate O(lgn). Reducere şi divizare .... Presupunem că T(k) = [lgk] + 1 pentru orice k < n şi arătăm că T(n) = [lgn] + 1.. pentru n = 2m.. Pentru n arbitrar relaţia se demonstrează prin inducţie matematică. Algoritmul căutării binare poate fi mai degrabă văzut ca un exemplu de aplicare a tehnicii reducerii (prin împărţirea problemei în două subprobleme dintre care doar una se rezolvă).. Observaţie. Tratăm separat cazurile: (i) n=2k. m = 2 şi k = 1. k = 2. . deci se aplică cazul al treilea al teoremei obţinâdu-se T(n) = n.69 - . În primul caz se obţine: T(n) = T(k) + 1 = [lgk] + 2 = [lgk + 1] + 1 = [lg(2k)] + 1 = [lgn] + 1 În al doilea caz obţinem: T(n) = T(k) + 1 = [lgk] + 2 = [lgk + 1] + 1 = [lg(2k)] + 1 = Ceil(lg(2k + 1)) = [lgn]+1 unde s-au utilizat relaţiile [lgn]+1= ceil(lg(n+1)) pentru nЄN şi [x]+1=ceil(x) pentru x ∉ N . Reprezintă o tehnică de analiză a algoritmilor elaboraţi prin tehnica divizării. Cu aceste ipoteze costul corespunzător algoritmului verifică relaţia de recurenţă: dacă n ≤ nc ⎧T0 T ( n) = ⎨ ⎩k ⋅ T (n / m) + TDC (n) dacă n > nc Determinarea lui T(n) pornind de la această recurenţă este uşurată de teorema următoare: ⎧Θ(n d ) dacă k < m d ⎪ T (n) = ⎨Θ(n d lg n) dacă k = m d ⎪ log m k ) dacă k > m d ⎩Θ(n Exemplu. . (ii) n = 2k + 1.. Considerăm că divizarea şi compunerea rezultatelor au împreună costul TDC(n) iar costul rezolvării în cazul particular este T0.. Se aplică cazul al doilea al teoremei master (1 = 20) şi se obţine T(n) =Θ(lgn).. m = 2. Presupunem că o problemă de dimensiune n este descompusă în m subprobleme de dimensiuni n/m dintre care este necesar să fie rezolvate k ≤ m. Metoda master.Proiectarea algoritmilor . Ceil este funcţia care dă un număr natural rotunjit la valoarea superioară întreagă a numărului real. Pentru algoritmul maxim avem d = 0. Pentru algoritmul căutării binare avem: TDC(n) = Θ(1) deci d = 0. T(21) = T(2) = T(1) + 1 T(20) = T(1) = 1 Însumând cele m + 1 relaţii se obţine T(n) = m + 1 = lgn + 1.

8. Propuneţi un algoritm pentru calculul lui An. număr natural arbitrar. Modificaţi algoritmul maxim astfel încât să permită determinarea atât a valorii maxime cât şi a celei minime. x2. Se aplică aceeaşi prelucrare asupra celor două mulţimi eliminând din mulţimea minimelor valorile mari şi din cea a maximelor valorile mici. Propuneţi un algoritm mai eficient decât putere1 pentru calculul puterii xn pentru un n. Modificaţi algoritmul de căutare binară astfel încât să returneze poziţia valorii căutate în cazul în care aceasta e prezentă în tablou şi -1 în caz contrar.. k k k− 3. 2.. Folosind relaţia Cn = Cn−1 + Cn−11 scrieţi un algoritm recursiv pentru calculul k lui Cn . Analizaţi complexitatea algoritmului propus şi comparaţi ordinul de n! k complexitate cu cel al algoritmului bazat pe relaţia: C n = . Pentru fiecare pereche se transferă valoarea minimă într-o mulţime cu minime iar valoarea maximă într-o mulţime cu maxime.Proiectarea algoritmilor 6. Se modifică ordinul de complexitate în raport cu algoritmul clasic de inserţie ? Reducere şi divizare . Analizaţi algoritmul propus. Scrieţi un algoritm de generare a permutărilor bazat pe abordarea "bottom-up" şi analizaţi complexitatea acestuia. cu A matrice pătratică de ordin n care să aibă o complexitate mai mică decât Θ(n4). k DO xi ↔ xk perm(k + 1) xi ↔ xk 7. Indicaţie. Exerciţii 1. Stabiliţi numărul de comparaţii efectuate. se bazează pe tehnica căutării binare..xi-1. Modificaţi algoritmul de sortare prin inserţie astfel încât căutarea poziţiei în care se inserează elementul xi în subtabloul x1. x2...70 - . xn ELSE FOR i ← 1.5. Stabiliţi ordinul de complexitate al algoritmului propus.. k!⋅(n − k )! 4. Algoritmul obţinut este mai eficient decât cel care constă în determinarea separată a minimului şi a maximului ? 5.. Scrieţi un algoritm care să implementeze următoarea idee pentru determinarea simultană a valorii minime şi maxime dintr-un tablou: Se grupează elementele tabloului în [n/2] perechi. 6. Algoritmul va fi apelat cu perm(1) şi poate fi descris prin: perm(k) IF k = n + 1 THEN WRITE x1. Procesul continuă până când aceste mulţimi conţin câte un element. Analizaţi complexitatea algoritmului obţinut.

Sortare prin interclasare Idee. Dimensiunea critică..2. Aceasta presupune: (i) descompunerea şirului iniţial în două subşiruri. Modul de lucru al sortării prin interclasare este ilustrat în figura 7. Figura 7.. 7. x[n/2] şi x[n/2]+1. implicit ordonat.1. xn se descompune în două subşiruri de lungimi cât mai apropiate: x1. Algoritmii elementari prezentaţi anterior au complexitate de ordinul O(n2). Sortarea prin interclasare Aplicaţii ale tehnicilor de reducere şi divizare . Şirul x1.... x2. Introducere Considerăm din nou problema ordonării crescătoare a unui şir de valori x1.. APLICAŢII ALE TEHNICII DIVIZĂRII... Se construieşte şirul final ordonat parcurgând cele două subşiruri şi preluând elemente din ele astfel încât să fie respectată relaţia de ordine (această prelucrare se numeşte interclasare). (iii) combinarea şirurilor ordonate parţiale pentru a obţine varianta ordonată a şirului total. sub care problema poate fi rezolvată direct este nc = 1. xn. Este posibil să se folosească şi 1 < nc ≤ 10 aplicând pentru sortarea acestor subşiruri una dintre metodele elementare de sortare (de exemplu metoda inserţiei). SORTAREA PRIN INTERCLASARE ŞI SORTAREA RAPIDĂ 7.. xn se ordonează fiecare dintre subşiruri aplicând aceeaşi tehnică.1.71 - .1. Ideea de start o reprezintă încercarea de a reduce această complexitate folosind principiul "divide et impera". În continuare sunt prezentate două metode de sortare bazate pe principiul divizării: sortarea prin interclasare ("mergesort") şi sortarea rapidă ("quicksort")... x2.Proiectarea algoritmilor 7.. x2. (ii) ordonarea fiecăruia dintre acestea folosind aceeaşi tehnică. În acest caz subşirul se reduce la un singur element. Acestea diferă atât în etapa descompunerii şirului în subşiruri cât şi în recombinarea rezultatelor.

m) mergesort(x.li.ls) i ← li {contor subşir li÷m} j ← m+1 {contor subşir m+1÷ls} k←1 {contor şir ieşire} WHILE (i ≤ m) AND (j ≤ ls) DO IF xi ≤ xj THEN ck ← xi {transfer din subşirul li.m} i←i+1 ELSE ck ← xj {transfer din subşirul m+1. Elementele celuilalt şir sunt transferate direct în şirul final.Proiectarea algoritmilor Structura generală a algoritmului este următoarea: Mergesort(x.m+1. În şirul final se transferă elementul mai mic dintre cele două iar contorul utilizat pentru parcurgerea şirului din care s-a transferat un element este incrementat. Există diverse modalităţi de a descrie algoritmic această prelucrare.m} ck ← xi i←i+1 k←k+1 WHILE (j ≤ ls) DO {transfer din rest din subşirul m+1.li.m.li.ls} ck ← xj j←j+1 k←k+1 j ← ls FOR i ←1 k-1 DO {refacere şir x} xj ← ci j ←j+1 Aplicaţii ale tehnicilor de reducere şi divizare . Procesul continuă până când unul dintre şiruri a fost transferat în întregime. Una dintre acestea este: Merge(x.ls) IF li < ls THEN m ← [(li+ls)/s] mergesort(x. Ideea prelucrării constă în a parcurge în paralel cele două şiruri şi a compara elementele curente.ls} j←j+1 k←k+1 WHILE (i ≤ m) DO {transfer din rest din subşirul li.72 - .m.ls) RETURN x {sortează prima jumătate} {sortează a doua jumătate} {interclasează cele două subşiruri} Interclasare. Etapa cea mai importantă a prelucrării este reprezentată de interclasare.ls) merge(x. Scopul acestei prelucrări este construirea unui şir ordonat pornind de la două şiruri ordonate.li.

TC(p. În acest caz algoritmul poate fi descris într-o formă mai condensată după cum urmează: Interclasare_fanion(a.i .xm crescător ∧ xm+1. Pentru a demonstra că algoritmul asigură satisfacerea postcondiţiei este suficient să se arate că {c1.. q) şi cel de transferuri ale elementelor (TM(p.p] şi b[1.... Observaţii.în cazul cel mai favorabil.73 - .q] (independent de algoritmul de sortare prin interclasare).1} este proprietate invariantă pentru fiecare dintre cele trei prelucrări repetitive. respectiv q + 1. Fanioanele constau în valori mai mari decât toate valorile prezente în a şi b plasate pe poziţiile p + 1.în cazul cel mai defavorabil.. Contorizând numărul de comparaţii (TC (p.ck-1 este crescător ∧ k = i +...q)) se obtine: TC(p.b.q) Є Θ( p+q).q]..q) Є Ω(min(p. Aplicaţii ale tehnicilor de reducere şi divizare .... Analiza complexităţii.cp+q este crescător} (notăm cu p numărul de elemente din primul tablou şi cu q numărul de elemente din al doilea). Costul redus al prelucrărilor din metoda mergesort este însă contrabalansat de faptul că se utilizează (la interclasare) o zonă de manevră de dimensiune proporţională cu cea a tabloului iniţial.xls crescător} iar postcondiţia este: { c1.p] şi b[1.. iar TM(p. Să analizăm cazul interclasării a două tablouri a[1.p.....q)) .q) Є O(p+q-1) .q) ap+1 ← ∞ {fixare fanioane} bq+1 ← ∞ i←1 {contor de intrare} j←1 FOR k ← 1. Notând cu T(n) numărul de prelucrări (comparaţii şi transferuri) efectuate de către sortarea prin interclasare şi cu Tinter(n) cele efectuate pe parcursul interclasării se obţine relaţia de recurentă: n =1 ⎧0 T ( n) = ⎨ n >1 ⎩T ([n / 2]) + T (n − [n / 2]) + Tint er (n) Cum k = m = 2 iar Tinter(n) Є Θ(n) rezultă că se poate aplica cazul doi al teoremei master (d = 1.Proiectarea algoritmilor Precondiţiile prelucrării de mai sus sunt: {xli. Prin urmare în varianta cu fanion se efectuează mai multe comparaţii decât în cea fără fanion.p+q DO IF ai ≤ bj THEN ck ← ai {transfer din subşirul a } i←i+1 ELSE ck ← bj {transfer din subşirul b} j←j+1 În acest caz atât numărul de comparaţii cât şi numărul de transferuri este TC(p. q) = p + q. k = md) obţinându-se că sortarea prin interclasare are complexitate Θ(nlgn). O variantă de algoritm este cea care foloseşte câte un fanion pentru fiecare dintre tablourile a[1.q) = TM(p.

Se observă că elementul 4 se află pe o poziţie privilegiată (q = 4) întrucât toate elementele care îl preced sunt mai mici decât el şi toate cele care îl succed sunt mai mari. Structura generală. x2. Exemplul 2. Aceasta înseamnă că se află deja pe poziţia finală.3.xn. Sortare rapidă Idee.. Scopul urmărit este de a simplifica combinarea rezultatelor. ls) RETURN x Aplicaţii ale tehnicilor de reducere şi divizare .li.74 - . q) quicksort1(x. Exemplul 1.n}. q} şi orice j Є {q+1...li.. 2.5. În aceste situaţii trebuie "creat" unul prin modificarea poziţiilor unor elemente. Ideal ar fi ca prin concatenarea şirurilor ordonate să se obţină şirul ordonat în întregime.ls) IF li < ls THEN q ← partitie1(x..li.ls) IF li < ls THEN q ← partitie2(x. Structura generală a acestor algoritmi poate fi descrisă prin: Quicksort1 (x.xq-1 şi xq+1. Se observă că poziţia q = 3 are următoarea proprietate: xi ≤ xj pentru orice i Є {1.. Acest tip de sortare este cunoscută sub numele de sortare rapidă (" quicksort") şi a fost dezvoltată de Hoare...xq şi xq+1. 1. 7.. Asta face ca elemente cu valori mici (sau mari) să se poată afla în fiecare dintre subşiruri.. 8)..5. Nu întotdeauna există un astfel de pivot după cum se observă din subşirul (3.1....q-1 şi xi ≥ xq pentru i=q+1.4.. Alteori pivotul. x2. dacă există. Considerăm şirul: x = (3...1. 5.. Poziţia q este numită poziţie de partiţionare.... La sortarea prin interclasare descompunerea şirului iniţial în două subşiruri se realizează pe baza poziţiei elementelor. În acest caz sortarea şirului iniţial se reduce la sortarea subşirurilor x1.8) valoarea de pe ultima poziţie poate fi considerată valoare pivot)...ls) quicksort1(x. Pornind de la exemplele de mai sus se pot dezvolta două variante de sortare bazate pe descompunerea şirului initial in două subşiruri: una care foloseşte un element pivot iar alta care foloseşte o poziţie de partiţionare..li.xn. Un element xq având proprietăţile: xi ≤ xq pentru i=1. O altă modalitate de descompunere ar fi aceea în care se tine cont şi de valoarea elementelor.2. Existenta unui pivot permite reducerea sortării şirului iniţial la sortarea subşirurilor x1. Din această cauză este necesară combinarea rezultatelor prin interclasare. Să considerăm acum şirul (3.2.n se numeşte pivot. q-1) quicksort1(x.q+1.7.ls) quicksort1(x.li.2).8). 4.q+1..li.Proiectarea algoritmilor 7. ls) RETURN x respectiv Quicksort2 (x.. se află pe o poziţie care nu permite descompunerea problemei iniţiale în subprobleme de dimensiuni apropiate (de exemplu în subşirul (7.

.5). Iniţial i = 0.2.li.ls) v ← xls i ← li -1 j ← ls WHILE i < j DO REPEAT i ← i+1 UNTIL xi ≥ v REPEAT j←j-1 UNTIL xj ≤ v IF i < j THEN xi ↔ xj xi ↔ xls RETURN i {se alege valoarea pivotului} {contor parcurgere stânga . Considerăm problema identificării în x1. Cum i < j se interschimbă x2 cu x6 obţinânduse (1. iar de la dreapta la stânga j = 4. Să considerăm şirul (4.4). Etapa 3.dreapta } {contor parcurgere dreapta . iar cele mai mari în a doua parte a şirului.8.4). Cum i < j se interschimbă x3 cu x4 şi se obtine (1.3. Ideea este următoarea: se alege o valoare arbitrară dintre cele prezente în şir şi se rearanjează elementele şirului (prin interschimbări) astfel încât elementele mai mici decât această valoare să fie în prima parte a şirului. xq cu proprietatea că xi ≤ xq pentru i < q şi xi ≥ xq pentru i > q.. Succesiunea prelucrărilor este: Etapa 1. Parcurgerea în continuare de la stânga la dreapta conduce la i = 3.8.8. În felul acesta se determină şi poziţia q pe care trebuie plasată valoarea. După execuţia primului ciclu REPEAT se obţine i = 2 (căci 7 > 4) iar după execuţia celui de al doilea se obţine j = 6. Partiţionare.7. Discutăm separat cele două variante deşi după cum se va vedea diferentele dintre ele sunt puţine.2.3. După cum s-a văzut în exemplul anterior nu întotdeauna există un pivot. Algoritmul poate fi descris astfel: Partitie1 (x.8.4.3..2. poziţia pivotului fiind 4.Proiectarea algoritmilor Diferenţa dintre cele două variante este mică: în prima variantă în prelucrarea de partiţionare se asigură şi plasarea pe poziţia q a valorii finale pe când în a doua doar se determină poziţia de partiţionare.7. Cum i > j se iese din prelucrarea repetitivă exterioară. Este prelucrarea cea mai importantă a algoritmului. Considerăm şirul (1.stânga} Exemplul 1. x0 = v condiţia de oprire a celui de-al doilea REPEAT nu Aplicaţii ale tehnicilor de reducere şi divizare . Exemplul 2. Etapa 2. În aceste situaţii se creează unul. iar elementele x4 şi x7 se interschimbă obţinându-se (1.7.2. j = 1 (a se observa că în acest caz fără a folosi o poziţie suplimentară cu rol de fanion. Această situaţie nu este insă obţinută întotdeauna.8.xn a unui pivot. Această poziţie asigură o partiţionare echilibrată a şirului.2.4).75 - .7. 1).5. Continuând parcurgerile în cele două direcţii se ajunge la i = 4 şi j = 3.5.5. j = 7 iar v = 4.7.5.3. Aplicând acelaşi algoritm după prima etapă se obţine: i = 1.3.

.i. Cum precondiţia este li < ls. iar dacă i ≥ j atunci xk ≤ v pentru k = li.. Ultima interschimbare asigură plasarea valorii fanion pe poziţia sa finală. şirul devine (1.4) iar poziţia pivotului este q = 1.. (ii) Problema nesatisfacerii condiţiei de oprire pentru ciclul după j poate să apară doar în cazul in care li = 1 şi atunci când v este cea mai mică valoare din şir.stânga} În acest caz se poate arăta că aserţiunea {dacă i < j atunci xk ≤ v pentru k = li.76 - ..5.ls) v ← xli i ← li -1 j ← ls+1 WHILE i < j DO REPEAT i ← i+1 UNTIL xi ≥ v REPEAT j←j-1 UNTIL xj ≤ v IF i < j THEN xi ↔ xj RETURN j {se alege valoarea pivotului} {contor parcurgere stânga ..ls}.. Este de preferat să se folosească valoare fanion decât să se extindă condiţia de oprire de la ciclu (de exemplu cu j < i). Partitie2 (x..i-1. pivotul aflat pe prima poziţie şi un subşir constituit din celelalte elemente)...... iar xk ≥ v pentru k = j+1. xk ≥ xi pentru k=i+1.li.i.. În plus el nu este plasat la sfârşit pe poziţia finală fiind necesară astfel sortarea subşirurilor xli. Aceasta diferă de prima în special prin faptul că permite ca valoarea pivotului să participe la interschimbări.3.. iar xk ≥ v pentru k = j...dreapta } {contor parcurgere dreapta .ls} se poate arăta că aserţiunea de mai sus este invariantă in raport cu prelucrarea repetitivă WHILE.i. În acelaşi timp dacă s-ar utiliza > şi < valoarea v nu ar putea fi folosită ca fanion.2. Considerăm acum cealaltă variantă de partiţionare.xls.. Se poate remarca că pentru primul ciclu REPEAT xls joacă rolul unui fanion...xq şi xq+1. iar după efectuarea ultimei interschimbări implică postcondiţiile.. În acest caz s-a obţinut o partiţionare dezechilibrată (şirul se descompune într-un subşir vid. Observaţii.. (i) Inegalităţile de tip ≥ şi ≤ din ciclurile REPEAT fac ca în cazul unor valori egale să se obţină o partiţionare echilibrată şi nu una dezechilibrată cum s-ar întâmpla dacă s-ar folosi inegalităţi stricte..8. Algoritmul poate fi descris după cum urmează. deci i < j şi postcondiţiile sunt {xk ≤ xi pentru k=1... Pentru a justifica corectitudinea algoritmului partiţie1 considerăm aserţiunea: {dacă i < j atunci xk ≤ v pentru k = li. (iii) La ieşirea din prelucrarea repetitivă exterioară (WHILE) indicii 'i şi ...7...Proiectarea algoritmilor este niciodată satisfăcută).ls. iar Aplicaţii ale tehnicilor de reducere şi divizare .i satisfac una dintre relaţiile: i = j sau i = j + 1.. Aceasta face să nu mai fie necesară plasarea pe poziţia 0 a unui fanion întrucât se creează în mod natural fanioane pentru fiecare dintre cele două cicluri REPEAT.

. Analiza în cazul cel mai favorabil.ls. Se bazează pe ipoteza că toate cele n poziţii ale şirului au aceeaşi probabilitate de a fi selectate ca poziţie pivot (probabilitatea este în acest caz 1/n... Aplicând metoda iteraţiei se obţine T(n) = (n... Se obţine astfel că în cazul cel mai defavorabil complexitatea este pătratică. respectiv n-[n/2]-1.1) + n + 1. Influenţa majoră asupra numărului de comparaţii efectuate de către quicksort1 o are raportul dintre dimensiunile celor două subşiruri obţinute după partiţionare.ls adică postcondiţia xk1 ≤ xk2 pentru orice k1= li.. Spre deosebire de metodele elementare de sortare pentru care un şir iniţial sortat conducea la un număr minim de prelucrări în acest caz tocmai aceste situaţii conduc la costul maxim (pentru un şir deja ordonat la fiecare partiţionare se obţine pivotul pe ultima poziţie). Prin urmare în cazul cel mai favorabil complexitatea algoritmului quicksort1 este Θ(nlgn).q... Atunci relaţia de recurenţă corespunzătoare este T(n) = T(n ..77 - . Analizăm complexitatea variantei quicksort1.1) + T(n . + 1)(n + 2)/2 . Presupunem că la fiecare partiţionare se efectuează n + 1 comparaţii şi că se generează un subşir vid şi unul de lungime n . Analiza în cazul cel mai defavorabil. iar numărul de comparaţii din partiţionare este n. iar cele mai puţin favorabile partiţionării dezechilibrate. Prin urmare numărul mediu de comparaţii satisface: Aplicaţii ale tehnicilor de reducere şi divizare .q) + n + 1. iar dacă i = j + 1 se vor efectua n + 1 comparaţii. întrucât nu se mai reduce dimensiunea problemei). Cu cât dimensiunile celor două subşiruri sunt mai apropiate cu atât se reduce numărul comparaţiilor efectuate..1.. Pe parcursul partiţionării numărul de comparaţii depăşeşte în general numărul de interschimbări. iar dacă i ≥ j atunci xk ≤ v pentru k = li.ls} este invariantă în raport cu ciclul WHILE iar la ieşirea din ciclu (când i = j sau i = j + 1) implică xk ≤ v pentru k = li.)......j şi xk ≥ v pentru k = j + 1. k2=j+1. numărul de comparaţii efectuate în cazul în care poziţia pivotului este q satisface: Tq(n) = T(q . Pentru un şir de lungime n numărul de comparaţii efectuate în cele două cicluri REPEAT din partiţionare1 este n + i .j. Analiza în cazul mediu.ls. Presupunem că la fiecare partiţionare a unui şir de lungime n se obţin două subşiruri de lungimi [n/2]. Presupunând că la fiecare partiţionare a unui şir de lungime n se efectuează n + 1 comparaţii.ls]). iar xk ≥ v pentru k = j+1.3.i-1. În cazul în care se doreşte ca xls să fie valoarea pivot este necesar ca apelurile recursive să se facă pentru: quicksort2(x. Astfel.q-1) şi qvicksort2(x. Astfel cazurile cele mai favorabile corespund partiţionării echilibrate.li.j (i şi j fiind valorile finale ale contoarelor). Pentru a evita partiţionarea dezechilibrată au fost propuse diverse variante de alegere a valorii pivotului. În aceste condiţii putem considera că marginea superioară a numărului de comparaţii satisface o relaţie de recurenţă de forma T(n) = 2T(n/2) + n ceea ce conduce prin teorema master la o complexitate de ordin nlgn.Proiectarea algoritmilor xk ≥ v pentru k = j. dacă i = j se vor efectua n comparaţii.... adică sortarea rapidă aparţine clasei O(n2). De remarcat că dacă se alege ca pivot xls varianta quicksort2 nu va funcţiona corect putând conduce la situaţia în care unul dintre subtablouri este vid (ceea ce provoacă o succesiune nesfârşită de apeluri recursive. Analiza complexităţii. una dintre acestea constând în selecţia a trei valori din şir şi alegerea ca valoare a pivotului a medianei acestor valori (valoarea aflată pe a doua poziţie în tripletul ordonat). motiv pentru care vom analiza doar numărul de comparaţii efectuate.

. Care este operaţia determinantă în asigurarea stabilităţii ? 3.. Descrieţi sortarea prin interclasare în manieră nerecursivă....Proiectarea algoritmilor 1 n 2 n ⋅ ∑ Tq (n) = n + 1 + ⋅ ∑ Tm (q − 1) n q =1 n q =1 Scăzând între ele relaţiile următoare (care rezultă din relaţia de mai sus): Tm (n) = n ⋅ Tm (n) = 2 ⋅ ∑ Tm (q − 1) + n ⋅ (n + 1) q =1 n (n − 1) ⋅ Tm (n − 1) = 2 ⋅ ∑ Tm (q − 1) + n ⋅ (n − 1) q =1 n −1 se obţine relaţia de recurenţă pentru Tm: n ⋅ Tm (n) = (n + 1) ⋅ Tm (n − 1) + 2 ⋅ n Aplicând metoda iteraţiei rezultă: Tm(n) Tm(n-1) Tm(n-2) . Observaţii. Să se studieze stabilitatea sortării prin interclasare. Tm(2) Tm(1) iar prin însumare se obţine: n 1 1⎞ 1 ⎛1 Tm (n) = 2 ⋅ (n + 1) ⋅ ⎜ + + . 4. Propuneţi un algoritm de complexitate Θ(nlgn) pentru verifica dacă într-un tablou x1. când este o valoare arbitrar aleasă din şir şi când se stabileşte cu regula Aplicaţii ale tehnicilor de reducere şi divizare .. n +1 ⋅ 3 ⋅ 1...38nlgn... 5.... Aceasta înseamnă că în cazul mediu sortarea rapidă este doar cu 38% mai costisitoare decât în cazul cel mai favorabil. Rescrieţi algoritmul partiţionare1 când valoarea pivotului este prima din şir.. Exerciţii n +1 ⋅ Tm (n − 1) + 2 n n = ⋅ Tm (n − 2) + 2 n −1 n −1 = ⋅ Tm (n − 3) + 2 n−2 .. Să se extindă algoritmul de interclasare pentru un număr arbitrar de şiruri ordonate. + ⎟ + 2 = 2 ⋅ (n + 1) ⋅ ∑ + 2 ≅ 3⎠ ⎝ n n −1 i =3 i ≅ 2 ⋅ (n + 1) ⋅ (ln n − ln 3) + 2 Prin urmare numărul mediu de comparaţii este de ordinul 2n· lnn ≈ 1. 3 = ⋅ Tm (1) + 2 2 =0 = n +1 n n +1 ⋅ n −1 . Sortarea rapidă nu este nici stabilă şi nici naturală... 7. x2. 2.4.78 - .xn există cel puţin două elemente egale.

Proiectarea algoritmilor medianei.79 - . 6. Construiţi un exemplu prin care să se ilustreze că sortarea rapidă nu este stabilă. 8. 7. Aplicaţii ale tehnicilor de reducere şi divizare . Modificaţi algoritmii de sortare prin interclasare şi sortare rapidă astfel încât să asigure ordonarea descrescătoare. Propuneţi un algoritm eficient prin care se reorganizeaza elementele unui tablou astfel încât toate elementele negative să fie înaintea celor pozitive.

şi anume acela care pare "optim" la momentul respectiv.. Se cere să se determine (dacă i =1 n există) o submulţime având cât mai puţine elemente şi a căror sumă să fie egală cu C.. În acest caz X reprezintă ansamblul submulţimilor lui A.. La o primă vedere problema pare foarte simplă întrucât este suficient să se parcurgă X şi să se aleagă elementul care satisface restricţiile şi optimizează criteriul... Exemplu..Proiectarea algoritmilor 8. a2. Două dintre acestea sunt tehnica alegerii local optimale ("greedy") şi cea a programării dinamice.80 - .sk) ⊂ A astfel încât S să satisfacă anumite restricţii şi să optimizeze un criteriu... Să se determine S = (s1. Principiul metodei constă în a construi succesiv soluţia S pornind de la setul vid şi adăugând la fiecare etapă un nou element. s2. Însă alegerea care pare optimă la etapa curentă s-ar putea să nu fie cea mai bună şi din punct de vedere global astfel că e posibil Tehnica alegerii local optimale „greedy” . O clasă frecvent întâlnită în practică este cea a problemelor de optimizare de tipul: Să se determine x Є X astfel încât: (i) x satisface anumite condiţii (restricţii). Un astfel de algoritm ar avea ordinul de complexitate O(2n).an) un set finit de elemente (nu neapărat distincte). Principiul tehnicii Să considerăm problema de optimizare formulată într-o variantă uşor diferită: Fie A = (a1. TEHNICA ALEGERII LOCAL OPTIMALE ("GREEDY") 8.1. (ii) x optimizează (minimizează sau maximizează) un criteriu. Introducere Problemele pot fi încadrate în clase abstracte de probleme ce au anumite elemente comune. 8. În continuare prin set vom înţelege o mulţime în sens general (elementele sale nu sunt neapărat distincte). O astfel de abordare (numită şi metoda forţei brute) devine total ineficientă (sau chiar impracticabilă) atunci când numărul de elemente din X este foarte mare. problema de optimizare fiind numită în acest caz discretă sau combinatorială. a2... (problema submulţimii de sumă dată şi cardinal minim) Se consideră mulţimea A = {a1... O subclasă importantă în informatică o reprezintă cea în care X este o mulţime finită. an} ⊂ R şi valoarea C ≤ ∑ ai . reţinerea celor care satisfac restricţia (suma elementelor egală cu C) şi alegerea celei (celor) ce au cele mai puţine elemente. O abordare prin metoda forţei brute a unei astfel de probleme necesită generarea tuturor submulţimilor lui A.. Selecţia elementului care va fi eventual adăugat urmăreşte apropierea de atingerea optimului.. Pentru a rezolva mai eficient probleme de acest tip au fost dezvoltate tehnici specifice de elaborare a algoritmilor.2.

. S.n. prin strategia greedy se poate obţine o singură soluţie chiar dacă problema are mai multe. În acest caz algoritmul poate fi descris ceva mai detaliat astfel: Greedy2(A..m DO Si ← Ai RETURN S Pentru această problemă se va demonstra în secţiunea următoare că strategia greedy produce întotdeauna o soluţie optimă.Sk +Ai satisface restricţiile” THEN k ← k+1 Sk ← Ai {se preia elementul} i ← i+1 {se trece la următorul element} RETURN S În aplicaţii contează principiul metodei.S2. să fie ordonat după un criteriu determinat de criteriul de optim astfel că elementele vor fi alese chiar în ordinea în care apar în A.. algoritmii construiţi folosindu-l putând fi destul de diferiţi de structurile generale greedy1 respectiv greedy2.81 - . În acest caz este suficient să ordonăm descrescător elementele din A şi să reţinem primele m elemente: Submultime(A.) Se cere determinarea unui subset cu m elemente. (Problema submulţimii de cardinal dat şi sumă maximă. Criteriul de sortare depinde de problema concretă care se rezolvă. Pe de altă parte.n) {sortare după un criteriu de optimizare} i←0 {contor parcurgere A} k←0 {contor pentru construirea mulţimii S} WHILE “S nu este soluţie” ∧ i ≤ n DO IF „S1. Pentru anumite probleme este posibil ca setul iniţial.Proiectarea algoritmilor să nu conducă la o soluţie optimă. o dată efectuată o alegere nu se mai revine asupra ei. Exemplul 1. aceasta fiind irevocabilă.m) Sortare_descrescatoare(A. Structura generală a algoritmului este: Greedy1(A) S←Ø WHILE “S nu este soluţie” ∧ “există elemente neselectate în A” DO selectează a din A dacă nu sunt încălcate restricţiile se adaugă a la S RETURN S Etapa cea mai importantă este cea a selectării unui nou element.n) Sortare(A.n) FOR i ← 1.. dintr-un set A având n > m elemente astfel încât suma elementelor selectate să fie cât mai mare. Totuşi. Tehnica alegerii local optimale „greedy” . A.

0) este optimă. Dacă valorile monedelor sunt {v1. 0. 5) şi C = 17 problema nu are soluţie. vn este ordonat crescător). 20..C) sortare_descrescatoare(v. Tehnica greedy conduce la o soluţie optimă pentru problema monedelor doar dacă valorile acestora satisfac anumite restricţii.Proiectarea algoritmilor Exemplul 2. Tehnica alegerii local optimale „greedy” . 5.. Se observă uşor că dacă există monedă cu valoarea 1 atunci pentru orice sumă C se poate determina o soluţie. 10... kn) (ki reprezintă numărul de monede de valoare vi şi poate fi egal cu 0) astfel încât să fie satisfăcută restricţia ∑k i =1 n i ⋅ vi = C i iar suma ∑k i =1 n să fie cât mai mică. vn.. 1) şi a valorii C = 40 strategia greedy ar conduce la soluţia (1.n. 2. v2...v2. 0) în timp ce varianta (0. 0... k2. Pe de altă parte există situaţii în care problema nu are soluţii.82 - . (Problema monedelor. 10.... De exemplu pentru cazul monedelor cu valorile (25.... Aceasta nu este însă neapărat optimală. Un exemplu de valori pentru care se poate demonstra optimalitatea soluţiei este: vi-1 este multiplu al lui vi pentru fiecare i ≥ 2 (în condiţiile în care v1... Se observă că această problemă este similară cu problema submulţimii de sumă dată şi cardinal minim cu observaţia că setul A este infinit: A = { v1..n) FOR i ← 1.... v2. Tehnica greedy nu conduce pentru orice instanţă a problemei monedelor la soluţia optimă.) Presupunem că o sumă de bani C trebuie acoperită folosind cât mai puţine monede. v1. De exemplu pentru monede având valorile (20. O abordare de tip greedy ar conduce (în cazul în care numărul de monede de fiecare tip este nelimitat) la un algoritm de forma: Monede(v. 1.} (pentru fiecare valoare vi există un număr nelimitat de elemente).. v2.vn} atunci a rezolva problema înseamnă a determina (k1. 1. vn..n DO Si ← 0 i ←1 WHILE C > 0 ∧ i ≤ n DO Si ← C DIV vi C ← C MOD vi i ← i+1 IF C = 0 THEN RETURN S ELSE WRITE “Nu s-a gasit solutie!” Observaţie. 0...

o2..≥om. Este suficient acum să demonstrăm că problema posedă proprietatea de substructură optimă.om) o soluţie optimă a problemei. Această etapă se reduce de fapt la a arăta că problema are proprietatea de substructură optimă.. Prin urmare o1 = a1 adică primul element al soluţiei este ales conform strategiei greedy. sn ) o ′ 2 soluţie mai bună. Verificarea corectitudinii si analiza complexităţii Tehnica alegerii local optimale este o tehnică intuitivă şi e_cientă.o2. ′ ′ Se presupune că S(n-1) nu este optimă. Fie O = (o1. Se consideră că o problemă are proprietatea de substructură optimă dacă o soluţie optimă a problemei conţine soluţii optime ale subproblemelor... Presupunem că o1 ≠ a1.. Exemplu.. aceasta trebuie demonstrată pentru cazul particular al problemei tratate. Verificarea corectitudinii.. Se analizează în continuare restul soluţiei (problema se reduce la una similară dar de dimensiune mai mică). Cum nu contează ordinea elementelor în O putem presupune că o1 ≥ o2 ≥. Întrucât tehnica greedy nu asigură implicit optimalitatea soluţiei. Pentru a demonstra că o problemă are această proprietate se porneşte de la o soluţie optimă global şi se arată că poate fi modificată astfel încât prima componentă să fie obţinută efectuând o alegere local optimală. • Proprietatea de substructură optimă. Atunci ar exista S ′(n − 1) = ( s2 ...... problemele pentru care tehnica greedy poate fi aplicată cu succes au următoarele proprietăţi: • Proprietatea de alegere greedy. Înseamnă că se poate ajunge la soluţia optimă global efectuând alegeri local optimale.. Aplicând principiul inducţiei matematice se arată că la fiecare pas poate fi efectuată o alegere de tip greedy.. Pornind de la o soluţie optimă S(n) = (s1.≥an) prin alegere de tip greedy prima componentă ar trebui să fie a1.3... s2. Cum elementele lui A sunt ordonate descrescător (a1 ≥ a2 ≥. Vom arăta că o1 = a1 prin metoda reducerii la absurd.1....om) are proprietatea că are suma mai mare ca soluţia O.83 - . Pentru a demonstra acest lucru se poate folosi tehnica reducerii la absurd.. Aceasta conduce de regulă la faptul că S ′(n) = ( s1 . Rezultă că a1 > o1 iar soluţia O’ = (a1.. deci mai bună decât O. Tehnica alegerii local optimale „greedy” ... Aceasta însă contrazice ipoteza că O este soluţie optimă..Proiectarea algoritmilor 8. s′ ) n este mai bună decât S(n) ceea ce contrazice ipoteza că S(n) este optimă. s′ .... Proprietatea de alegere greedy. În general. sn) se arată că S(n .1) = (s2...sn) este soluţie optimă pentru subproblema de dimensiune n . Demonstrăm că algoritmul submulţime generează soluţia optimă. dar nu garantează obţinerea soluţiei optime decât pentru anumite cazuri particulare de probleme.

. Aplicaţii Problema rucsacului.. Este posibil să fie transferate şi fracţiuni din obiecte..om) o soluţie optimă a problemei iniţiale. (pik. Analiza complexităţii. În algoritmul monede sortarea domină celelalte prelucrări astfel că aceasta impune ordinul de complexitate (O(n2) sau O(nlgn)). atât cât să se umple rucsacul.. (pn. (ii) se transferă obiectele în ordinea în care apar în A. ((pi1. Se ajunge astfel la un ordin de complexitate O(mn). În cazul algoritmului submulţime dacă m este mic în raport cu n atunci nu este justificat să se ordoneze întregul set A ci să se alegă la fiecare etapă valoarea maximă din cele ce nu au fost încă selectate.o2. Din structura generală (greedy1) se observă că prelucrarea care determină ordinul de complexitate este cea de selecţie... Se consideră un set de obiecte caracterizate prin profitul (p) şi dimensiunea lor (d): A = ((p1...dik)) care să nu depăşească ⎛ k ⎛ k ⎞ ⎞ capacitatea rucsacului ⎜ ∑ d ij ≤ C ⎟ şi să asigure un profit maxim ⎜ ∑ pij = max!⎟ . profitul asigurat fiind proporţional cu fracţiunea. În acest caz alegerea local optimală este cea care corespunde profitului relativ maxim (profitul relativ al obiectului i este pi /di).. Este o problemă clasică ce are multe aplicaţii şi diverse variante.. Aplicând strategia greedy se ajunge la a efectua următoarele prelucrări: (i) se ordonează A descrescător după profitul relativ... Tehnica alegerii local optimale „greedy” . Strategia greedy conduce în general la algoritmi eficienţi. di1).. Fie O = (o1.≥an).. dn)).84 - .om) este soluţie optimă a problemei similare pentru A(2) = (a2... deci problema posedă proprietatea substructurii optime. ⎜ ⎜ ⎟ ⎟ ⎝ j =1 ⎝ j =1 ⎠ ⎠ Două dintre cele mai cunoscute variante ale problemei sunt: • Varianta discretă (0-1). Arătăm că O(1) = (o2.. Se mai consideră un rucsac de capacitate maximă C şi se pune problema selectării unui subset de obiecte. În general însă aplicarea strategiei necesită o sortare prealabilă a elementelor lui A astfel că se ajunge la complexitate de tipul O(n2) sau O(nlgn) (dacă se foloseşte un algoritm eficient de sortare). Presupunem că elementele lui A sunt ordonate descrescător (a1 ≥ a2 ≥. Dacă aceasta este simplă se pot obţine chiar algoritmi de complexitate liniară....Proiectarea algoritmilor Proprietatea substructurii optime.4. Dacă nu ar fi soluţie optimă înseamnă că ar exista o ′ altă soluţie mai bună: ( o2 .. d1)... 8. • Varianta continuă (fracţionară). Doar pentru varianta fracţionară se poate obţine o soluţie optimă aplicând strategia greedy. Obiectele nu pot fi divizate: un obiect este fie preluat în întregime fie nu este preluat.... S-a ajuns la o contradicţie. în întregime cu excepţia ultimului obiect din care se ia doar o fracţiune.an) prin reducere la absurd. o′ ) care completată pe prima poziţie cu o1 ar conduce la o m soluţie globală mai bună decât O.

on ) este generată aplicând tehnica greedy.. B− = {i | oi′ < oi } iar k = minB_ (cel mai mic indice pentru care oi′ < oi). o2 ..p.Ai..n.. 0.d reprezintă profitul respectiv dimensiunea obiectului i. Fie B+ = {i | oi′ ≥ oi } . Ai. 1..n DO Si ← 0 i ←1 WHILE C > 0 ∧ i ≤ n DO IF Ai.d ≤ C THEN Si ← 1 C ← C .85 - .. on) o soluţie optimă şi demonstrăm că este de tip greedy prin reducere la absurd.p/ Ai. Soluţia va fi de forma: S = (S1.d C ←0 i←i+1 RETURN S {după profitul relativ Ai..Proiectarea algoritmilor Pentru a descrie algoritmul facem următoarele convenţii: Ai... Considerăm O = (o1.. 1].C) Sortare_descrescatoare(A.obiectul i nu este selectat.. astfel că în continuare considerăm că restricţia problemei este de n tip egalitate.... o2.d} Soluţia obţinută aplicând acest algoritm va fi de forma: S = (1.. Din structura unei soluţii de tip greedy rezultă că dacă i ∈ B+ şi j ∈ B. Demonstrăm că rucsac fracţionar generează o soluţie optimă arătând că orice soluţie optimă trebuie să respecte criteriul alegerii greedy. >pn/dn (în cazul când inegalitatea nu este strictă alegerea de tip greedy nu este unică şi complică puţin demonstraţia).. În plus i =1 ∑ Si ⋅ di = C . S2.n) FOR i ← 1...este selectată doar o fracţiune din obiectul i.atunci i < j. Din restricţia problemei rezultă: B i =1 ∑ oi ⋅ di = ∑ oi′ ⋅ di i =1 i∈B− n n adică i∈B+ ∑ (oi′ − oi ) ⋅ di = ∑ (oi − oi′ ) ⋅ di Tehnica alegerii local optimale „greedy” .. Sn ) cu Si ∈ [0. 0). Considerăm că obiectele sunt ordonate descrescător după valoarea profitului relativ: p1/d1 > p2/d2>. Si ∈ (0.. Cu aceste convenţii algoritmul poate fi descris astfel: Rucsac_fractionar(A. Presupunem că O ′ ′ ′ nu este de tip greedy şi considerăm că O′ = (o1.. 1) . 1. iar elementele sale vor fi interpretate astfel: Si = 0 . Si = 1 – obiectul i este selectat în întregime... f.d ELSE Si ← C/Ai.

5... Dintre aceste variante cea pentru care se poate demonstra că asigură obţinerea soluţiei optime este a treia: la fiecare etapă se alege activitatea care se termină cel mai devreme. 10). aim) care satisfac [pij .Proiectarea algoritmilor Calculăm profiturile corespunzătoare celor două soluţii: P = ∑ oi ⋅ pi i =1 n ′ şi P′ = ∑ oi ⋅ pi i =1 n diferenţa lor este ′ P′ − P = ∑ (oi − oi ) ⋅ pi = i =1 n Se observă că pi/di > pk/dk pentru orice i ∈ B+ iar pi/di ≤ pk/dk pentru orice i ∈ B. Pentru a ilustra faptul că pentru varianta discretă această strategie nu conduce la soluţia optimă considerăm exemplul: A = ((60. ai2. În schimb se poate obţine o soluţie optimă aplicând tehnica programării dinamice. 220. 20). 4. Dacă s-ar transfera al doilea şi al treilea obiect s-ar ajunge la un profit mai mare. O soluţie a acestei probleme constă într-un subset de activităţi S = (ai1. 30)). (100. Presupunem că pentru fiecare activitate. Prin urmare B B i∈B+ ∑ (oi′ − oi ) ⋅ di ⋅ d i − ∑ (oi − oi′ ) ⋅ di ⋅ d i i i∈B− i p p p p ′ P′ − P > k ∑ (oi′ − oi ) ⋅ d i − k ∑ (oi − oi ) ⋅ d i = 0 d k i∈B d k i∈B + − Însă P′ > P contrazice ipoteza că O este optimă. Se consideră un set de activităţi care au nevoie de o anumită resursă şi la un moment dat o singură activitate poate beneficia de resursa respectivă (de exemplu activitatea poate fi un examen..p. Se cere să se selecteze un număr cât mai mare de activităţi compatibile. Deşi nu conduce la soluţia optimă. Notând cu Ai. Problema selectării activităţilor. se cunoaşte momentul de începere. (iv) intervalul care se intersectează cu cele mai puţine alte intervale. Criteriul de selecţie ar putea fi: (i) cea mai mică durată. iar A este deja ordonat descrescător după acest criteriu. Observaţie. Două activităţi Ai şi Aj se consideră compatibile dacă intervalele asociate sunt disjuncte. Ai.86 - . tik ) = Ø pentru orice j≠ k. C = 50. Aplicând strategia greedy s-ar transfera primele două obiecte ducând la un profit egal cu 160. ti). (120. Ai. Profiturile relative sunt: 6. strategia greedy poate fi aplicată şi pentru varianta discretă conducând la o soluţie sub-optimală. iar resursa o sală de examen). Presupunem că activitatea se desfăşoară în intervalul [pi. Deci O are o structură greedy.t momentul de începere respectiv cel de final al activităţii Ai]algoritmul bazat pe strategia greedy poate fi descris astfel: Tehnica alegerii local optimale „greedy” . pi şi cel de finalizare ti (ti > pi). (ii) cel mai mic moment de începere. tij ) ∩ [pik.. Proprietatea de substructură optimă rezultă imediat prin reducere la absurd. (iii) cel mai mic moment de sfârşit.

ti1). în schimb prin selecţie după momentul de finalizare se obţine o soluţie. Evident ti1 ≥ t1 prin urmare înlocuind Ai1 cu A1 în O. Ai. în care activităţile sunt deja ordonate în ordinea în care vor fi efectuate... 8).. Să considerăm cazul A = ((1. 5). Durata execuţiei prelucrărilor este aceeaşi (se consideră egală cu 1).. 6))...2. S = ((2. (6. (2. (pi2. Se consideră un set de n prelucrări ce trebuie executate de către un procesor.. Prin selecţie după momentul de începere a activităţilor se obţine ((1.t ≤ Ai.87 - . Considerăm o soluţie optimă O = ((pi1. 6). ti ≤ n şi un profit. Astfel problema satisface şi proprietatea substructurii optime.n) {după timpul de finalizare..Proiectarea algoritmilor Selectieăctivitati(A.sn).. (6. Pentru rezolvarea problemei se poate aplica o tehnică de tip greedy caracterizată prin: • se sortează activităţile în ordinea descrescătoare a profitului.. (2. 8)).p THEN k ← k +1 Sk ← Ai i←i+1 RETURN S Demonstrăm că algoritmul de mai sus conduce la soluţia optimă. O soluţie constă în stabilirea unui "orar" de execuţie a prelucrărilor S = (s1. tim)). 8))..≤ tn . 5)). pi. Fiecare prelucrare i are asociat un termen final de execuţie. Dacă O este soluţia optimă a problemei iniţiale atunci O′ = ((pi2. 8). (5. O dată aleasă prima activitate. ti2). se obţine o soluţie în care există acelaşi număr de activităţi compatibile dar prima activitate este aleasă conform strategiei greedy. (6. (pim... Deci problema satisface proprietate alegerii local optimale.. si ∈ {1. tim)) este soluţie optimă a subproblemei la care se ajunge după stabilirea primei activităţi.. s2. Profitul unei prelucrări intervine în calculul profitului total doar dacă prelucrarea este executată (dacă prelucrarea nu poate fi planificată înainte de termenul final de execuţie profitul este nul). 6). Sortând A în ordinea crescătoare a duratei activităţilor se obţine ca soluţie: S = ((5. Tehnica alegerii local optimale „greedy” . 8)... (pim. • fiecare activitate se planifică într-un interval liber cât mai apropiat de termenul final de execuţie. ... Problema planificării activităţilor. Se cere să se planifice activităţile astfel încât să fie maximizat profitul total (acesta este corelat cu numărul de prelucrări planificate).t} S1 ← A1 i←2 k ←1 WHILE i ≤ n DO IF Sk.n} fiind indicele prelucrării planificate la momentul i.n) Sortare_descrescatoare(A. problema se reduce la planificarea optimă a activităţilor compatibile cu prima. ti2). După ordonarea crescătoare după timpul de final avem t1 ≤ t2 ≤.. (5. 5).

4. k fiind numărul de subseturi generat prin strategia greedy de mai sus. Elementele setului iniţial pot fi în orice ordine. Se cere să se grupeze în cât mai puţine subseturi (k) astfel încât suma elementelor din fiecare subset să nu depăşească valoarea 1. Se ordonează obiectele descrescător după profitul relativ şi se selectează în această ordine.. 0. 3).7kopt. Obiectele care nu încap în rucsac în etapa selectării lor sunt ignorate. Indicaţie. 1. 1.t WHILE Spoz ≠ 0 ∧ poz ≥ 1 DO poz ← poz -1 IF poz ≠ 0 THEN {se planifică activitatea} Spoz ← I RETURN S Se observă că dacă pentru fiecare i ∈ {1. Se consideră o variantă a problemei rucsacului în care ordonarea obiectelor după profit coincide cu ordonarea obiectelor după dimensiune (un caz particular este acela în Tehnica alegerii local optimale „greedy” . 2. 1.. Indicaţie. din elementele rămase se transferă elemente în al doilea subset etc.5. 2) iar activitatea 4 nu este planificată.2. Varianta 3.. Să se aplice strategia greedy pentru a rezolva problema discretă a rucsacului. (nu e garantată optimalitatea soluţiei însă s-a demonstrat că k < 2kopt.Proiectarea algoritmilor Planificare(A.88 - . Se parcurge setul de numere şi fiecare număr se transferă în primul subset în care "încape". Problema împachetării. Varianta 2. are proprietatea k < 1. 2..p} FOR i ← 1.n} numărul activităţilor care au termenul final cel mult i este cel mult egal cu i (card{j| tj ≤ i} ≤ i) atunci toate activităţile vor fi planificate. 1). 3. altfel vor exista activităţi ce nu pot fi planificate. 2) şi profiturile corespunzătoare (4. 1]. Varianta 1.. a2. În anexă se prezintă un program DELPHI care utilizează această variantă. Dacă însă termenele de execuţie sunt: (2. 2. Exerciţii 1. 2) şi aceleaşi profituri se obţine soluţia (3. 8. Dacă se ordonează descrescător setul iniţial şi se aplică varianta 2 se obţine o ^îmbunătăţire: k < 11/9kopt + 4. Să considerăm n = 4 activităţi având termenele finale: (2. Numărul de subseturi nevide astfel constituite k. iar kopt este numărul optim de subseturi). an cu proprietatea că ai ∈ (0.n DO Si ← 0 FOR i ← 1..n DO {termenul final de execuţie} poz ← Ai. Atunci aplicând tehnica greedy se obţine soluţia (4.n) {după timpul de profit. Ai. Se construiesc succesiv submulţimile: se transferă (în ordinea în care se află în set) în primul subset atâtea elemente cât este posibil. 4. Se consideră un set de numere a1. 3..n) Sortare_descrescatoare(A. Se iniţializează n subseturi vide. 3.

table=array [1. TObject).ListBox1. ActnList.k. TForm1 = class(TForm) Button1: TButton. procedure Button1Click(Sender: procedure Button2Click(Sender: procedure Button3Click(Sender: procedure FormActivate(Sender: procedure Button4Click(Sender: private { Private declarations } public { Public declarations } end.Add(tit). var i:word. SysUtils. fis_in:textfile. x. Button2: TButton. ListBox1: TListBox.suma. Controls. Să se elaboreze un algoritm bazat pe strategia greedy care să rezolve problema.Add('Numar elemente: '+inttostr(n)).1000] of real. Messages. TObject). var Form1: TForm1. StdActns. FileOpen1: TFileOpen. ExtActns. implementation {$R *.math.1. n.1000] of tableb=array [1.1000] of word. Classes.89 - . type tabler=array [1. Graphics. Button4: TButton. numef:string. s:string. Să se elaboreze un algoritm bazat pe strategia greedy în care selecţia se face în ordinea profiturilor absolute. form1.i:word.dfm} procedure afissirb(x:tableb. TObject).y:tabler.. ANEXA Program pentru împachetare optimă (varianta 3) unit impachetare. Se obţine soluţia optimă ? Aceeaşi problemă pentru cazul în care toate profiturile sunt identice (dar dimensiunile sunt diferite). StdCtrls. Se consideră o variantă a problemei rucsacului în care toate obiectele au aceeaşi dimensiune (dar profituri diferite).Proiectarea algoritmilor care sunt egale). Forms... Dialogs.tit:string). ActionList1: TActionList.Items. Tehnica alegerii local optimale „greedy” .Items.. TObject). begin form1.listbox1. Variants. Conduce algoritmul la soluţia optimă ? 4. a:table. interface uses Windows. Button3: TButton. TObject). Label1: TLabel.n:word.1000. real.

reset(fis_in). end.0). end. form1. closefile(fis_in).ListBox1.ListBox1.Add('Numar elemente: '+inttostr(n)).Items. afissir(x. end.Items.tit:string).Proiectarea algoritmilor s:=' '.ListBox1. end.Items. for i:=1 to n do if length(s)<65 then s:=s+floattostr(x[i])+' ' else begin form1.ListBox1.n:word. mterror.ListBox1. end Tehnica alegerii local optimale „greedy” .mterror. ordine: '+inttostr(i)+' valoare: '+floattostr(x[i]).Button1Click(Sender: TObject). begin form1.0).90 - . application. var i:word. err:=true. s:=' '+floattostr(x[i])+' '.Add(s). begin if numef<>'' then begin label1. var i:word.Visible:=true. for i:=1 to n do if length(s)<65 then s:=s+floattostr(x[i])+' ' else begin form1. for i:=1 to n do if x[i] > 1 then begin messagedlg('Element mai mare ca 1: nr.Caption:='Nume fisier: '+numef.listbox1. procedure TForm1.Clear.[mbok]. end.Items.x[i]). err:boolean.Add(s).n. if err then begin messagedlg('Corectati datele de intrare!'.[mbok]. end.Items. s:string. form1. readln(fis_in. listbox1.'Sir initial:').Add(s).n).Visible:=true. for i:=1 to n do read(fis_in.Add(s). procedure afissir(x:tabler.Terminate. s:=' '+floattostr(x[i])+' '. listbox1.Add(tit).Items. s:=' '. err:=false. label1. form1.

Button3Click(Sender: TObject). x[i+1]:=man. end. procedure TForm1.mterror.p:word. numef:=''. var j.FormActivate(Sender: TObject). procedure TForm1.Clear. procedure TForm1. begin randomize. var x:tabler).Proiectarea algoritmilor else messagedlg('Alegeti fisierul cu date !'. winexec(pchar('notepad '+numef).Button2Click(Sender: TObject).InitialDir:=getcurrentdir.Visible:=true. var test:boolean. begin fileopen1. n:=0.[mbok].FileName.Dialog.100. closefile(fis_in).[mbok]. begin if n=0 then messagedlg('Stabiliti un sir de intrare !'. for i:=1 to n-1 do if x[i]<x[i+1] then begin man:=x[i].0) else begin msum:=0. until test. end. test:=false. x[i]:=x[i+1]. man:real. begin numef:=fileopen1.'Sir initial:'). for i:=1 to 100 do x[i]:=trunc(random*100)/100.sw_show). end. var i:word. if fileexists(numef) then reset(fis_in) else rewrite(fis_in). n:=100. Tehnica alegerii local optimale „greedy” . procedure sortsir(n:word.Dialog. end.0).91 - .Button4Click(Sender: TObject). end.mterror. assignfile(fis_in. i:word. listbox1.numef). begin repeat test:=true. listbox1. procedure TForm1. afissir(x. msum:real. end.

end. listbox1.j]:=0. end. for i:=1 to k do begin p:=1. while a[j. end.Add(' ').p]<>0 do begin y[p]:=a[i. for i:=2 to n do begin j:=1.Add('Numar pachete: '+inttostr(k)+' pachete (teoretic): '+inttostr(trunc(msum)+1)). while a[i.p]:=x[i]. p:=1.00000001 do j:=j+1.Items. end.p-1. end. while (suma[j]+x[i])>1. inc(p). a[j. listbox1. end.92 - . sortsir(n.Items. a[1. afissir(y. for i:=1 to n do begin for j:=1 to n do a[i. Numar minim de Suma: Tehnica alegerii local optimale „greedy” .p]. suma[i]:=0. suma[1]:=x[1].1]:=x[1].'Pachet: '+inttostr(i)+' '+floattostr(suma[i])). end.x).p]<>0 do p:=p+1. k:=1. suma[j]:=suma[j]+x[i]. if j>k then k:=j.Proiectarea algoritmilor for i:=1 to n do msum:=msum+x[i].

• Proprietatea de suprapunere a problemelor. Această tehnică se bazează pe descompunerea unei probleme în subprobleme şi este adecvată rezolvării problemelor (în particular celor de optimizare) care au următoarele proprietăţi: • Proprietatea de substructură optimă. În funcţie de problemă. (c) Calculul valorii asociate soluţiei optime dezvoltând relaţia de recurenţă într-o manieră ascendentă şi reţinând valorile calculate asociate subproblemelor într-o structură tabelară. Ideea descompunerii problemei în subprobleme este folosită şi în metoda divizării însă în acel caz era important ca subproblemele să fie independente. Această proprietatea este specifică şi problemelor ce pot fi rezolvate prin tehnica greedy.93 - . La construirea tabelelor pentru completarea unui element se folosesc elemente completate anterior (construirea se realizează în manieră dinamică). 9. Aceasta descrie legătura dintre valoarea criteriului de optim corespunzător problemei şi cele corespunzătoare subproblemelor. (b) Stabilirea unei relaţii de recurentă referitoare la criteriul de optimizat sau la valoarea ce trebuie calculată. Pentru a verifica dacă o problemă posedă această proprietate se poate folosi metoda reducerii la absurd. Introducere Programarea dinamică (introdusă in 1950 de R.1. Pentru ca programarea dinamică să fie eficientă este necesar ca numărul subproblemelor ce trebuie efectiv rezolvate în scopul obţinerii soluţiei problemei iniţiale să fie relativ mic (polinomial în raport cu dimensiunea problemei). Orice soluţie optimă este constituită din soluţii optime ale subproblemelor. Principiul tehnicii şi etapele aplicării La aplicarea metodei se parcurg următoarele etape: (a) Analiza structurii unei soluţii optime şi a proprietăţilor acesteia prin punerea în evidentă a relaţiei existente între soluţia problemei şi soluţiile subproblemelor (se verifică dacă problema posedă proprietatea de substructură optimă).2. Aceasta înseamnă că în procesul de descompunere a problemei se ajunge de mai multe ori la aceeaşi subproblemă care însă va fi rezolvată o singură dată iar soluţia ei va fi reţinută într-un tabel. Bellman pentru rezolvarea problemelor de optimizare) este o metodă bazată pe construirea şi utilizarea unor tabele cu informaţii.Proiectarea algoritmilor 9. în Tehnica programării dinamice . TEHNICA PROGRAMĂRII DINAMICE 9.

Dezvoltarea ascendentă şi descendentă a unei relaţii de recurenţă. fm.2 (complexitate liniară). n ≥ 3). Cum fm 1+ 5 rezultă că fib_rec are complexitate exponenţială. (d) Construirea unei soluţii optime folosind informaţiile determinate şi reţinute la etapa anterioară.2) + 1. O abordare descendentă conduce la algoritmul recursiv: Fib_rec(m) IF (m = 1) OR (m = 2) THEN RETURN 1 ELSE RETURN fib_rec(m-1)+ fib_rec(m-2) Numărul de adunări efectuate pentru a determina pe fm. f2= 1.. În acest caz algoritmul poate fi descris prin: ∈ Θ(Φm) cu Φ = Fib_asc(m) f1 ← 1 f2 ← 1 FOR i ← 3... f2. pentru m ≥ 5. Suprapunerea problemelor face ca obţinerea valorii prin dezvoltarea relaţiei de recurentă să nu fie eficientă dacă este abordată în manieră descendentă (" top-down") prin implementarea recursivă a relaţiei.. 2 Considerăm acum varianta generării lui fm în manieră ascendentă: se calculează şi se reţin valorile lui f1. Algoritmul poate fi uşor transformat astfel încât să nu folosească decât trei variabile pentru reţinerea elementelor şirului dar să rămână cu complexitate liniară: Tehnica programării dinamice .Proiectarea algoritmilor această etapă se pot retine şi alte informaţii care vor fi utilizate în momentul construirii soluţiei. Deşi se bazează pe descompunerea unei probleme în subprobleme la fel ca tehnica divizării specificul programării dinamice este că subproblemele nu sunt independente (ci se suprapun). Aceasta deoarece o aceeaşi valoare poate fi utilizată de mai multe ori şi de fiecare dată când este utilizată este recalculată. T(m) verifică relatiile: T(1) = T(2) = 0. Această variantă de implementare introduce utilizarea unui spaţiu auxiliar de memorie de dimensiune m. În schimb tehnica divizării conduce la algoritmi eficienţi doar dacă subproblemele sunt independente. T(m) = T(m -1) +T(m . m DO fi ← fi-1 + fi-2 RETURN fm numărul de adunări efectuate fiind de această dată T(m) = m . Să considerăm problema determinării celui de-al m-lea element din şirul lui Fibonacci (f1=1. fn = fn-1 + fn-2. Prin urmare T(m) ≥ fm-1.94 - .

Cn .k)+ comb_rec(n-1. m DO f2 ← f1 + f2 f1 ← f2 . (n ≥ k ) .k}. În abordarea ascendentă ideea este să se reţină toate valorile Ci j calculate pentru 0 ≤ j ≤ i ≤ n.k.k) ≥ 2min{n-k.95 - . m DO f3 ← f2 + f2 f1 ← f2 f2 ← f3 RETURN f3 Numărul variabilelor de lucru poate fi redus chiar la două în modul următor: Fib_asc3(m) f1 ← 1 f2 ← 1 FOR i ← 3.k) IF (k=0) OR (n=k) THEN RETURN 1 ELSE RETURN comb_rec(n-1. Aceasta s-ar putea realiza prin completarea elementelor aij din zona inferior triunghiulară a unei matrice n x n. Algoritmul poate fi descris prin: Tehnica programării dinamice . k}.k-1) are complexitate exponenţială întrucât T(n. pornind de la relaţia de recurenţă: ⎪1 k ⎧ Cn = ⎨ k k −1 ⎪C n −1 + C n −1 ⎩ dacă k = 0 sau n = k altfel Algoritmul in varianta recursivă: comb_rec(n.f1 RETURN f2 k Un exemplu similar este cel al calculului combinărilor. Aceasta se poate justifica utilizând arborele de apel şi observând că cea mai scurtă ramură din arbore are lungimea min{n . Dacă n = k zona triunghiulară astfel completată este cunoscută sub denumirea de triunghiul lui Pascal. Aceasta se poate demonstra dezvoltând arborele de apel şi estimând numărul de noduri al arborelui trunchiat până la nivelul corespunzător celei mai scurte ramuri.Proiectarea algoritmilor Fib_asc2(m) f1 ← 1 f2 ← 1 FOR i ← 3. De fapt este suficient să se completeze până la coloana k.

k) FOR i ← 0. i=1.3) există patru subşiruri crescătoare de lungime maximă (2): (2. Prin reducere la absurd se poate arăta că aj1 < aj2 <. a) Caracterizarea soluţiei optime.< ajk...2. Prin urmare problema are proprietatea de substructură optimă şi lungimea unui subşir crescător care se termină în ai poate fi exprimată în funcţie de lungimea subşirurilor crescătoare care se termină cu elemente ap ce satisfac ap < ai. aj2.3...2. Fie (Bi). T(n.. a2.2.k} DO IF (i = j) OR (j = 0) THEN aij ← 1 ELSE aij ← ai-1j + ai-1j-1 RETURN ank Numărul de adunări efectuate. ajk) cu 1 ≤ jl < j2 < . a2..4). Considerăm că ajk = ai iar ajk-1 = ap (evident p < i. ap) care au proprietatea că ultimul element este chiar ap.8. (1.1.3).. aj1 < aj2 <.. an şi se caută un subşir (aj1. (2.10) există două subşiruri strict crescătoare de lungime 5: (2.< ajk-1 este cel mai lung dintre subşirurile crescătoare ale şirului parţial (a1...10)..Proiectarea algoritmilor comb_asc(n.96 - . (1. Problema determinării celui mai lung şir crescător. Se consideră un şir de valori reale a1.5.3.. min{i.4). Pe de altă parte nu toate subşirurile de aceeaşi lungime se termină cu acelaşi element. B i = k +1 j =1 ∑ n ∑ 1 = ∑ (i − 1) + i =1 k k i = k +1 ∑k = n k ⋅ (k − 1) + k ⋅ (n − k ) 2 Tehnica programării dinamice ..4) tabloul lungimilor subşirurilor optime care se termină în fiecare element al lui a este: B = (1.2. k) satisface T ( n. şi astfel încât k să fie cât mai mare.. Un astfel de subşir nu este neapărat unic...6... < jk ≤ n..6.8... Fie aj1 < aj2 <.. întrucât pentru completarea liniei i se folosesc doar valorile din linia i – 1.3).10) şi (1.6.1. Ţinând cont de proprietăţile soluţiei optime se poate stabili o relaţie de recurenţă pentru Bi: i =1 ⎧1 Bi = ⎨ ⎩1 + max{B j | 1 ≤ j < i şi a j < ai } i > 1 Dacă mulţimea MI = {Bi 1≤ j < i şi aj < ai} este vidă atunci max Mi = 0.6.n DO FOR j ← 0.. De exemplu pentru şirul iniţial a = (2. Se observă că zona auxiliară utilizată poate fi redusă.. k ) = ∑ ∑ 1 + i =1 j =1 k i −1 deci T(n.8.3.. a2.4...3. Exemplu. an) care are pe ai ca ultim element (spunem că subşirul se termină în ai).1. De exemplu pentru şirul (2.5.< ajk-1 < ajk un subşir de lungime maximă.3.3). b) Stabilirea unei relaţii de recurenţă între lungimile subşirurilor..1. Cea mai mare valoare din B indică numărul de elemente din cel mai lung subşir crescător. k) ∈ Θ(nk).n un tablou ce conţine pe poziţia i numărul de elemente al celui mai lung subşir strict crescător al lui (a1..8. De exemplu în şirul (2..4..

am.. din şirul iniţial cu care se termină subşirul. B completare(a. la fiecare etapă..2.. d) Construirea unei soluţii optime. relaţiei de recurenţă în manieră ascendentă. un element din şir mai mic decât ultimul completat în subşir şi căruia îi corespunde în B o valoare cu 1 mai mică decât cea curentă. Algoritmul poate fi descris prin: construire(a. Pornind de la acest element subşirul se construieşte în ordinea inversă a elementelor sale căutând.B.n DO IF Bimax < Bi THEN imax ← i m ← imax {construirea unei soluţii} k ← Bm xk ← am {ultimul element al subşirului} WHILE Bm > 1 DO i ← m-1 WHILE (ai ≥ am) OR (Bi ≠ Bm -1) DO i←i–1 m←i k←k–1 xk ← am RETURN x Tehnica programării dinamice . i=1.97 - .n.n DO max ← 0 FOR j ← 1.Proiectarea algoritmilor c) Dezvoltarea. Se completează un tablou cu elementele lui (Bi). Aceasta indică numărul de elemente ale celui mai lung subşir crescător iar poziţia pe care se află indică elementul. Se determină cea mai mare valoare din B.n) {detrminarea valorii şi poziţiei maxumului în B} imax ← 1 FOR i ← 2. i-1 DO IF (aj < ai) AND (max < Bj) THEN max ← Bj Bi ← max + 1 RETURN B B Luând in considerare doar comparaţia dintre două elemente ale şirului (aj < ai) costul algoritmului este T ( n) = i = 2 j =1 ∑ ∑1 = n i −1 i=2 ∑ (i − 1) = n n ⋅ (n − 1) 2 deci completarea tabelului B este de complexitate Θ(n2).n) B1 ← 1 FOR i ← 2.

p2.. .5) şi (5. adică matricea Ai are pi-l linii şi pi coloane.. (20.3... Astfel dacă p < q va fi selectat q. p1. .Proiectarea algoritmilor Dacă după completarea elementului am în subşir există două subşiruri din zona a1.i) parantezări ale produsului Ai+1 . În acest caz există două modalităţi de plasare a parantezelor: 1. Pentru n mare numărul de parantezări (variante de plasare a parantezelor) poate fi foarte mare astfel că este exclusă generarea tuturor parantezărilor posibile şi alegerea celei mai bune. .1. A1· A2· A3= (A1· A2)· A3.3. de lungime maximă egală cu Bm . ..6.. .. Continuând procesul se selectează în continuare elementele 3 şi 1 obţinându-se subşirul crescător (1. Pentru calculul produsului A1· A2···· An notând cu K(n) numărul de parantezări posibile obţinem: ⎧1 ⎪ K ( n ) = ⎨ n −1 ⎪ ∑ ( K (i ) ⋅ K ( n − i ) ) ⎩ i =1 n =1 n >1 întrucât ultimul nivel de paranteze poate fi aplicat în oricare dintre poziţiile i ∈ {1.. A2..20).. An. Aplicaţii Înmulţirea optimală a unui şir de matrice. chiar dacă sunt două cicluri WHILE suprapuse. Fie A1..3.. Pentru a calcula produsul A = A1· A2···· An trebuie stabilit un mod de grupare a factorilor astfel încât să se pună în evidentă ordinea în care vor fi efectuate înmulţirile. A2. Să presupunem că aceste dimensiuni sunt: (p0..10).8) de lungime 4. 2. Se poate demonstra prin inducţie matematică că Tehnica programării dinamice . adică mai mare.98 - . Considerăm că produsul a două matrice se efectuează după metoda clasică astfel că la produsul Ai · Ai+1 se efectuează pi-l pi pi+l înmulţiri scalare.n . la fiecare etapă înmulţindu-se două matrice. Cum şi determinarea maximului lui B are acelaşi ordin de complexitate rezultă că algoritmul de construire are complexitate liniară.5. A1· A2· A3= A1·( A2· A3). 2.. B 9.8.. am-1.6. Întrucât în ciclul de construire căutarea continuă de la poziţia noului element selectat. În acest caz se efectuează 2·20·5 + 2·5·10 = 300 înmulţiri scalare. În acest caz se efectuează 20·5·10 + 2·20·10 = 1400 înmulţiri scalare. Aplicând algoritmul de construire a şirului (2.1} şi fiecare dintre cele K(i) parantezări ale produsului A1· A2 . şi A3 având dimensiunile (2.pn). .1: unul care se termină in ap şi unul care se termină in aq (astfel încât ap < am şi aq < am) algoritmul va selecta ca element pentru subşir pe cel cu indicele mai apropiat de m.4) se va porni cu m = 6 (Bm = 4) ultimul element din subşir fiind astfel 8. Ai poate fi combinată cu fiecare dintre cele K(n . a2. Modul de grupare a factorilor (plasarea parantezelor pentru a indica ordinea de efectuare a înmulţirilor) nu influenţează rezultatul final (înmulţirea este asociativă) însă poate influenta numărul de operaţii efectuate. . ordinul de complexitate este O(n). Să considerăm cazul a trei matrice A1. Cum B5 = 3 şi 6 < 8 penultimul element va fi 6. An un şir de matrice având dimensiuni compatibile pentru a putea calcula produsul: A1· A2···· An.

.j. n-l DO j ← i+l cij ← cii + ci+1.k·Ak+1.n).. Din acest motiv elementele se completează în ordinea crescătoare a diferenţei j . j-1 DO cost ← cik + ck+1. Construirea în manieră ascendentă se bazează pe ideea completării matricei astfel încât în momentul calculului lui cij toate elementele cik şi ck+l.n.n) FOR i ← 1.. k şi n.j-1} să fie deja completate.. Valorile cij au sens doar pentru i ≤ j iar relaţia de recurenţă dedusă din proprietatea de substructură optimă este: i= j ⎧0 cij = ⎨ i< j ⎩min i ≤ k < j (cik + ck +1. completare(p.j + pi-1pipj sij ← i FOR k ← i+1.j pentru k ∈ {i..d. Construirea în manieră recursivă a matricei este ineficientă. a) Pentru a specifica produsele parţiale introducem notaţia Ai..a...j+ pi-1pipj IF cost < cij THEN cij ← cost sij ← k RETURN c. adică ultima înmulţire efectuată este: A1. b) Fie cij numărul de înmulţiri scalare efectuate pentru calculul lui Ai. apoi se completează elementele aflate imediat deasupra diagonalei principale (j = i + 1) ş.n DO {l = j-i} FOR i ← 1.i: prima dată se completează elementele diagonalei principale (i = j).. .j = Ai· Ai+1···· Aj. j + pi −1 ⋅ pk ⋅ p j ) K ( n) = n 1 C2⋅−n −1) ( Relaţia se bazează pe faptul că dintre toate parantezările posibile ale lui Ai.. Atunci parantezările asociate lui A1. Aplicăm pentru rezolvarea problemei programarea dinamică.k şi Ak+1.m. Fie o soluţie optimă caracterizată prin faptul că parantezele cele mai exterioare sunt plasate pe poziţiile 1.j se alege cea mai bună (de cost minim).99 - . i + 1.Proiectarea algoritmilor ⎛ 4n −1 ⎞ ⎟ şi K (n) ∈ Ω⎜ 3 ⎟ ⎜ n ⎝ (n − 1)2 ⎠ Problema înmulţirii optimale a unui şir de matrice (un caz particular al problemelor de planificare optimală a prelucrărilor) constă în a determina parantezarea (ordinea de efectuare a înmulţirilor) care conduce la un număr minim de înnulţiri scalare..n DO cii ← 0 FOR l ← 2. s Tehnica programării dinamice .n trebuie să fie şi ele optime (în caz contrar ar există o parantezare mai bună pentru A1. c) Valorile cij pot fi reţinute în porţiunea superior triunghiulară a unei matrice. .

dik)) care să nu depăşească capacitatea rucsacului ( ∑ d ij ≤ C ) şi să asigure un profit maxim ( ∑ pij j =1 j =1 k k este maximă).... Se pune problema selectării unui subset de obiecte. sij) Y ← Produs_optimal( sij+1. Aceste poziţii sunt utile la construirea soluţiei..j.k ·Ak+1... (iii) Determinarea ordinii în care se efectuează înmulţirile: Parantezare(i.j) Problema rucsacului . Pentru exemplul celor trei matricei cu dimensiunile (2. Considerăm varianta discretă a problemei rucsacului... (iii) modul de descompunere a produsului (parantezare)... Se consideră că dimensiunea fiecărui obiect este mai mică decât cea Tehnica programării dinamice ...Proiectarea algoritmilor O dată cu completarea matricei de costuri se reţine şi poziţia în care se descompune un produs în doi factori: sij = k indică faptul că produsul Ai. iar capacitatea maximă a rucsacului este C. di2). (pik. Presupunem că obiectele se caracterizează prin dimensiunile (dl. sij) WRITE sij Parantezare(sij+1.5) şi (5. (i) Numărul minim de înmulţiri este chiar c1n. Cum pentru determinarea valorii fiecăruia dintre cele n(n-1)/2 elemente este necesară determinarea unui minim dintr-un tablou cu cel mult n elemente rezultă că ordinul de complexitate al algoritmului de completare este O(n3).j) IF i < j THEN Parantezare(i. di1)...j) R ← produs(X.100 - . (ii) rezultatul înmulţirii matricelor...dn) şi profiturile (valorile): (p1.10) se obţin matricele: ⎡ 0 200 300 ⎤ ⎡ 0 1 1⎤ ⎢− 0 400⎥ s = ⎢− 0 2⎥ c=⎢ ⎥ ⎥ ⎢ ⎢− − ⎢− − 0⎥ 0 ⎥ ⎦ ⎦ ⎣ ⎣ d) În funcţie de cerinţele problemei se poate determina: (i) numărul minim de operaţii.Y) {produs matrici} RETURN R În algoritmul de mai sus s-a presupus că pot fi accesate matricele din şir precum şi elementele matricei s..20). (pi2. (20.j se descompune în Ai.j) IF i=j THEN RETURN Ai ELSE X ← Produs_optimal(i. p2.pn). ((pi1.. d2.varianta 0-1. (ii) Calculul produsului poate fi efectuat în manieră recursivă: Produs_optimal(i.

n. Problema selectării dintre cele n obiecte poate fi redusă la problema rucsacului corespunzătoare primelor n ... Astfel valoarea este identică cu cea corespunzătoare subproblemei primelor i .2.. Din acest motiv se analizează ambele valori şi se alege cea maximă.n.. c) Dezvoltarea relaţiei de recurenţă.1. 0) = 0. i=1.j..... Dacă C şi di. j = 1. Dacă soluţia subproblemei nu ar fi optimă atunci ar putea fi înlocuită cu una mai bună ceea ce ar conduce la o soluţie mai bună a problemei iniţiale. Vi – 1. C Vij = ⎨ dacă j − d i ≥ 0 ⎪max pi + Vi −1.C iar V(i.Proiectarea algoritmilor maximă (di ≤ C).2. j −di .. Cele două cazuri din relaţia de recurenţă provin din faptul că o soluţie optimă a problemei asociate primelor i obiecte şi capacităţii j poate să nu conţină sau să conţină obiectul i.. În al doilea caz obiectul i ar putea fi selectat însă el va fi selectat doar dacă conduce la o valoare totală mai mare decât dacă nu ar fi fost selectat. i=1.1 obiecte şi capacităţii j. Algoritmul de construire a tabelului de valori poate fi descris astfel: Tehnica programării dinamice . b)Stabilirea unei relaţii de recurenţă. j i = 1.101 - . O soluţie optimă a problemei iniţiale va fi constituită dintr-o soluţie optimă a subproblemei corespunzătoare primelor n .n şi C sunt valori naturale. Vi −1.2. j ⎩ cu V(0. În varianta 0-1 a problemei un obiect poate fi selectat doar în întregime.j) = 0 pentru j = 0. În acest caz tehnica greedy nu garantează obţinerea soluţiei optimale.1 obiecte şi a capacităţii maxime 1 ≤ Cn-l ≤ C.1 obiecte.. pentru i = 1..di { } (capacitatea rămasă disponibilă după selectarea obiectului i).n sunt valori întregi atunci valorile lui Vij pot fi reţinute într-o matrice cu n + 1 linii şi C + 1 coloane. a)Analiza structurii unei soluţii optime. În primul caz dimensiunea obiectului i este prea mare pentru ca acesta să poată fi selectat.. Pentru a uşura aplicarea tehnicii programării dinamice vom considera că di. VnC reprezintă valoarea maximă a unui set de obiecte a căror dimensiuni însumate nu depăşeşte pe C adică valoarea asociată soluţiei optime a problemei.1 obiecte la care se adaugă eventual al n-lea obiect (dacă Cn-1 + dn ≤ C). Cum soluţia optimă a problemei corespunzătoare lui i poate fi exprimată prin soluţia optimă a problemei corespunzătoare lui i . Valoarea corespunzătoare cazului în care obiectul este selectat este obţinută adăugând valoarea celui de-al i-lea obiect (pi) la valoarea soluţiei problemei corespunzătoare celor i . Fie Vij valoarea obiectelor selectate în soluţia optimă a problemei corespunzătoare primelor i obiecte şi capacităţii j.1 rezultă următoarea relaţie de recurenţă pentru Vij: dacă j − d i < 0 ⎧ ⎪Vi −1.

j −di { } RETURN V Să considerăm cazul în care n = 5.13. o3.2.23 = 15 reprezintă chiar valoarea obiectului o4).1. o4} cu dimensiunea totală 5 şi valoarea totală 38. Aceasta înseamnă că obiectul o5 nu este selectat.j ELSE Vij ← max Vi −1. j .o2} şi capacităţii 4 – d3 = 2. dimensiunile obiectelor sunt (2. Aceasta reduce problema la selecţia dintre obiectele {o1.d. Cum V22 = V12 şi V12 ≠ 0 rezultă că o2 nu este selectat în schimb este selectat o1.Proiectarea algoritmilor Tabel_valori (p.C.C DO V0j ← 0 FOR i ← 1.102 - . se observă că V34 ≠ V24 adică obiectul o3 este selectat.C DO IF (j < di) THEN Vij ← Vi-1.15.4. Valoarea unei soluţii optime a acestei subprobleme este V22 = 10. C = 5. În acest caz matricea de valori este cu 6 linii şi 6 coloane (indiciate de la 0 la 5) şi conţine elementele: ⎡0 0 0 0 0 0 ⎤ ⎢0 0 10 10 10 10 ⎥ ⎥ ⎢ ⎢0 0 10 10 20 20⎥ V =⎢ ⎥ ⎢0 0 13 13 23 23⎥ ⎢0 15 15 28 28 38⎥ ⎢ ⎥ ⎢0 15 15 28 38 38⎥ ⎣ ⎦ Pornind de la elementul V55 se poate construi soluţia astfel.18).d4 = 4. o2.n DO Vi0 ← 0 FOR j ← 1.n) FOR i ← 0. pi + Vi −1. o3} pentru un rucsac de capacitate 5 . Se observă că V55 = V45. În schimb V45 ≠ V35 adică obiectul o4 este selectat. În continuare. Algoritmul poate fi descris prin: Tehnica programării dinamice . Pentru construirea soluţiei se analizează tabelul de valori construit la etapa anterioară iniţiind parcurgerea din VnC după strategia descrisă în exemplul de mai sus. d) Construirea soluţiei. Astfel soluţia problemei iniţiale este {o1. Valoarea unei soluţii optime a acestei subprobleme este V34 = 23 (se observă că diferenţa V55 – V34 = 38 . Astfel problema se reduce la subproblema corespunzătoare setului {o1.3) iar valorile asociate (10.20.n DO FOR j ← 1.

V52. rucsac} WHILE Vij = Vi-1.di i ← i-1 RETURN s Tehnica funcţiilor de memorie sau a memoizării. Dacă se foloseşte abordarea top-down atunci se vor calcula doar valorile asociate subproblemelor care sunt necesare pentru a obţine valoarea corespunzătoare problemei iniţiale.C.103 - . în felul acesta se va putea verifica dacă o poziţie din tabel a fost calculată deja sau nu. V53 şi V54 din tabelul construit pentru problema rucsacului).Proiectarea algoritmilor Construire_solutie(V.j AND i ≥ 1 DO i ← i-1 k ← k+1 sk ← i j ← j . În aplicaţii e posibil ca anumite valori din tabel să nu fie necesare nici în calculul celorlalte valori şi nici în construcţia soluţiei (de exemplu elementele V51. • calculul valorii corespunzătoare soluţiei în manieră recursivă (cu reţinerea valorilor calculate). În felul acesta dacă o valoare deja calculată este necesară din nou ea nu va fi recalculată ci se va folosi valoarea reţinută anterior. Principalul dezavantaj al abordării ascendente este faptul că se bazează pe completarea unui întreg tabel de valori. Dar dacă o subproblemă este întâlnită de mai multe ori atunci ea este rezolvată de fiecare dată. O soluţie de compromis care îmbină avantajele abordării ascendente cu a celei descendente este de a dezvolta relaţia de recurentă într-o manieră recursivă reţinând fiecare dintre valorile calculate. Această variantă hibridă este cunoscută ca tehnica funcţiilor de memorie sau tehnica memoizării.d.n) i←n {indici matrice V} j←C k←0 {contor soluţie} WHILE j > 0 {cât timp nu se depăşeşte cap. Aplicată la construirea tabelului de valori pentru problema rucsacului această tehnică conduce la: Tehnica programării dinamice . aceasta presupune că tabelul de valori este o structură globală ce poate fi accesată la fiecare apel recursiv. Aplicarea ei în practică constă în: • iniţializarea tabelului cu o valoare virtuală ce va fi diferită de valorile ce se vor obţine din calcule.

.. Rn = R*... k} cu proprietăţile: (i1. Pentru a elabora algoritmul de construire a lui R* considerăm relaţiile binare pe {1. . . C DO V0j ← 0 FOR i ← 0. . . ... . (im-1. n} x {1. 2... Considerăm o relaţie binară R ⊂ {1. .im) ∈ R iar i=i1 şi j=ik atunci (i. Nu doar problemele de optimizare pot fi rezolvate cu tehnica programării dinamice ci şi alte probleme a căror soluţie poate fi exprimată în funcţie de soluţiile unor subprobleme. .n} x {1.j) IF i = 0 OR j = 0 THEN RETURN 0 IF Vij < 0 THEN IF j < di THEN val ← calcul_valori(i-1.n}. C DO Vij ← -1 FOR j ← 0. .j) ∈ Rk-1 sau (i. j ) ∉ R ⎩0 Relaţiile de recurenţă pentru construirea matricelor asociate relaţiilor binare R0...n DO FOR j ← 0.j) ∈ Rk. n} cu proprietăţile: (i1.. ∈ {1. R1. i=0. Apelul calcul_valori(n. .j) ∈ Rk-1.. .n.C.. j=0. Problema închiderii tranzitive... pi+ calcul_valori(i-1.... ..dn şi Vij. Pentru a construi R* se consideră următorul set de relaţii binare R0 = R... .i3) ∈ R. ..j-di)} Vij ← val RETURN Vij Algoritmul calcul_valori are acces la tablourile d1.. (i2.j)..C) FOR i ← 1..j) ∈ R*. ..n} reprezentate prin matrice ale căror elemente sunt definite astfel: dacă (i. Relaţiile pot fi descrise prin recurenţe astfel: (i..j) ELSE val ← max{ calcul_valori(i-1... j ∈ {1.. (im-1.j) ∈ Rk dacă (i. .. .i2) ∈ R. definite astfel: dacă pentru i. .k) ∈ Rk-1 şi (k... .Proiectarea algoritmilor Initializare(n...C) se plasează după iniţializarea tabloului. . ∈ {1. n DO Vi0 ← 0 RETURN V şi calcul_valori(i. . j ∈ {1. n} există il.. d2. . Închiderea sa tranzitivă este o relaţie binară R* ⊂ {1. (i2. i2) ∈ R.n} având proprietatea: dacă pentru i...im.i3) ∈ R. . i2.. j ) ∈ R ⎧1 rij = ⎨ dacă (i.. im...104 - {Valoare virtuală – 1} . . .. Tehnica programării dinamice . Rl. n} există il.im) ∈ R iar i = il şi j = im atunci (i.

an). 3. Aplicaţi tehnica memoizării pentru şirul lui Fibonacci şi studiaţi complexitatea algoritmului obţinut.n DO FOR j ← 1. Se consideră un set de valori naturale nenule A = (al. Justificaţi. Exerciţii 1. Aplicaţi tehnica memoizării pentru calculul costului minim in cazul înmulţirii unui şir de matrice.…. Rn sunt: k k ⎧1 dacă rijk −1 = 1 ∨ rik −1 = 1 ∧ rkj −1 = 1 ⎪ rijk = ⎨ k=1.105 - .n DO IF R1ij =1 OR (R1ik=1 AND R1kj=1) THEN R2ij ←1 ELSE R2ij ←0 RETURN R2 Algoritmul pentru determinarea inchiderii tranzitive este cunoscut §i sub numele de algoritmul lui Warshall.n DO R1 ← R2 FOR i ← 1. 4.n ⎪0 altfel ⎩ 0 cu rij = rij .2. 9.. a2. Indicaţie. Obiectele selectate vor reprezenta subsetul B. iar cele neselectate subsetul Tehnica programării dinamice . utilizând doar două matrice auxiliare astfel: ( ) inchidere_tranzitiva(R. .Proiectarea algoritmilor . Propuneţi un algoritm de calculare în manieră ascendentă a lui Cn pe baza dacă k = 0 sau n = k ⎧1 relaţiei de recurenţă C nk = ⎨ k folosind cât mai k −1 altfel ⎩C n −1 + C n −1 puţin spaţiu auxiliar. Se reduce la un caz particular al problemei rucsacului: selecţia unor obiecte care să maximizeze gradul de umplere al unui rucsac având capacitatea egală cu ⎡1 n ⎤ S = ⎢ ⋅ ∑ ai ⎥ (criteriul de optim nu este legat de valorile ci de dimensiunile ⎣ 2 i =1 ⎦ obiectelor).. că algoritmul comb_rec are complexitate exponenţială.n) R2 ←R FOR k ← 1. folosind arborele de apel. Folosind aceste relaţii de recurenţă se poate construi matricea asociată relaţiei binare Rn. Să se descompună A în două subseturi B şi C astfel încât sumele elementelor din cele două subseturi să fie cât mai apropiate.. 5. k 2.4.

ck) cu proprietatea că există i1 < i2 <…. j ) = ⎨T (i − 1. Indicaţie.bj) şi se foloseşte relaţia de recurenţă: dacă i = 0 sau j = 0 ⎧0 ⎪ T (i. c2. Să se determine cel mai lung subşir comun al celor două şiruri. b2.bm) două şiruri de valori. j ). j − 1)} în celelalte cazuri ⎩ Tehnica programării dinamice .j) numărul de elemente al celui mai lung subşir comun al lui (al.106 - .< jk astfel încât bq = aiq = bjq. 6.…. Minimizând diferenţa dintre suma elementelor din B şi valoarea S se minimizează de fapt modulul diferenţei dintre sumele elementelor celor două subseturi. j − 1) + 1 dacă ai = bi ⎪max{T (i − 1.am) şi B = (bl.…. a2.….….Proiectarea algoritmilor C.< ik şi j1 < j2 <…. a2. b2.…. Fie A = (al. T (i. Se notează cu T(i.ai) şi (bl. adică (cl.

. Introducere Tehnica căutării cu revenire (numită şi tehnica "backtracking") se utilizează pentru rezolvarea problemelor printr-o căutare controlată a spaţiului soluţiilor. n} (Al = A2 = .x An) • La completarea componentei k se verifică dacă soluţia parţială (s1. • Procesul de căutare şi revenire este continuat fie până când este găsită o soluţie (în cazul în care este suficientă determinarea uneia) sau până când au fost testate Tehnica căutării cu revenire .. 2. De exemplu. n} x.) verifică condiţiile induse de restricţiile problemei (acestea sunt numite condiţii de continuare)... problema determinării tuturor permutărilor de ordin n poate fi reformulată ca problema determinării submulţimii produsului cartezian {1. 2. O soluţie este de forma s = (s1. Majoritatea problemelor ce pot fi rezolvate prin "backtracking" pot fi reduse la determinarea unei submulţimi a unui produs cartezian de forma A1 x A2 x.......... O soluţie parţială care satisface condiţiile de continuare este denumită soluţie parţială validă (sau viabilă) întrucât poate conduce la o soluţie a problemei. = An = {1.sn) cu sk ∈ Ak = a1k ... TEHNICA CĂUTĂRII CU REVENIRE 10. amk mk = cardAk.backtracking .a. 2....... k k s2.sk...m.. pentru orice i ≠ j).1. Fiecare element al submulţimii poate fi văzut ca o soluţie (metoda fiind astfel adecvată în special în situaţiile în care se doreşte determinarea tuturor soluţiilor unei probleme şi nu numai a unei dintre ele).... În ultimă instanţă este o îmbunătăţire a metodei căutării exhaustive (metoda forţei brute) care permite reducerea numărului de soluţii potenţiale analizate........ n}) în care elementele au componentele distincte (restricţiile problemei sunt: si ≠ sj.2.. Specificul metodei constă în maniera de parcurgere a spaţiului soluţiilor: • Soluţiile sunt construite succesiv. la fiecare etapă fiind completată câte o componentă (similar cu tehnica greedy însă ulterior se poate reveni asupra alegerii unei componente) • Alegerea unei valori pentru o componentă se face într-o anumită ordine (aceasta presupune că pe mulţimile Ak există o relaţie de ordine şi se realizează o parcurgere sistematică a spaţiului A1 x A2 x.... a2 . • Dacă au fost încercate toate valorile corespunzătoare componentei k şi încă nu a fost găsită o soluţie sau dacă se doreşte determinarea unei noi soluţii atunci se revine la componenta anterioară (k-1) şi se încearcă următoarea valoare corespunzătoare acesteia ş.. ( ) 10. Principiul metodei şi structura generală a algoritmului Metoda backtracking constă în construirea soluţiei s completând succesiv componentele sk pentru k =1.. În majoritatea cazurilor nu orice element al produsului cartezian este soluţie ci doar cele care satisfac anumite restricţii.2.n. Această revenire la o componentă anterioară este specifică tehnicii backtracking. {1.107 - . s2.Proiectarea algoritmilor 10..x An (cu mulţimile Ak finite).d.

A1. ik reprezintă indicele elementului curent din Ak.108 - . În descrierea structurii generale a algoritmului vom folosi notaţiile: Ak = k k a1k . k indică componenta curentă din s. componentă căutată} ik ← 0 {index căutare în Ak} WHILE k > 0 DO {cât timp sunt componente la care să se revină} ik ← ik + 1 valid ← FALSE WHILE (valid = FALSE) AND (ik ≤ mk) DO {cauta comp.. b. An şi relaţiile de ordine care indică modul de parcurgere a fiecărei mulţimi • pornind de la restricţiile problemei se stabilesc condiţiile de validitate ale soluţiilor parţiale (condiţiile de continuare). neexistând restricţii.…. k} sk ← aik k Tehnica căutării cu revenire . . An) k←1 {nr.Proiectarea algoritmilor toate configuraţiile posibile.backtracking . Strategia de construire a soluţiilor aplicând backtracking este similară construirii unui structuri arborescente ale cărei noduri corespund unor soluţii parţiale valide (nodurile interne) sau soluţiilor finale (nodurile de pe frontieră).. A2. A2. toate nodurile de pe frontieră corespund unor soluţii. c} x {x. mk reprezentând numărul de elemente din Ak..1 este ilustrat modul de parcurgere a spaţiului soluţiilor în cazul generării produsului cartezian {a. Figura 10..1 Parcurgerea spaţiului soluţiilor În cazul în care sunt specificate restricţii anumite ramuri ale structurii arborescente asociate parcurgerii sunt abandonate înainte de a atinge lungimea n. Structura generală a algoritmului este: ( ) Backtracking(n. Nodurile de pe frontieră pot corespunde unor soluţii parţial invalide.. În aplicarea metodei pentru o problemă concretă se parcurg etapele: • se alege o reprezentare a soluţiei sub forma unui vector cu n componente • se identifică mulţimile Al.. În figura 10.. a2 . y}.. amk . În acest caz.

s2... . Mulţimile A1. 2. j ∈ {1. Dacă s = (s1.n} se poate considera sk = ik.. s2.backtracking . 4. .. Condiţiile de continuare se deduc din restricţiile problemei. În acest caz orice vector cu n componente care respectă restricţiile este o soluţie. În aplicaţiile concrete pot interveni următoarele situaţii: 1..n}.. = An. 3... . altfel procesul de căutare continuă prin analizarea următoarei valori a ultimei componente completate... nu sunt neapărat distincte sau elementele lor pot fi generate pe parcursul algoritmului fără a fi necesară transmiterea lor ca argument algoritmului.….. . Deci dacă k = n înseamnă că a fost găsită o soluţie. Prelucrarea soluţiilor.sk). s2. Restricţiile şi condiţiile de continuare. algoritmul de generare a permutărilor poate fi descris prin: Tehnica căutării cu revenire .Proiectarea algoritmilor IF (s1.sn) este o soluţie atunci ea trebuie să respecte restricţiile: si≠ sj pentru oricare i ≠j. s2. Exemplu: generarea permutărilor de ordin n. A2. Un vector cu k elemente. La găsirea unei soluţii de cele mai multe ori această se afişează sau se reţine într-o zonă dedicată. poate conduce la o soluţie doar dacă satisface condiţiile de continuare si≠ sj pentru orice i ≠j (i.…. O permutare de ordin n este un tablou cu n elemente distincte din {1.sk-1. . Mulţimile Ak Mulţimile ce conţin componentele soluţiilor sunt toate egale cu {1. (s1.sk) “satisface condiţiile de continuare” THEN valid ← TRUE ELSE ik ← ik +1 IF valid = TRUE THEN IF (s1... Condiţia de găsire a unei soluţii.......sk) este soluţie THEN WRITE “S-a găsit o soluţie” ELSE k ← k+1 {se trece la următoarea componentă} ik ← 0 ELSE k ←k–1 {se revine la precedenta} Observaţii..109 - .. 2. Cu aceste precizări. Se observă că este suficient să se verifice că sk este diferit de s1. Ordinea de parcurgere a elementelor este cea naturală: de la cel mai mic către cel mai mare element.2. An. Vom considera că verificarea condiţiilor de continuare va fi efectuată in cadrul unui algoritm de validare..... Caracteristicile acestei probleme sunt: Reprezentarea soluţiilor.2. n} A1 =A2= .. Dacă se doreşte identificarea unei singure soluţii atunci căutarea se opreşte după găsirea acesteia.. Întrucât Ak ={1. Pentru unele probleme soluţia este obţinută în cazul în care k = n iar pentru altele este posibil să fie satisfăcută o condiţie de găsire a soluţiei pentru k < n (pentru anumite probleme nu toate soluţiile conţin acelaşi număr de elemente). s2. Fiecare soluţie obţinută va fi afişată.k})....

.k) FOR i ← 1.. algoritmul poate fi descris prin: Backtracking_recursiv(k) IF (s1. mulţimile AI. s2. s2.An) au caracter global. s2.sk) THEN valid ← TRUE ELSE sk ← sk +1 IF valid = TRUE THEN IF k=n THEN WRITE s ELSE k ← k+1 sk ← 0 ELSE k ←k–1 unde funcţia de validare poate fi scrisă: Validare(s. k-1 DO IF sk = si THEN RETURN FALSE RETURN TRUE Varianta recursivă a algoritmului.sk) “satisface condiţiile de continuare” THEN Backtracking_recursiv(k+1) Tehnica căutării cu revenire .Proiectarea algoritmilor permutari(n) k←1 sk ← 0 WHILE k > 0 DO sk ← sk + 1 valid ← FALSE WHILE (valid = FALSE) AND (sk ≤ n) DO IF validare(s1.backtracking .mk DO sk → a k j IF (s1.….sk) este soluţie THEN WRITE “S-a găsit o soluţie” ELSE FOR j ← 1..110 - .…..…. Datorită faptului că după completarea componentei k problema se reduce la una similară de completare a componentei k + 1 cu una dintre valorile valide tehnica backtracking poate fi uşor descrisă recursiv. Considerând ca parametru al algoritmului a câta componentă trebuie completată în cadrul apelului curent şi considerând că celelalte date (n.

1} şi orice vector cu componente 0 sau 1 este o soluţie validă (nu se impun restricţii) rezultă că problema este echivalentă cu a genera elementele produsului cartezian A1 x . x An = {0....sn) caracterizat prin: dacă xk ∈ S ⎧1 sk = ⎨ dacă xk ∉ S ⎩0 Astfel A1= ..xn}. Aplicaţii Generarea tuturor submulţimilor unei mulţimi. Algoritmul poate fi descris prin: submultimi(n) k←1 sk ← -1 WHILE k > 0 DO sk ← sk + 1 IF sk ≤ 1 THEN IF k=n THEN WRITE s ELSE k ← k+1 sk ← -1 ELSE k ←k–1 iar varianta recursivă prin: Tehnica căutării cu revenire .s2. Orice submulţime S ⊂ X poate fi descrisă prin vectorul caracteristic S = (s1. .sk ELSE FOR j ← 1.…... s2..n DO sk → j IF validare(s. x2. Se consideră problema determinării tuturor celor 2n submulţimi ale unei mulţimi X = {x1. Pentru problema generării perrnutărilor de ordin n varianta recursivă a algoritmului este: Permutari_recursiv(k) IF k=n + 1 THEN WRITE s1..3.111 - ..Proiectarea algoritmilor Algoritmul se apelează pentru k =1 (completarea soluţiei începe cu prima componentă) Backtracking_recursiv(1) Exemplu.. 1}n.k) THEN permutari_recursiv(k+1) 10. = An = {0.backtracking .. .

s2.….s2.….s2.sk) este ∑s j =1 n j = m .. Un vector (s1.m) k←1 sk ← -1 WHILE k > 0 DO sk ← sk + 1 IF (sk ≤ 1) AND suma(s1.112 - .sk)=m THEN WRITE s ELSE IF k < n THEN k ← k+1 sk ← -1 ELSE k ←k–1 Algoritmul suma(s1..Proiectarea algoritmilor subm_rec(k) IF k=n + 1 THEN WRITE s1... Această problemă se caracterizează prin faptul că soluţiile satisfac restricţia că numărul de componente egale ⎛ n ⎞ cu 1 (sau echivalent suma tuturor componentelor) este egală cu m ⎜ ∑ s j = m ⎟ .backtracking .s2. Algoritmul submultimi se modifică după cum urmează: combinari(n.k.. Această ⎜ ⎟ ⎝ j =1 ⎠ restricţie conduce la condiţia de continuare: soluţie dacă ∑s j =1 k j ≤ m ..….sk) ≤ m THEN IF suma(s1.…..sn ELSE sk → 0 subm_rec(k+1) sk → 1 subm_rec(k+1) Pornind de la acest algoritm poate fi descris cel pentru generarea tuturor submulţimilor cu m elemente (combinări de n luate câte m). Varianta recursivă se obţine uşor din subm_rec prin introducerea restricţiilor: Tehnica căutării cu revenire .s2. Se observă că vectorii având toate componentele completate (k = n) dar pentru care suma elementelor este diferită de m sunt ignoraţi..sk) calculează suma elementelor din s pentru indice în domeniul 1.

1. Din modul de reprezentare a soluţiilor restricţia ca damele să nu fie plasate pe aceeaşi linie este implicit satisfăcută.113 - . La completarea componentei k condiţiile de continuare sunt: sk ≠ si şi |k . numărul configuraţiilor devine din ce în ce mai mare (pentru n = 8 există 92 de configuraţii) .s2.sk-1 ELSE sk → 0 comb_rec(k+1) sk → 1 comb_rec(k+1) Amplasarea dame lor pe tabla de şah. dame trebuie amplasate în cadrul unei matrice pătratice n x n..sk-1)=m THEN WRITE s1.2 Configuraţii valide pentru problema damelor (n=4) Restricţii şi condiţii de continuare.s2. Întrucât pe fiecare linie se va afla exact o damă şi toate damele sunt identice este suficient să reţinem coloana pe care se află fiecare dintre ele.4. Figura 10.…. Condiţia ca pe orice coloană să se afle o singură damă este echivalentă cu si≠ sj pentru orice i ≠ j.3) respectiv (3. În ceea ce priveşte condiţia referitoare la diagonale pornim de la observaţia că două elemente ale unei matrice aflate pe poziţiile (i1.sn) unde sk indică coloana pe care se va afla dama de pe linia k.sj şi i _ si ≠ j + sj pentru orice i ≠ j.s2.….Proiectarea algoritmilor comb_rec(k) IF suma(s1.backtracking . Considerăm cazul general în care n. Astfel condiţia ca două dame să nu se afle pe aceeaşi diagonală este: i .4. pe nici o coloană şi pe nici o diagonală să nu se afle două dame. O problemă clasică (enunţată de Gauss în 1850) de generare a unor configuraţii ce respectă anumite restricţii este cea a amplasării damelor pe o tablă de şah astfel încât să nu se atace reciproc. Cele două relaţii sunt echivalente cu | i – j | ≠ |si – sj| pentru orice i ≠ j.2 sunt (2.2). Astfel soluţia problemei va fi de forma (s1.j2) se află pe aceeaşi diagonală dacă i1-j1 = i2-j2 sau i1+j1 = i2+j2. Vectorii corespunzători configuraţiilor din figura 10.…. Pentru valori mai mari ale lui n. astfel încât pe nici o linie. Reprezentarea soluţiei. Descrierea algoritmului Tehnica căutării cu revenire .j1) respectiv (i2.si ≠ j .i| ≠ |sk – si| pentru orice k≠i.1.

…..….s2...k) THEN dame_rec(k+1) Tehnica căutării cu revenire .2.k) THEN valid ← TRUE ELSE sk ← sk + 1 IF valid = TRUE THEN IF k=n THEN WRITE s1.n}.Proiectarea algoritmilor Plasare_dame(n) k←1 sk ← 0 WHILE k > 0 DO sk ← sk + 1 valid ← FALSE WHILE (valid = FALSE) ∧ (sk ≤ n) DO IF validare(s.sn ELSE FOR i ← 1.k) FOR i ← 1.s2..n DO sk ← i IF validare(s. pentru A1=A2=.114 - . k-1 DO IF (sk = si) OR |k-i|=|sk – si| THEN RETURN FALSE RETURN TRUE În varianta recursivă algoritmul poate fi descris prin: Dame_rec(k) IF k=n+1 THEN WRITE s1.=An= {1..backtracking .sn ELSE k ← k+ 1 sk ← 0 ELSE k←k–1 Se observă că structura algoritmului este cea generală. iar validarea implementează condiţiile de continuare: Validare(s..

. Descrierea algoritmului Colorare(n) k←1 sk ← 0 WHILE k > 0 DO sk ← sk + 1 valid ← FALSE WHILE (valid = FALSE) ∧ (sk ≤ n) DO IF validare(s... Restricţii şi condiţii de continuare.k) FOR i ← 1.. Condiţia de continuare pe care trebuie să o satisfacă soluţia parţială (s1. k-1 DO IF (sk = si) AND (vik = 1) THEN RETURN FALSE RETURN TRUE În varianta recursivă algoritmul poate fi descris prin: Tehnica căutării cu revenire ..backtracking .s2.sk) este: sk ≠ si pentru orice i < k cu proprietatea că vik = 1... m}... Mulţimile de valori ale elementelor sunt A1 = .. Relaţia de vecinătate dintre ţări este reţinută Într-o matrice n x n ale cărei elemente sunt: dacă i e vecină cu j ⎧1 vij = ⎨ dacă i nu e vecină cu j ⎩0 Reprezentarea soluţiilor. Restricţia ca două ţări vecine să fie colorate diferit se specifică prin: si ≠ sj pentru orice i şi j având proprietatea vij = 1. m} reprezentând culoarea asociată tării i.115 - .k) THEN valid ← TRUE ELSE sk ← sk + 1 IF valid = TRUE THEN IF k=n THEN WRITE s1. Se consideră o hartă cu n ţări care trebuie colorată folosind m < n culori....sn) cu si ∈ {1.Proiectarea algoritmilor Colorarea hărţilor. = An = {1.sn ELSE k ← k+ 1 sk ← 0 ELSE k←k–1 cu algoritmul de validare: Validare(s.s2.... astfel încât oricare două ţări vecine să fie colorate diferit. O soluţie a problemei este o modalitate de colorare a ţărilor şi poate fi reprezentată printr-un vector (s1...….s2..

….k) THEN colorare_rec(k+1) Determinarea tuturor drumurilor dintre două oraşe.116 - . O soluţie a problemei este de forma s1.backtracking . k . iar la apel se specifică drumuri_rec(2).s2. Se consideră o mulţime de n oraşe {o1.. o2. sm = q (oraşul destinaţie). În varianta recursivă algoritmul poate fi descris prin: Drumuri_rec(k) IF sk-1 = q THEN WRITE s1.. n ..….. O soluţie (s1.. Condiţia de găsire a unei soluţii nu este determinată de numărul de componente completate ei de faptul că sk = q.n DO sk ← i IF validare(s. condiţia de continuare este sk ≠si i = 1...1 (între oraşele parcurse succesiv există drum direct).n} indicând oraşul care va fi parcurs în etapa i a traseului.…...k) THEN drumuri_rec(k+1) cu validarea specifică dată mai jos.…..s2. Înainte de apel se completează s1 cu p.2.. vsi si +1 = 1 pentru i = 1..2. si ≠sj pentru orice i ≠ j (nu se trece de două ori prin acelaşi oraş).1 şi vsk −1sk = 1 . La completarea componentei k.sk-1 ELSE IF k ≠ n+1 THEN FOR i ← 1.s2.2.. on} şi o matrice binară cu n linii şi n coloane care specifică între care oraşe există drumuri directe.sn ELSE FOR i ← 1. Elementele matricei sunt de forma: dacă există drum direct între i şi j ⎧1 vij = ⎨ altfel ⎩0 Se pune problema determinării tuturor drumurilor care leagă oraşul op de oraşul oq . Tehnica căutării cu revenire .n DO sk ← i IF validare(s. Restricţii şi condiţii de continuare.Proiectarea algoritmilor Colorare_rec(k) IF k=n+1 THEN WRITE s1.sm ) trebuie să satisfacă: s1 = p (oraşul de start). Reprezentarea soluţiilor..sm cu si ∈ {1.s2. Spre deosebire de problemele anterioare nu toate soluţiile au aceeaşi lungime..

4. Este suficient să se modifice condiţia de găsire a unei soluţii din k = n în k = m. k-1 DO IF (sk = si) THEN RETURN FALSE RETURN TRUE 10. Indicaţie.Proiectarea algoritmilor Validare(s. 3. Dezvoltaţi un algoritm bazat pe tehnica backtracking pentru rezolvarea variantei discrete a problemei rucsacului. Indicaţie. Să se modifice algoritmul pentru generarea permutărilor de ordin n astfel încât să fie generate aranjamentele de n luate câte m.sk = 0 THEN RETURN FALSE ELSE FOR i ← 1.117 - .k) IF vsk −1 .backtracking . Să se modifice algoritmul pentru generarea permutărilor de ordin n astfel încât să fie generate doar permutările ce nu conţin puncte fixe (si ≠ i pentru orice i). Este suficient să se modifice algoritmul de validare astfel încât să se verifice în plus că sk ≠ k. Exerciţii 1. Tehnica căutării cu revenire . 2.

Verifică valoarea variabilei imediat după obţinerea acesteia. în al doilea caz se recomandă ca verificarea să urmeze imediat după citirea valorii respectivei variabile. reducând costul realizării programelor. Dar nu se poate rezolva o problemă dacă nu se cunoaşte această problemă.. Divide et impera .c2 verifică respectarea acestei proprietăţi. Aceste metode încurajează reutilizarea. folosirea unor componente existente (deci testate) măreşte gradul de fiabilitate a produselor soft realizate şi scurtează perioada de realizare a acestora. De asemenea. trebuie pusă în prim plan gândirea. să fie construit având tot timpul în faţă această specificaţie. care ar fi cea mai potrivită scopului urmărit? În paralel cu proiectarea algoritmului demonstrează corectitudinea lui. ci una foarte importantă şi adeseori chiar dificilă. Rafinarea în paşi succesivi. programarea modulară.118 - . Gândeşte mai întâi. să fie testat şi validat ţinând seama de această specificaţie. să i se demonstreze corectitudinea în raport cu această specificaţie. Verifică corectitudinea fiecărui pas înainte de a merge mai departe.Sfaturi . Este vorba de programarea Top-Down. Cunoaşte şi foloseşte metodele de programare. foarte importantă în activitatea de programare. să nu se bazeze pe specificul unui anumit compilator. Este specificaţia problemei corectă? Între metodele de rezolvare posibile. Programul realizat trebuie să fie portabil. SFATURI PENTRU PROIECTAREA ALGORITMILOR 1. 5. Cu toate acestea nu e bine să ne bazăm pe o asemenea iniţializare ci să atribuim singuri valorile iniţiale corespunzătoare variabilelor. Dacă ai primit o sarcină fără specificaţii complete atunci să le ceri! 2. Nu folosi variabile neiniţializate. viteza de lucru va creşte prin Epilog . etc. dacă o parte din subalgoritmii necesari programului sunt deja scrişi şi verificaţi. Specificarea corectă şi completă a problemei nu este o sarcină trivială. verificarea trebuie făcută după calcul. În primul caz. Este vorba de prezenţa unei variabile într-o expresie fără ca în prealabil această variabilă să fi primit valoare. Bottom-up şi mixtă. Programul trebuie să respecte această specificaţie. programează pe urmă.Proiectarea algoritmilor EPILOG. neverificând dacă o variabilă a fost iniţializată înaintea folosirii ei. Începând cu scrierea specificaţiilor problemei. Destule compilatoare permit folosirea variabilelor neiniţializate. 4. pare fără sens pentru unii cititori. Această indicaţie. Este o eroare foarte frecventă a programatorilor începători (dar nu numai a lor). 3. Dacă o variabilă întreagă trebuie să ia valori într-un subdomeniu c1. Defineşte complet problema. Evident. Alte compilatoare iniţializează automat variabilele numerice cu valoarea zero. Orice încălcare a ei indică o eroare care trebuie înlăturată. Valoarea variabilei poate fi calculată sau introdusă de utilizator.

).Sfaturi . a prescurtărilor şi simplificărilor se pierde adesea din claritatea programului şi. Nu uita însă că pentru beneficiar "Detaliile nesemnificative sunt semnificative". Verifică corectitudinea algoritmului şi programului în fiecare etapă a elaborării lor. în primul rând se acordă atenţie aspectelor esenţiale. câteodată. mult mai grav. În plus se poate pierde portabilitatea programului. O bună programare modulară elimină legăturile între două module prin variabile globale. Se recomandă demonstrarea corectitudinii fiecărui algoritm folosit. 8. Se recomandă ca fiecare modul să realizeze o activitate bine definită şi independentă de alt modul.Proiectarea algoritmilor folosirea lor. modificarea este mult mai uşoară (doar la locul definiţiei constantei) şi nu duce la erori. uneori se ajunge chiar la introducerea unor erori. nu modificarea valorii concrete în toate instrucţiunile programului. care să înglobeze experienţa proprie. Comunicarea între două module trebuie să se realizeze numai prin mecanismul parametrilor formali-actuali. sau nu sunt corecte. Prin folosirea artificiilor în programare. 9. începând cu modulul principal. În fiecare fază dă atenţie lucrurilor importante. Evită artificiile. evitându-se activităţi inutile de depanare. Foloseşte deci bibliotecile de componente reutilizabile existente şi construieşte singur astfel de biblioteci. la precizarea limitelor de variaţie a unor variabile. etc. Foloseşte constante simbolice. imposibil de eliminat altfel decât prin rescrierea modulului sau programului respectiv. iar în situaţia în care valoarea unei constante trebuie schimbată. Amână pe mai târziu detaliile nesemnificative . este inutil să se piardă timp cu scrierea unor părţi de program pentru tipărirea rezultatelor şi a constata ulterior că rezultatele nu sunt cele dorite. judecă programatorii după această formă. Detectarea şi eliminarea unei erori imediat după comiterea ei duce la creşterea vitezei de realizare a produsului. 7. adeseori. Această regulă stabileşte priorităţile de realizare a componentelor unui program. Beneficiarii ţin foarte mult la forma rezultatelor şi. în caz contrar nu se recomandă folosirea lor. 6. Urmează testarea fiecărui subprogram imediat Epilog . De exemplu. Ea implică numai definiţia constantei. Dacă acest fapt este important atunci artificiile sunt binevenite. Prin utilizarea acestor constante se măreşte gradul de generalitate a textului scris. Există însă situaţii în care prin anumite artificii se câştigă eficienţă în execuţie sau se face economie de memorie. Folosirea intensivă a constantelor simbolice este recomandată oriunde în textul sursă trebuie scris un număr (la declararea tablourilor. întrucât erorile semnalate în timpul testării sunt adeseori greu de descoperit şi.119 - . E păcat de munca depusă dacă tipărirea rezultatelor lasă o impresie proastă asupra beneficiarului.

în codificare (şi testarea aferentă codificării). Foloseşte denumiri sugestive pentru identificatorii utilizaţi în program. acesteia i se ataşează un invariant. Fiecare identificator (nume de variabilă. 10. Folosirea necontrolată a mai multor variabile auxiliare. care să scoată cât mai bine în evidenţă structura programului şi funcţiile fiecărei părţi a acestuia. lungimea programului creşte şi citirea lui devine greoaie. ruperea unor expresii chiar lungi în subexpresii cu diferite denumiri. Fiecare variabilă are o semnificaţie. .obligă implementatorul să gândească încă o utilizare (cel puţin) a respectivului subprogram. Prin scriere redă cât mai fidel structura programului. 13.facilitează detectarea erorilor. obţinuţi prin concatenarea mai multor cuvinte. 15. Sugerăm ca această testare să se facă independent de programul în care se va folosi subprogramul testat. O greşeală frecventă făcută de unii programatori constă în folosirea unei variabile în mai multe scopuri. Fiecare variabilă trebuie să aibă o semnificaţie proprie. Dacă pentru proiectare se pot folosi oricare dintre metodele indicate. ceea ce rămâne de testat la nivelul respectiv este gestiunea corectă a apelurilor respectivelor componente. E bine ca denumirea să reflecte această semnificaţie. folosind identificatori lungi. dar claritatea textului scade. . abordarea de jos în sus este esenţială. În demonstrarea corectitudinii algoritmului această semnificaţie se reflectă. Fiecare programator trebuie să aibă propriile reguli de scriere. Unii programatori exagerează însă. E clar că denumirea alesă redă semnificaţia variabilei. Importanţa indentării şi spaţierii pentru claritatea programului au fost arătate anterior. în fapt nu se pierde timp cu scrierea unui program de test. iar în demonstrarea corectitudinii programului. de constante. 14. de cele mai multe ori. deoarece dimensiunea problemei este mai mică. deoarece la fiecare nivel de detaliere se vor folosi numai componente testate deja. Acest lucru se potriveşte codificării bottom-up şi sugerează o abordare sistematică a activităţii de codificare. Cunoaşte şi respectă semnificaţia fiecărei variabile.Proiectarea algoritmilor după ce a fost scris (codificat). de tip de date. Foloseşte variabile auxiliare numai acolo unde este strict necesar. ci se câştigă timp. mărind astfel claritatea textului programului. independentă de cea pentru care a fost iniţial conceput. pot duce la reducerea clarităţii programului. care trebuie verificat. dar ea este utilă cel puţin din trei puncte de vedere: . Este adevărat că activitatea de testare necesită un anumit timp. Epilog .120 - .Sfaturi . printr-un predicat invariant. de subprograme) îşi are rolul şi semnificaţia lui într-un program.scoate în evidenţă erorile provocate de proiectarea algoritmului sau codificarea neadecvată a acestuia.

proiectarea algoritmilor. În situaţia când corpul conţine şi testarea condiţiei de continuare a ciclării. Atunci când este necesară schimbarea variabilei de ciclare sau a limitelor se recomandă folosirea uneia din structurile repetitive REPEAT sau WHILE <condiţie> DO. program scris în urmă cu câteva luni sau ani de zile. 20.Proiectarea algoritmilor 16. care contribuie la asigurarea a ceea ce am numit interfaţă prietenoasă. chiar dacă este vorba de propriu. Nu uita să testezi programul chiar dacă ai demonstrat corectitudinea lui. programul poate conţine greşeli de codificare. Primele trei sunt necesare la întreţinerea aplicaţiei. Dar. chiar dacă demonstrarea corectitudinii algoritmului este validă. datele de test folosite).. programul propriu-zis. Şi o demonstraţie a corectitudinii unui program poate fi greşită. Rolul comentariilor a fost explicat în secţiunea 4. implementare şi exploatare. Pe lângă acestea. E bine ca aceste decizii să rămână consemnate împreună cu rezultatul final al fiecărei faze din viaţa programului (specificarea problemei. 18. Minimum de comentarii într-un modul trebuie să conţină specificarea acestui modul şi semnificaţia fiecărei variabile. proiectare.. DO şi nu FOR. Orice program sau modul trebuie să fie însoţit de comentarii explicative dacă dorim să-l refolosim şi nu trebuie să scriem programe care să nu poată fi refolosite. Foloseşte comentariile. Elaborează documentaţia programului în paralel cu realizarea lui. trebuind a fi actualizate ori de câte ori se produc modificări. Este foarte greu să descifrăm un program lipsit de comentarii. Nu recalcula limitele şi nu modifica variabila de ciclare în interiorul unei structuri repetitive dată prin propoziţia FOR O astfel de practică poate duce la erori greu de detectat şi încalcă regulile programării structurate. recomandăm a se folosi structurile REPEAT sau WHILE . un program bun va trebui să posede şi o componentă de asistenţă on-line (funcţie help). 19. pe durata de viaţă a unui program se iau mai multe decizii.121 - . iar ultima este necesară celor care exploatează aplicaţia. 17. Aşa cum s-a arătat în mai multe locuri din acest material. Nu ieşi forţat din corpul unei structuri repetitive redată prin propoziţia FOR Instrucţiunea FOR corespunde unui număr cunoscut de execuţii ale corpului ciclului. de introducere (tastare) sau pot fi alte cauze care generează erori. Vor rezulta documentaţii de analiză. Sunt cunoscute demonstraţii greşite pentru unele teoreme celebre din matematică. Epilog .Sfaturi .4.

Proiectarea algoritmilor EXERCIŢII SUPLIMENTARE 1. Stabilirea complexităţii unui algoritm 1.1. Se consideră algoritmul pentru calculul produsului scalar al doi vectori, de dimensiune n:
n r r v1 ⋅ v2 = ∑ v1i ⋅ v2i i =1

Funcţia care generează produsul scalar, în pseudocod este: produs _ scalar (v1, v 2, n) 1 : ps ← 0 | stocare produs scalar
2 : FOR i = 1, n 3: || ps ← ps + v1i ⋅ v 2i RETURN ps Să se stabilească complexitatea algoritmului, considerând toate operaţiile cu cost egal.

Rezolvare Notând instrucţiunile cu 1, 2, 3 vom avea numărul de operaţii: 1: 1 2: 2·(n+1) 3: 3·n Pentru instrucţiunea FOR s-au considerat 2 operaţii pentru fiecare valoare a lui i: incrementare şi verificarea i ≤ n. Operaţia se execută până i=n+1. Pentru instrucţiunea 3-a s-a ţinut seama că avem 3 operaţii pentru fiecare valoarea a lui i: o înmulţire, o adunare şi o atribuire. Sumând obţinem: T(n) = 5·n+3 Rezultă T(n) Є Θ(n). 1.2. Să se scrie şi să se determine complexitatea pentru algoritmul de ortonormare r r r prin procedeul Gramm-Schmidt. Vectori de intrare: v1 , v2 ,.., vn . Vectorii r r r ortonormaţi de ieşire: d1 , d 2 ,.., d n . Aceştia au proprietatea: r r ⎧1 daca i = j di ⋅ d j = ⎨ ⎩0 daca i ≠ j Calculul vectorilor ortonormaţi se face iterativ cu relaţiile:

Exerciţii suplimentare

- 122 -

Proiectarea algoritmilor r r v1 d1 = r v1
r r i −1 r r r ui = vi − ∑ vi ⋅ d k ⋅ d k , i = 2,.., n r r ui d i = r , i = 2,.., n ui
k =1

(

)

Rezolvare Folosim tehnica rafinării unui algoritm în subalgoritmi. Întrucât avem n vectori cu n componente vom folosi matrice pătrate pentru memorarea unui sistem de r vectori (v ,d ,u) notate cu [V], [D], [U]. Un vector oarecare vi va fi memorat în coloana i a matricei [V]. r Mai întâi scrie funcţia care determină modulul unui vector vi : valabs (v, n, i )

1: a ← 0 2 : FOR k = 1, n 3: 4:
2 || a ← a + vki

a← a RETURN a

r r u Procedura de calcul a vectorului de lungime unitară: d i = ri ui norm(u, d , n, i ) 1 : mu ← valabs(u, n, i ) 2 : FOR k = 1, n u 3: || d ki ← ki mu RETURN d De remarcat că procedura de mai sus modifică numai coloana i din matricea [D]. r r Procedura pentru produsul scalar, descrisă la problema 1, dintre vectorii ui , d k va fi: produs _ scalar (u, d , n, i, k ) 1 : ps ← 0 | stocare produs scalar
2 : FOR j = 1, n 3: || ps ← ps + u ji ⋅ d jk RETURN ps
Exerciţii suplimentare - 123 -

Proiectarea algoritmilor Algoritmul principal va fi: Ortonormare(v, d , n)
1 : d ← norm(v, d , n,1) 2 : FOR i = 2, n 3: 4: 5: 6: || FOR k = 1, n || || u ki ← vki || FOR k = 1, i − 1 || || ps ← produs _ scalar (v, d , n, i, k )

r r v1 | d1 = r v1

r r | ui = vi r r | vi ⋅ d k
i −1 r r r | ui − ∑ vi ⋅ d k ⋅ d k

7: 8: 9:

|| || FOR j = 1, n || || || u ji ← u ji − ps ⋅ d jk || d ← norm(u , d , n, i ) RETURN d

r r ui | di = r ui

k =1

(

)

Scriem complexitatea pe module. Numărul de operaţii: a. Procedura valabs 1: 1 2: 2·(n+1) 3: 3·n 4: 2 T1(n) = 5·n + 5

| ridicare la pătrat, adunare şi atribuire | radical şi atribuire

b. Procedura produs_scalar T2(n)=5·n+3 | a se vedea problema 1.1 c. Procedura norm 1: T1(n)+1 | modul+atribuire 2: 2·(n+1) 3: 2·n | împărţire şi atribuire T3(n)=5·n+5+4·n+3=9·n+8 Algoritmul principal: 1: T3(n)+1=9·n+9=9·(n+1) 2: 2·n 3: (n-1) ·2·(n+1) 4: (n-1) ·n

Exerciţii suplimentare

- 124 -

partea întreagă. atribuire 4: p·3 | 3 operaţii logice – pentru n prim 2·3 | pentru n divizibil cu 2 5: 2·(p-1) | calcul rest +testare rest=0.Proiectarea algoritmilor 5: 6: 7: 8: 9: i=2 ∑ 2 ⋅ i = 2 ⋅ ∑ (i + 1) = n ⋅ (n − 1) + 2 ⋅ (n − 1) = (n + 2)⋅ (n − 1) i =1 n n −1 i =1 i=2 n n −1 [T 2(n) + 1]⋅ ∑ (i − 1) = [T 2(n) + 1]⋅ ∑ i = n ⋅ (n − 1) ⋅ (5 ⋅ n + 4) 2 i = 2 k =1 n i −1 n ∑ ∑ 2 ⋅ (n + 1) =2 ⋅ (n + 1)⋅ ∑ (i − 1) = 2 ⋅ (n + 1)⋅ ∑ i = (n − 1)⋅ n ⋅ (n + 1) i=2 i =1 i = 2 k =1 j =1 n i −1 n n −1 ∑ ∑∑ 3 = ∑ ∑ 3 ⋅ n = 2 ⋅ (n − 1)⋅ n 2 i = 2 k =1 n i −1 3 (n − 1) ⋅ [T 3(n) + 1] = (n − 1) ⋅ (9 ⋅ n + 9) = 9 ⋅ (n − 1) ⋅ (n + 1) T (n) = 5 ⋅ n 3 + 11⋅ n 2 + 8 ⋅ n − 4 Rezultă T(n) Є Θ(n3). 1.125 - . dat mai jos: prim(n) 1: r ← T 2: i ← 2 3: p ← n 4 : WHILE (i ≤ p ) and (r = T ) 5: || IF n mod i = 0 6: || || r ← F 7: || i ← i + 1 RETURN r [ ] Rezolvare Numărul de operaţii pentru procedura prim: 1: 1 2: 1 3: 3 | radical. pentru n prim | pentru n divizibil cu 2 2 6: 1 | pentru n neprim 7: p-1 | pentru n prim | pentru n divizibil cu 2 1 Exerciţii suplimentare . Să se stabilească complexitatea algoritmului pentru verificarea dacă un număr este prim.3.

( ) Rezolvare Dacă considerăm şirul care memorează înregistrările xi. Sortarea se va face în ordinea descrescătoare a salariului şi. n || x0 ← xi || k ← i − 1 || WHILE xk ..marca. se realizează sortarea. atunci accesarea informaţiilor relative la o marcă se va face sub forma x.salariu || || xk +1 ← xk || || k ← k − 1 || xk +1 ← x0 k ←1 | sortare dupa nume in ordine crescatoare WHILE k ≤ n − 1 || i ← k + 1 || WHILE ( xi . Datele sunt memorate sub forma unor înregistrări având cele 3 câmpuri.salariu ) and (i ≤ n ) | cat timp salariul este acelasi || || i ← i + 1 | sortare dupa salariu metoda insertiei Exerciţii suplimentare . în ordinea alfabetică a câmpului nume+prenume. n) FOR i = 2. nume şi prenume.salariu = xi −1. salariu. după nume+prenume. i=1.Proiectarea algoritmilor Cazul cel mai favorabil – n divizibil cu 2: T(n) = 15 Cazul cel mai nefavorabil – n prim: T(n) = 5+3·p+3·(p-1) = 6·p+2 15 ≤ T ( n) ≤ 6 ⋅ n + 2 Rezultă T (n) ∈ O n şi T (n) ∈ Ω(15) .1. x..salariu < x0 . 2. iar apoi..126 - .salariu.nume_prenume. Se va realiza mai întâi sortarea după salariu. Sortare 2. Algoritmul este prezentat mai jos: sortare _ personal ( x. în ordine alfabetică. Vom folosi metoda de sortare prin inserţie. pentru acelaşi salariu. Să se scrie algoritmul pentru sortarea unor înregistrări care conţin: marca. x. pentru mărcile care au acelaşi salariu.2.n. Vom folosi un fanion pe poziţia x0.

camp valoarea unui câmp (nod1. cu numele fsir.127 - . variabile cu indice cuprins între k şi i. nod2 reprezintă marca nodurilor (valori numerice. a şirurilor de caractere aferente numerelor nod1 şi nod2. Şirul de intrare este citit dintr-un fişier ASCII. Şirul rezultant va fi memorat dinamic prin variabile înlănţuite în memorie prin pointeri.. crescător după nume. sub forma: p nod1 nod2 record 1 next nod1 nod2 record 2 next nod1 nod2 record n nil unde nod1. Prima variantă este de a genera şirul memorat dinamic sortat în raport cu nod1 şi apoi sortarea în raport cu nod2 pentru valorile multiple ale lui nod1.2. Cheia de sortare va fi câmpul compus nod1 + nod2.Proiectarea algoritmilor || IF i > k + 1 || || sort _ num( x. Rezolvare Având în vedere că sortarea se face crescător în raport cu nod1 şi nod2. k .1.. avem 2 variante de sortare. de exemplu. i ) FOR m = k + 1. i || x0 ← xm || n ← m − 1 || WHILE ( xn . cu maxim 5 cifre).nume _ prenume ) and (n ≥ k ) || || x n +1 ← xn || || n ← n − 1 || xn +1 ← x0 RETURN x 2. record n.nume _ prenume > x0 . i − 1) | sortare dupa nume la aceleasi salariu || k ← i RETURN x Sortare prin metoda inserţiei. adică principiul utilizat la problema 2. O altă variantă este de a genera direct cheia compusă prin concatenarea. nod2. Nil indică că nu mai urmează nici o înregistrare. Vom nota cu x^. record 2. record) din înregistrarea dinamică x. sort _ num( x. k . pentru persoanele care au acelaşi salariu. câmpuri compuse care conţin informaţii despre laturile delimitate de nodurile respective. Semnificaţia notaţiei este „accesează” câmpul „camp” de la adresa x. adică nod1 crescător şi pentru acelaşi nod1. Vom prezenta în continuare ce-a de-a doua variantă. Variabilele p şi next sunt adrese ale înregistrărilor în memorie. iar record 1. nod2 în ordine crescătoare. Exerciţii suplimentare .. Să se sorteze în ordine crescătoare un şir cu date referitoare la laturile ale unei reţele electrice. secvenţial.

nod 2) r ← str (nod1.5) se converteşte câmpul numeric n într-un şir pe 5 caractere.nod 2 ← nod 2 || x ^. De exemplu ntostr(17. Procedura sortlat este prezentată pe pagina următoare.nod 2) < ntostr ( nod1. record | se memoreaza prima inregistrare citita x ^.next ← nil | cat timp nu s − a ajuns la sfarsitul fsir WHILE NOT EOF ( fsir ) || READ fsir . În acest caz funcţia READ aflată după WHILE NOT EOF(fsir) trebuie amplasată înaintea buclei.5) RETURN r Prin funcţia str(n. nod 2.next Exerciţii suplimentare .record ← record || xs ← p || WHILE ( xs ^. Există medii de dezvoltare (de exemplu FOX) în care funcţia EOF (sau similară) generează T la încercarea de citire a unei înregistrări aflată după ultima înregistrare validă. Şirul generat are spaţii în faţă dacă n<10000.Proiectarea algoritmilor Procedura de generare a unei chei compuse denumită ntostr (numeric to string) este: ntostr (nod1. De precizat că în procedura prezentată s-a considerat că funcţia EOF(fisier) generează T la citirea ultimei înregistrări valide.nod 2 ← nod 2 x ^. record || NEW x || x ^. nod1. xs ^. iar în interiorul buclei va fi amplasată o instrucţiune de citire la sfârşitul ei.nod1 ← nod1 | in x x ^. nod 2) | pozitionare in sir int re xs si xm || || xm ← xs || || xs ← xs ^.nod1. nod 2.35) = ’ 17 35’.next ≠ nil ) and ntostr ( xs ^.128 - .5) + str (nod 2. nod1.record ← record | marcheza ca ultima inregistrare x ^.nod1 ← nod1 | se memoreaza inregistrare citita || x ^. sortlat | deschide fisier ASCII sursa OPEN fsir | aloca memorie pentru o inregistrare dinamica NEW x | memoreaza in p adresa primei inregistrari p←x | citeste o inregistrare din fisierul sursa READ fsir .

initial 1 | catul impartirii lui n la 2 k . initial n | coeficientul ak k RETURN p Exerciţii suplimentare .1. Să se scrie o procedură pentru calcul xn .129 - .1. Algoritmul este prezentat mai jos: k k −1 k −1 putere( x. Rezolvare Descompunem de n după puterile lui 2: n= k =0 ∑ ak ⋅ 2 k . x Є R..m valoarea x 2 = x 2 ⋅ x 2 pentru generarea succesivă a factorilor. initial k = 0 | factor ce retine x n . Totodată.next ← xs || IF xs = p | " agata" inregistrarea urmatoare | pozitionare la inceput | pozitionare in sir sau la sfarsit || || || p ← x || xm^. Reducere şi divizare 3. x n = x k =0 = x a m ⋅ 2 ⋅ x a m−1 ⋅ 2 ⋅ ⋅ ⋅ ⋅x a1 ⋅ 2 ⋅ x a 0 Având în vedere că descompunerea unui număr în baza 2 prin împărţire repetată la 2 ne dă mai întâi puterile mici. n) s←x p ←1 c←n WHILE c > 0 || r ← c mod 2 ⎡c⎤ || c ← ⎢ ⎥ ⎣2⎦ || IF r > 0 || || p ← p ⋅ s || s ← s ⋅ s | ∏ x ai ⋅2 | ∏ x2 i =0 i =0 k +1 i k i | factorul x 2 . rezultă că va trebuie să reţinem la un pas k. care aibă clasa de complexitate Θ(lgn). unde ∑ ak ⋅2 k m m m −1 m m =[ lgn] (logaritm în baza 2).Proiectarea algoritmilor || x ^. iar ak=0 sau 1. n Є N. k=0...next ← x || ELSE 3. într-o altă variabilă trebuie rezultatul curent al ridicării la putere ţinând seama de coeficienţii ak.

daca f (a) ⋅ f ⎜ ⎟<0 2 ⎝ 2 ⎠ Algoritmul se va opri atunci când |a-b| < ε. Rezultă: a ⋅ (m + 1) + c + 1 ≤ T (n) ≤ (a + 1) ⋅ (m + 1) + c a ⋅ (lg n + 1) + c + 1 ≤ T (n) ≤ (a + 1) ⋅ (lg n + 1) + c T (n) ∈ Θ(lg n ) a. Să se stabilească un algoritm pentru rezolvarea ecuaţiei. Se va folosi metoda înjumătăţirii intervalului.2. limitele noului interval se vor calcula astfel: a+b ⎛a+b⎞ a← . Rezolvare Algoritmul de rezolvare a ecuaţiei. adică soluţia se află în intervalul [a.numărul de operaţii din ciclul WHILE care nu depind de valoarea lui n c.Proiectarea algoritmilor Pentru a aprecia complexitatea. a şi b. Toate instrucţiunile din ciclu se execută de m+1 ori.b]. mai puţin instrucţiunea p=p·s care se execută de m+1 ori pentru n=2m+1-1 şi se execută o dată pentru n=2m. observăm că ciclul WHILE se repetă de m+1 ori (numărul de cifre ale lui n în baza 2). Să se aprecieze complexitatea algoritmului (se vor considera numai iteraţiile de bază). f(x)=0. cunoscându-se două valori ale lui x. prim metoda înjumătăţirii intervalului este: rez _ ec( f .numărul de operaţii din afara ciclului WHILE 3. a. daca f (b) ⋅ f ⎜ ⎟<0 2 ⎝ 2 ⎠ a+b ⎛a+b⎞ b← .130 - . cu f(a)·f(b) < 0. b > a. b) IF f (a) ⋅ f (b) > 0 || WRITE " Interval de cautare eronat!" ELSE || WHILE b − a > ε ⎛ a+b⎞ || || IF f ⎜ ⎟ ⋅ f (a) > 0 ⎝ 2 ⎠ a+b || || || a ← 2 || || ELSE a+b || || || b ← 2 a+b RETURN 2 Exerciţii suplimentare .

. ..3.Proiectarea algoritmilor Numărul de repetări ale ciclului WHILE. xn în două subşiruri în raport cu o valoare dată a. Tehnica greedy 4. Dacă a este mai mare ca orice element al şirului atunci se returnează n+1. Algoritmul returnează valoarea indicelui pentru care începe ce de-al doilea subşir. este prezentat mai sus. x2. Să se găsească un algoritm rapid pentru separarea elementelor unui şir de numere x1. iar şirul nu se modifică. el va fi luat în consideraţie o singură dată.. x2. Cele două subşiruri vor fi: x1. || || x j ← m 4. a ) i ←1 j←n WHILE i < j || WHILE ( xi < a ) AND (i < n ) || || i ← i + 1 || WHILE x j ≥ a AND ( j > 1) ( ) || || j ← j − 1 || IF i < j || || m ← xi || || xi ← x j IF (i = n ) AND (a > xn ) || i ← n + 1 RETURN i Vom folosi tehnica de partiţionare a unui şir prezentată în cadrul metodei de sortare Quiksort. Rezolvare sep _ sir ( x. Algoritmul.131 - ... x2. datorită faptului ca a poate fi oarecare..xn. notat cu m.. Atunci când un număr prim se repetă. Dacă a este mai mic ca orice element al şirului atunci se returnează 1.. Valorile mai mici ca a sunt în primul subşir.xi-1 şi xi. Exerciţii suplimentare .. este dat de inegalitatea: a −b a −b a −b < ε ⇒ 2m > ⇔ m > lg m ε ε 2 Rezultă o complexitate logaritmică în raport cu precizia impusă procesului de calcul.. iar cele mai mari sau egale cu sunt în cel de-al doilea..xn.1.. adaptat. iar şirul nu se modifică. Să se calculeze suma componentelor prime din şirul de numere naturale x1. xi+1. n. 3.

este mai bine să sortăm şirul de intrare. 4. rezultă imediat că servirea în ordinea crescătoare a timpilor de servire conduce la timpi totali de aşteptare mai mici. Rezolvare O primă variantă de rezolvare este utilizarea forţei brute: generarea tuturor variantelor de servire şi alegerea variantei în care timpul total de aşteptare este minim. fiind indiferentă ordinea în acest caz. Să se scrie un algoritm care să stabilească timpul minim de aşteptare şi ordinea servirii în acest caz. Întrucât timpii de aşteptare pentru clienţii serviţi la urmă cuprind timpi de servire pentru clienţii din faţă. suma _ prime( x. într-o variantă de servire oarecare. 1. Dacă ar fi serviţi întâi clienţii cu timpi de servire mari. n) sortare( x. De remarcat că sortarea se poate face în ordine crescătoare sau descrescătoare. aceşti timpi s-ar aduna la timpii de aşteptare pentru toţi clienţii. Timpul de servire necesar fiecărui client este cunoscut în prealabil: pentru clientul i este necesar un timp ti. pentru a evita căutarea repetată în şirul selectat. O singura staţie de servire (de exemplu pompa de benzina) trebuie sa satisfacă cererile a n clienţi. rezultând un timp de calcul factorial.132 - .3. Timpul total de aşteptare. 1 i n.2. n) IF prim( x1 ) || S ← x1 ELSE || S ← 0 i←2 WHILE i ≤ n || IF ( xi ≠ xi −1 ) AND prim( xi ) || || S ← S + xi || i ← i + 1 RETURN S O procedură pentru verificarea unui număr că este prim sau nu a fost prezentată în exemplul de la pct. va fi: Ta = ∑ t ai = ∑ ∑ ti i =1 i =1 k =1 n n i Suma după k în relaţia de mai sus se face în ordinea servirii. Exerciţii suplimentare .Proiectarea algoritmilor Rezolvare Deoarece trebuie eliminate dublurile. Aplicarea metodei „forţa brută” conduce la evaluarea timpilor de aşteptare în n! situaţii.

i=1. Similar dacă toţi ai < 0.. b. n || || IF pm < ai ⋅ bk || || || pm = ai ⋅ bk || E ← E + pm RETURN E De remarcat că dacă toţi ai > 0. unde n > m şi x Є {b .Proiectarea algoritmilor Algoritmul care ţine seama de ordinea de servire este prezentat mai jos: servire(t . n) sortare(t . Să se determine valoarea maximă a expresiei.133 - . + a x m 1 1 2 2 pentru valorile x din mulţimea B= {b . sum _ prod (a. n) | sortare crescatoare dupa timpii de servire Ta ← 0 | initializare timp total de asteptare FOR i = 1. n) E ←0 FOR i = 1..2.m atunci va fi ales o singură valoare din B. b …. m || pm ← ai ⋅ b1 || FOR k = 2.m. Pentru fiecare valoare a lui a vom alege o valoare din mulţimea B care să maximizeze produsul.a …. i=1. 1 2 n 1 2 | calcul timp de asteptare a .3. E = a x + a x + ….. Exerciţii suplimentare .b } n i 1 2 n i 1 2 m m Rezolvare Întrucât produsele ai·xi sunt independente. b … b }. b .. Se dau n numere întregi nenule b .. n || FOR k = 1.… . i || || Ta ← Ta + t k RETURN Ta 4. vom obţine maximul sumei ca suma maximelor produselor.. m.2. b şi m numere întregi nenule a .

3 x 40.Proiectarea algoritmilor 5. Să se stabilească succesiunea optimă de înmulţire a matricelor A. j + pi −1 ⋅ pk ⋅ p j daca i < j ⎪ i≤k < j ⎩ Rezultatele acestui calcul le trecem în matricea c: ( ) Exerciţii suplimentare .D.C. În varianta b aplicăm tehnica programării dinamice şi utilizăm relaţia de recurenţă pentru determinarea succesiunii optime a produsului de matrice. 90 x 3. Tehnica programării dinamice 5. Valoarea optimă este poz.B.E de dimensiuni 10 x 5. Numărul de înmulţiri pentru produsul matricelor i. Parantezare Nr.134 - .. Tehnica forţei brute – studierea tuturor combinaţiilor de efectuare a înmulţirilor şi alegerea alelei variante în care numărul de înmulţiri este mai mic b. 13. 40 x 2. Rezolvare Avem două variante de rezolvare: a. 5 x 90. înmulţiri 1 ((((AB)C)D)E) 9200 2 ((AB)((CD)E)) 24300 3 ((AB)(C(DE))) 7080 3 (((AB)(CD))E) 52100 4 (((AB)C)(DE)) 7500 5 ((A(BC))(DE)) 1800 6 (((A(BC))D)E) 3500 7 (A(((BC)D)E)) 2450 8 ((A((BC)D))E) 4750 9 ((A(B(CD)))E) 31600 11 (A((B(CD))E)) 29300 12 (A(B((CD)E))) 19000 13 (A((BC)(DE))) 1720 14 (A(B(C(DE)))) 1780 Pentru calculul acestor variante au fost necesare 14·8=112 înmulţiri +14·3=42 adunări.1. cu numărul minim de înmulţiri 1720.j. În prima variantă numărul de variante de grupare este dată de: 1 n 1 1 4 K (n) = ⋅ C 2⋅−n −1) = ⋅ C8 = 14 ( n 5 Rezultă variantele: Nr. Aplicarea tehnicii programării dinamice şi stabilirea succesiunii optime de efectuare a înmulţirilor. 0 daca i = j ⎧ ⎪ cij = ⎨ min cik + ck +1.

1350+5·3·40} = = min{28800. adică după care matrice. c13+c44+ p0·p3·p4} = min{1950 + 10·5·40. c13+c45+ p0·p3·p5.3500}=1720 s15=1 Valoarea optimă este c15 = 1720 înmulţiri. p2. c12+c34+ p0·p2·p4. c12+c33+ p0·p2·p3} = min{1350+10·5·3.pentru gruparea 1-5. c24+c55+ p1·p4·p5} = min{780 + 5·90·2. Parantezarea optimă se obţine din matricea s: .135 - .2. c14+c55+ p0·p4·p5} = min{1620 + 10·5·2.1620. p4.7200}=1500 s13=1 c24 = min{c22+c34+p1·p2·p4.40.1950+5·40·2} = min{1680. p3.2700+10·40·2} = = min{1720.51300. paranteza este după matricea 1 (s15=1) – A(BCDE) . Calculul termenilor din matricea c: Se calculează direct termenii situaţi imediat deasupra diagonalei: s12=1 c12 = 10·5·90=4500 s23=2 c23 = 5·90·3 = 1350 s34=3 c34 = 90·3·40=10800 s45=4 c45 = 3·40·2= 240 Termenii următori se calculează utilizând relaţia de recurenţă: c13 = min{c11+c23+p0·p1·p3. Valorile lui s sunt valorile optime ale lui k din relaţia de recurenţă şi indică cum se împarte gruparea respectivă. p1.7080. c23+c45+ p1·p3·p5. paranteza este după matricea 3 (s25=3) – A((BC)(DE)) Numărul de înmulţiri efectuate pentru obţinerea soluţiei optime: 20·2=40 Exerciţii suplimentare . p5 sunt date de dimensiunile matricelor: 10. 4500+ 780 + 10·90·2.Proiectarea algoritmilor ⎡0 4500 1500 2700 1720⎤ ⎢ 0 1350 1950 1620⎥ ⎢ ⎥ c=⎢ 0 10800 780 ⎥ ⎢ ⎥ 0 240 ⎥ ⎢ ⎢ 0 ⎥ ⎣ ⎦ ⎡0 1 1 3 1 ⎤ ⎢ 0 2 3 3⎥ ⎢ ⎥ s=⎢ 0 3 3⎥ ⎢ ⎥ 0 4⎥ ⎢ ⎢ 0⎥ ⎣ ⎦ Mărimile p0.2700}=2700 s14=3 c35 = min{c33+c45+p2·p3·p5. numărată din stânga.5.90.pentru gruparea 2-5.18000}=780 s35=3 c25 = min{c22+c35+p1·p2·p5. Simultan vom completa şi matricea s. c23+c44+ p1·p3·p4} = min{10800+5·90·40. c12+c35+ p0·p2·p5.2350}=1620 s25=3 c15 = min{c11+c25+p0·p1·p5. 1350+ 240 + 5·3·2.1500+240+10·3·2. se pune paranteza.4500+10·90·3} = = min{1500.3. c34+c55+ p2·p4·p5} = min{240+90·3·2.1950}=1950 s24=3 c14 = min{c11+c24+p0·p1·p4.1500+10·3·40} = min{3950. 4500+ 10800 + 10·90·40.10800+90·40·2} = = min{780.1800.

...Proiectarea algoritmilor Numărul de adunări: 20 Se constată că soluţia optimă obţinută prin cele două metode este aceeaşi.n..n. [x] reprezintă partea întreagă a valorii x. i=1... iar greutatea totală ∑ g i ⋅ xi să fie i =1 n cel mult egală cu greutatea maximă pe care o poate căra hoţul. i=1... n j − pentru care se obtine mimiul pt. 1.. În final se obţin valorile xi. Vi . i=1.2.2. Să se stabilească selecţia optimă de produse astfel încât valoarea să fie maximă. ⎣ gi ⎦⎭ ⎩ ⎡ j ⎤ ⎢ ⎥ ≤ ai ⎣ gi ⎦ j = 0.3. n Împărţim greutatea totală G în 10 coloane.2. Dik=0. k=0.1.... k − j + vi ⋅ ⎢ ⎥ ⎬.2. Exerciţii suplimentare . fiecare coloană însemnând 1 kg.. Un hoţ pătrunde într-un magazin şi poate fura n produse cu valorile vi . Iniţial Vik=-∞.. xi.. 3. k = ⎢ ⎥ ⋅ g i . Se va rezolva problema pentru n=5. G.136 - .n şi greutăţile gi.m. a=(2..2..2. g=(4 2 1 5 3) [kg/buc].. ⎢ ⎥ ≤ a1 ⎣ g1 ⎦ ⎣ g1 ⎦ ⎧ ⎡ j ⎤⎫ Vi .. m=G/1=10. Vom construi matricea valorilor V şi matricea deciziilor D de dimensiuni n x (m+1).1. k ⎡ j⎤ Di .2.. i = 1. k = max ⎨Vi −1.. ⎣ gi ⎦ i = 2.n. Numărul de produse de fiecare tip. k = ⎢ ⎥ ⋅ v1 ⎣ g1 ⎦ ⎡k ⎤ ⎡k ⎤ D1.1.. Rezolvare Modelul matematic al problemei de optimizare este: f = ∑ vi ⋅ xi = max! i =1 n ∑ g i ⋅ xi ≤ G i =1 n 0 ≤ xi ≤ ai . k = ⎢ ⎥ ⋅ g1 . G=10 kg.n afle în magazin sunt ai. i=1.n-1. 5.... v = (7 4 3 9 2) [mil. lei/buc]. i=n. însă volumul de calcule este semnificativ mai mic prin programarea dinamică (40+20=60 < < 112+42= 154 operaţii).. i=1. 5. Relaţiile de recurenţă sunt: ⎡k ⎤ V1.. k În relaţiile de mai sus.2.. 3) [buc]...

. m ⎣4⎦ ⎣ g1 ⎦ V1 = (0 0 0 0 7 7 7 7 14 14 14 ) ⎡k⎤ ⎡k ⎤ ⎡k ⎤ D1.1.1..Proiectarea algoritmilor xn = 1 ⋅ Dn. k = ⎢ ⎥ ⋅ v1 = ⎢ ⎥ ⋅ 7. i i = n − 1.. m Prin aplicarea relaţiei iterative.. k = ⎡ j ⎤ ⎢ ⎥ ≤ a2 ⎣ g2 ⎦ max ⎨V1. n − 2. k = 0.0 = V1.1 1 ⋅ Di . l i gi f max = Vn. ⎢ ⎥ ≤ 2 ⎣4⎦ ⎣4⎦ ⎣ g1 ⎦ D1 = (0 0 0 0 4 4 4 4 8 8 8) V2. 0 = 0 Exerciţii suplimentare ...2.. m.137 - .2.. k = 0... ⎣ ⎦⎭ ⎩ ⎣ ⎦ ⎩ ⎭ ⎡ j⎤ ⎢ 2 ⎥ ≤3 ⎣ ⎦ ⎧ ⎡ j ⎤⎫ ⎧ ⎡ j ⎤⎫ j = 0.. k ⎡0⎤ V2.. k = ⎢ ⎥ ⋅ g1 = ⎢ ⎥ ⋅ 4. k − j + v2 ⋅ ⎢ g 2 ⎥ ⎬ = max ⎨V1.0 + 4 ⋅ ⎢ ⎥ = 0 ⎣2⎦ D2 .1. k − j + 4 ⋅ ⎢ 2 ⎥ ⎬.. rezultă matricele V şi D: ⎡0 ⎢0 ⎢ V = ⎢0 ⎢ ⎢0 ⎢0 ⎣ ⎡0 ⎢0 ⎢ D = ⎢0 ⎢ ⎢0 ⎢0 ⎣ 0 0 0 7 7 7 7 14 14 14 ⎤ 15 15 19 ⎥ ⎥ 15 18 19 ⎥ ⎥ 16 18 20⎥ 16 18 20⎥ ⎦ 8 8⎤ 4 6⎥ ⎥ 1 0⎥ ⎥ 0 5⎥ 0 0⎥ ⎦ 0 4 4 8 8 12 12 3 4 7 8 11 12 15 3 4 7 8 11 12 15 3 4 7 8 11 12 15 0 0 0 4 4 4 4 8 0 2 2 4 4 6 6 4 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 Detalierea calculului iterativ ⎡k ⎤ ⎡k ⎤ V1.. m gn k =n li −1 = xi = ∑ xk ⋅ g k .

4 V2.1. 2 = max ⎨V1.0 + 4. ⎣ 2 ⎦⎭ ⎩ ⎡ j⎤ ⎢ 2 ⎥ ≤3 ⎣ ⎦ j = 0.3.5 = 2 ⋅ ⎢ ⎥ = 4 ⎣2⎦ ⎧ ⎡ j ⎤⎫ V2.4.0 + 4.0 + 12} = 12 ⎡6⎤ D2.2.2.3 = max ⎨V1.138 - . 4 − j + 4 ⋅ ⎢ ⎥ ⎬.1 ⎧ ⎡ j ⎤⎫ V2.0 + 0} = 0 D2.3 V2.6 − j + 4 ⋅ ⎢ ⎥ ⎬.4.1.0 + 4} = 4 ⎡2⎤ D2.7 + 0. 4 = max ⎨V1.1 = max ⎨V1.1.3 = 2 ⋅ ⎢ ⎥ = 2 ⎣2⎦ ⎧ ⎡ j ⎤⎫ V2.0 + 4.1.0 + 0.0 + 8} = 8 ⎡4⎤ D2.0 + 8} = 8 ⎡4⎤ D2.6 = max ⎨V1.0 + 4.Proiectarea algoritmilor ⎧ ⎡ j ⎤⎫ V2.0 + 8. ⎣ 2 ⎦⎭ ⎩ ⎡ j⎤ V2. ⎣ 2 ⎦⎭ ⎩ ⎡ j⎤ ⎢ 2 ⎥ ≤3 ⎣ ⎦ ⎢ 2 ⎥ ≤3 ⎣ ⎦ j = 0.3.0 + 8. 2 = max{0 + 0.0 + 4. ⎣ 2 ⎦⎭ ⎩ ⎡ j⎤ ⎢ 2 ⎥ ≤3 ⎣ ⎦ j = 0.2.0 + 0.1 = 0 ⎢ 2 ⎥ ≤3 ⎣ ⎦ j = 0.3 = max{0 + 0.2.0 + 4. 4 = max{7 + 0. ⎣ 2 ⎦⎭ ⎩ ⎡ j⎤ V2.2 − j + 4 ⋅ ⎢ ⎥ ⎬.3 − j + 4 ⋅ ⎢ ⎥ ⎬.1 = max{0 + 0.5 − j + 4 ⋅ ⎢ ⎥ ⎬.1.6 = max{7 + 0. ⎣ 2 ⎦⎭ ⎩ ⎡ j⎤ ⎢ 2 ⎥ ≤3 ⎣ ⎦ j = 0.2 j = 0.5.3.1− j + 4 ⋅ ⎢ ⎥ ⎬.0 + 8.7 + 0.7 + 4.5 V2. 2 = 2 ⋅ ⎢ ⎥ = 2 ⎣2⎦ ⎧ ⎡ j ⎤⎫ V2. 4 = 2 ⋅ ⎢ ⎥ = 4 ⎣2⎦ ⎧ ⎡ j ⎤⎫ V2.0 + 0.0 + 4} = 4 ⎡2⎤ D2 .6 = 2 ⋅ ⎢ ⎥ = 6 ⎣2⎦ Exerciţii suplimentare .6 V2.5 = max{7 + 0.5 = max ⎨V1.

7 + 12} = 19 14 ⎡6⎤ D2.6 V2.4.7 + 0.8 − j + 4 ⋅ ⎢ ⎥ ⎬.5.10 = 2 ⋅ ⎢ ⎥ = 6 ⎣2⎦ Se continuă cu liniile următoare.8 = max ⎨V1.2.2.5.4. ⎣ 2 ⎦⎭ ⎩ ⎡ j⎤ ⎢ 2 ⎥ ≤3 ⎣ ⎦ j = 0.7 + 4.7 + 4. ⎣ 2 ⎦⎭ ⎩ ⎡ j⎤ ⎢ 2 ⎥ ≤3 ⎣ ⎦ j = 0.9 = max{ + 0.1.7 + 0.10 − 0 5 x4 = = =1 5 g4 Pentru x3 ne deplasăm pe linia 3 din D cu g4·x4=5 coloane la stânga: D3.14 + 4.7 + 4.Proiectarea algoritmilor ⎧ ⎡ j ⎤⎫ V2.139 - .7 = 2 ⋅ ⎢ ⎥ = 6 ⎣2⎦ ⎧ ⎡ j ⎤⎫ V2.9 = 2 ⋅ ⎢ ⎥ = 4 ⎣2⎦ ⎧ ⎡ j ⎤⎫ V2.0 + 8.8 = max{ + 0.7 − j + 4 ⋅ ⎢ ⎥ ⎬.9 − j + 4 ⋅ ⎢ ⎥ ⎬.7 = max{7 + 0.10 = max{ + 0. m D5. ⎣ 2 ⎦⎭ ⎩ ⎡ j⎤ ⎢ 2 ⎥ ≤3 ⎣ ⎦ j = 0. în mod asemănător.7 + 4.7 + 4.4.0 + 12} = 12 ⎡6⎤ D2. Dn.14 + 0.0 + 12} = 15 14 ⎡4⎤ D2.5.7 + 8.2.7 + 8.9 = max ⎨V1.6 V2.10 0 x5 = = = =0 3 3 g5 Pentru x4 ne deplasăm pe linia 4 din D cu g5·x5=0 coloane la stânga: D4.0 + 8.7 + 8.3.10 − 5 1 x3 = = =1 1 g3 Pentru x2 ne deplasăm pe linia 2 din D cu g3·x3=1 coloane la stânga: Exerciţii suplimentare . ţinând seama de faptul că o coloană înseamnă 1 kg.1.2.14 + 0. Soluţia optimă se obţine din tabloul D.7 + 8.3.1.7 + 4.7 + 4. ⎣ 2 ⎦⎭ ⎩ ⎡ j⎤ ⎢ 2 ⎥ ≤3 ⎣ ⎦ j = 0.4.6 V2.7 = max ⎨V1.3.7 + 8.0 + 12} = 15 14 ⎡4⎤ D2.8 = 2 ⋅ ⎢ ⎥ = 4 ⎣2⎦ ⎧ ⎡ j ⎤⎫ V2.10 − j + 4 ⋅ ⎢ ⎥ ⎬.0 + 8.5.6 V2.1.3.10 = max ⎨V1.

f=x3·v3+ x2·v2+ x5·v5=1·3+3·4+1·2=17 < 20. x5=1 (3 kg).140 - . Exerciţii suplimentare . Dacă aplicăm tehnica greedy alegerea s-ar fi făcut în ordinea crescătoare a valorii raportată la greutate. x1 – nu pot fi luate întrucât se depăşeşte greutatea totală.Proiectarea algoritmilor x2 = D2.5 −1 g2 = 4 =2 2 Pentru x1 ne deplasăm pe linia 1 din D cu g2·x2=4 coloane la stânga: D1.m=V5. 4 − 4 0 x1 = = =0 4 g1 Vom avea în final: x5=0 x4=1 x3=1 x2=2 x1=0 Valoarea optimă este dată de Vn. vi/gi =(7/4 2 3 9/5 2/3) rezultând: x3 = 1 (1 kg) x2=3 (2·3=6 kg). x4.10=fmax=20 Verificare Greutatea G=0·4+2·2+1·1+1·5+0·3=10 f=0·7+2·4+1·3+1·9+0·2=20 Obs.

Cormen. O perspectivă C++. Editura Libris.Introduction to Algorithms.E. C. Daniela Zaharie – Algoritmică. M. Universitatea de Vest Timişoara.141 - .Algorithms. R. Ilie Gârbacea – Algoritmi fundamentali. Rivest. L.Information Theory.C. Leiserson. David J. Johnsonbaugh. Cluj-Napoca. Schaefer . R. H. Second Edition. McGraw-Hill Book Company. http://web. 2001 4. MacKay . T. Inference. 2004 Bibliografie . Razvan Andonie.Proiectarea algoritmilor BIBLIOGRAFIE 1.ro 2.info. 1995 3. The Massachusetts Institute of Technology. 2005. Stein .uvt. and Learning Algorithms. Pearson Education. Cambridge University Press 2003 5. C.

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->