Transcript tehprog

Coordonator ştiinţific:
Conf. dr. CĂLIN ENĂCHESCU
Absolvent:
Farkas Sándor
INTRODUCERE
Această lucrare este un mediu educaţional pentru cei
interesaţi de teoria algoritmilor, mai precis a unei părţi
din această materie, şi anume: tehnici de programare.
Scopul acestei lucrări este să prezinte, într-o manieră
accesibilă pentru utilizatorii tehnicii de calcul, câteva
metode de programare cum ar fi: Backtracking, Divide et
Impera, Branch & Bound, Greedy şi Programare
dinamică).
Se au în vedere atât aspectele teoretice ale problemelor,
cât şi cele practice, fiecare capitol conţinând pe lângă
teorie, probleme rezolvate şi probleme propuse.
Lucrarea poate fi folosită ca suport de curs şi laborator,
fiind gândită pentru un semestru de predare. Ea poate sluji
la fel de bine ca suport de studiu individual.
Fiecare capitol este compus din patru părţi:
Prima parte este teoria generală, în care sunt
descrise ideile generale a fiecărei metode de
programare
În partea a doua sunt descrise câteva exemple
rezolvate, simulate prin Visual Café.
Partea a treia conţine problemele, care sunt
propuse celor care au înţeles ideea tehnicilor şi
stăpânesc cel puţin la nivel superficial, unul dintre
limbajele de programare în care sunt realizate
implementările.
Partea a patra este un test de verificare tip grilă,
pentru cei care doresc să-şi verifice cunoştinţele.
Conţinutul lucrării:
I. Metoda Backtracking
II. Metoda Branch and Bound
III. Metoda Divide et Impera
IV. Metoda Greedy
V. Metoda Programării dinamice
Capitolul I.
Metoda Backtracking
Această metodă de programare se foloseşte
în cazul problemelor ce îndeplinesc simultan
următoarele trei condiţii:
- soluţia lor poate fi pusă sub forma de vectori
S = x1, x2, ... , xn, cu x1 aparţinând mulţimii A1,
x2 aparţinând mulţimii A2, ..., xn aparţinând
mulţimii An ;
- mulţimile A1, A2, ... , An sunt mulţimi finite, iar
elementele lor se consideră că se află într-o
relaţie de ordine bine stabilită;
- nu se dispune de o altă soluţie mai rapidă.
Metoda Backtracking constă în următoarele:
- se alege primul element, x1, ce aparţine A1 ;
- presupunând generate elementele x1, x2, ..., xk,
aparţinând mulţimilor A1, A2, ..., Ak, se alege
(dacă există) xk+1, primul element disponibil din
multimea Ak+1 care îndeplineşte anumite condiţii
de continuare, apărând astfel două posibilităţi:
a) elementul există, se testează dacă nu
s-a ajuns la o soluţie, în caz afirmativ
aceasta se tipăreşte, în caz contrar se
consideră generate x1, x2, ..., xk, xk+1;
b) elementul nu există, situaţie în care se
consideră generate elementele x1, x2, ... ,
xk-1, reluându-se căutarea de la elementul
următor lui xk în multimea Ak ;
- algoritmul se încheie când au fost luate în
consideraţie toate elementele mulţimii A .
Ca aplicaţii ale metodei Backtracking, am prezentat
algoritmi pentru:
- generarea aranjamentelor
- generarea combinărilor
- generarea permutărilor
- generarea partiţiilor unei mulţimi
- problema plăţii unei sume s, utilizând n tipuri
de metode
Acest capitol conţine şi un subcapitol care propune
spre rezolvare câteva probleme, folosind metoda
Backtracking.
Capitolul II.
Metoda Branch and Bound
Metoda va folosi o listă în care vor fi înscrise
vârfuri ale arborelui spaţiului de stări pentru a fi
prelucrate la un moment ulterior, numite vârfuri active.
Dintre vârfurile active se alege câte un vârf
pentru a fi prelucrat, care se numeşte vârf curent.
Cunoaştem două modalităţi de parcurgere a
arborilor care respectă condiţiile enunţate şi anume
parcurgere BF (în care lista vârfurilor active are
organizare de coadă) şi D (în care lista vârfurilor active
este organizată ca stivă).
Pentru înţelegerea acestei metode se dau două
exemple, care aplică algoritmul Branch and
Bound:
- lampa lui Dario Uri
- problema macaralei
Acest capitol conţine şi un subcapitol care propune spre
rezolvare câteva probleme, folosind metoda Branch and
Bound.
Capitolul III.
Metoda Divide et Impera
Pentru clarificarea metodei presupunem că se
dă un vector A=( a1, a2 , ..., aN) şi că trebuie
efectuată o prelucrare oarecare asupra elementelor
sale. Mai mult, presupunem că pentru orice p, q
naturali cu 1  p < q  N, există mє{p, ... , q-1}, astfel
încât prelucrarea secvenţei {ap, ... , aq} se poate face
prelucrând secvenţele {ap, ... , am} şi {am+1, ... , aq}
şi apoi combinând rezultatele pentru a obţine
prelucrarea dorită a întregii secvenţe {ap, ... , aq}.
Pentru înţelegerea acestei metode se dau
câteva exemple, care aplică algoritmul Divide
et Impera:
- problema turnurilor din Hanoi
- sortarea rapidă
- sortarea prin interclasare
Acest capitol conţine şi un subcapitol care propune
spre rezolvare câteva probleme, folosind metoda
Divide et Impera.
Capitolul IV.
Metoda Greedy
Această tehnică se foloseşte în situaţia în care este
dată o mulţime A cu n elemente de intrare şi se cere să
se găsească o submulţime B a sa, care să
îndeplinească anumite condiţii pentru a fi acceptată; cum în general există mai multe astfel de mulţimi, se
mai dă şi un criteriu conform căruia dintre submulţimile
acceptabile (numite soluţii posibile) să alegem una
singură(numită soluţie optimă). Soluţiile posibile au
următoarea proprietate: dacă b este soluţie posibilă şi C
inclusă în B, atunci şi în C este soluţie posibilă; vom
presupune că este întotdeauna soluţie posibilă.
Metoda Greedy tratează acest tip de probleme în
următoarele două moduri, care urmează aceeaşi idee
dar diferă doar prin ordinea de efectuare a unor operaţii
a) Algoritmul Greedy 1
Se pleacă de la soluţia vidă, se alege pe rând, într-un
anumit fel, un element din A neales la paşii precedenţi.
Dacă adăugarea lui la soluţia parţială anterior construită
conduce la o soluţie posibilă, construim noua soluţie
posibilă prin adăugarea elementului ales.
b) Algoritmul Greedy 2
Se procedează similar, cu excepţia faptului că se
stabileşte de la început ordinea în care trebuie
considerate elementele.
Pentru o explicaţie cât mai clară a acestei metode
se dau câteva exemple, care aplică algoritmul
Greedy:
- problema comis-voiajorului
- algoritmul lui Prim
- problema tetrix
Acest capitol conţine şi un subcapitol care propune spre
rezolvare câteva probleme, folosind metoda Greedy.
Capitolul V.
Metoda programării dinamice
Programarea dinamică este o metodă de
proiectare a algoritmilor care poate fi utilizată în cazul în
care soluţia problemei poate fi privită ca rezultatul unei
succesiuni de decizii. De remarcat faptul că este posibil ca
decizia luată la un moment dat să depindă de cele luate în
etapele anterioare.
O modalitate de rezolvare a problemelor pentru
care nu este posibil să se efectueze o secvenţă de decizii
care să conducă la soluţia optimă constă în încercarea
tuturor secvenţelor posibile de decizii.
Programarea dinamică oferă posibilitatea reducerii
drastice a secvenţelor de decizii, eliminându-le pe cele
care nu conduc la soluţia optimă.
Rezolvarea unei probleme de programare dinamică se
face respectând următoarele etape:
- verificarea principiului de optimalitate în una din cele 3
forme ale sale;
- scrierea relaţiilor care apar, corespunzătoare formei în
care este verificat principiul de optimalitate;
Pentru o explicaţie cât mai clară a acestei metode
se dau câteva exemple, care aplică algoritmul
programării dinamice:
- subşir crescător de lungime maximă
- problema reconstituirii frazei
- problema tirului
Acest capitol conţine şi un subcapitol care
propune spre rezolvare câteva probleme, folosind
metoda programării dinamice.