Sunteți pe pagina 1din 9

Algoritmi de cutare

n informatic exist algoritmi care rezolv diferite probleme cu o singur soluie. Aa cum am vzut n semestrul I. Dar n diferite domenii exist i alte probleme care au mai multe soluii, una din ele fiind optimal. La fel pot fi i mai multe soluii optimale. Algoritmii care urmeaz rezolv aceste probleme. Cei mai cunoscui algoritmi sunt: 1. 2. 3. 4. 5. 6. 7. 8. Greedy (lacom) Backtracking (cu revenire) Programare dinamic Branch and Bound (ramific i mrginete) Divide et Impera (divide i stpnete) Algoritmi euristici (situaii concrete) Algoritmi probabilistici Algoritmi genetici

Greedy
Problem prototip: Maxim n drum spre Italia nimerete pe o insul pustie unde gsete o barc micu i mai multe buci de metale preioase. Maxim vrea s ctige ct mai mult i ncarc n barc mai nti bucile din metalul cel mai preios. ncarc ct e posibil n barc, dup care continu cu bucile mai puin preioase pn cnd se va umple barca. Comportamentul su e asemenea unui om lacom. Problem rezolvat: Mihai se va angaja pe var ca vnztor unde va trebui s dea restul cu un numr minimal de monede, avnd la dispoziie un numr nelimitat de monede de 50, 25, 10, 5 i 1 ban. Exemplu: Fie suma S=137, Mihai va returna: 2 monede de 50, 1 moned de 25, 1 de 10 i 2 de 1. Program:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. /** * Name: Algoritm Greedy. Numar de monede minim */ #include <stdio.h> #include <conio.h> int main() { int monede[2][5] = {{50, 25, 10, 5, 1}, {0, 0, 0, 0, 0}}, suma, s, i, n; printf("Introdu suma:\n"); scanf("%d", &suma); s = suma; i = 0; do { monede[1][i] = s/monede[0][i]; s = s%monede[0][i];

19. 20. 21. 22. 23. 24. 25.

i++; } while(s); printf("Moneda | Numar\n"); for(i=0; i<5; i++) if(monede[1][i]) printf("%6d | %-5d\n", monede[0][i], monede[1][i]); getch(); return 0;

26. 27. 28. 29. }

n aceast problem algoritmul Greedy ne conduce ntotdeauna la soluia optimal. Dar s-a vzut c algoritmul dat nu ne d ntotdeauna rezultatul optimal. Rezultatul depinde de datele problemei i datele introduse. Fie un alt sistem monetar format din monede de 25, 12, 5, 1. Fie S=129. Aplicm algoritmul Greedy: 5 monede de 25 i 4 de 1, n total 9 monede. Soluia dat nu e optimal, fiindc exist alta i mai bun: 4 monede de 25, 2 de 12 i 1 de 5, n total 7 monede. Algoritmul Greedy e totui utilizat fiindc e simplu i rapid.

BackTracking
Asigur o soluie optimal. Problem prototip: Dima n vacan are un rendez-vous Ana n locul indicat n modul urmtor: se merge cu troleibuzul 10 de la str. Studenilor i se va cobor la staia unde este chioc "Xerox", dup care va merge la dreapta pe jos pn ce va gsi la urmtoarea intersecie un chioc "AKM" i va continua la stnga pn ce va ajunge la o cas cu 2 etaje i olane roii. Problem rezolvat: Dup ntoarcerea din Statele Unite, Mihai are un capital C=5000$ pe care vrea s-i investeasc ca s obin un profit. Investiie (fi) 2000 2200 2500 Beneficiu (bi) 300 400 500 Pentru a nelege aceast metod vom construi un arbore de cutare care opereaz cu noiunile: profit potenial, investiie, profit real.

si=0 pp=1200 i1=DA si=2000 pp=120 0 i2=DA si=4200 pp=1200 i3=DA X si > suma pr=700 pp=700 pp=800 i3=NU i3=DA si=4200 pr=700 prmax=700 si=4500 pr=800 prmax=800 pr=300 pp=800 i2=NU si=2000 pr=300 pp=500 i2=NU X pp<prmax pp=300 pp=900 X pp<prmax si=4700 pr=900 prmax=900 pr=0 pp=900 i1=NU si=0 pr=0 pp=900 i2=DA si=2200 pr=400 pp=400 i3=DA X pp<prmax

Algoritmul este lent i depinde foarte mult de dimensiunea problemei, dar n schimb asigur soluia optimal. Cod:
1. // Algoritmul BACKTRACKING 2. #include<conio.h> 3. #include<stdio.h> 4. #include<stdlib.h> 5. 6. #define max_oferte 10 7. #define max_sol 10 8. #define true 1 9. #define false 0 10. 11. int n, // numar de oferte 12. C, // capital 13. s[max_oferte], // solutie curenta 14. f[max_oferte], // investitii 15. b[max_oferte], // beneficii 16. sol_opt[max_sol][max_oferte], 17. i,j, 18. nsol, // numar solutii optime 19. profit_potential, 20. investitie, 21. profit_optim=0, 22. investitie_optima=0; 23. 24. void test_optim(int profit)

25. { 26. int j; 27. if (profit>profit_optim || profit == profit_optim && investitie < investitie_optima) 28. { 29. nsol=1; 30. for(j=0;j<max_oferte;j++) 31. sol_opt[nsol-1][j]=s[j]; 32. profit_optim=profit; 33. investitie_optima=investitie; 34. } 35. else 36. if (profit==profit_optim && investitie==investitie_optima) 37. { 38. nsol++; 39. for(j=0;j<max_oferte;j++) 40. sol_opt[nsol][j]=s[j]; 41. } 42. } 43. 44. void extindere(int p,int investitie,int profit_potential) 45. { 46. int profit_real; 47. if (investitie+f[p]<=C) 48. { 49. s[p]=true; 50. if(p<n-1) 51. extindere(p+1,investitie+f[p],profit_potential); 52. else 53. test_optim(profit_potential); 54. s[p]=false; 55. } 56. 57. profit_real=profit_potential-b[p]; 58. if (profit_real>=profit_optim) 59. if(p<n) 60. { 61. s[p]=false; 62. extindere(p+1,investitie,profit_real); 63. } 64. else test_optim(profit_real); 65. } 66. 67. void main() 68. { 69. char buf[30]; 70. printf("Capital="); gets(buf); 71. sscanf(buf,"%i",&C);

72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. }

printf("Numar de oferte="); gets(buf); sscanf(buf,"%i",&n); printf("Oferta Investitie Profit\n"); for(i=0;i<n;i++) { printf("%d ",i+1); gets(buf); sscanf(buf,"%i %i",&f[i],&b[i]); } profit_potential=0; for(i=0;i<n;i++) profit_potential+=b[i]; nsol=0; investitie=0; extindere(0,investitie,profit_potential); if (nsol==0) printf("Nu exista solutie\n"); else { printf("Numar de solutii optime: %i\n",nsol); printf("Profitul %d\n",profit_optim); for(i=0;i<nsol;i++) { for(j=0;j<n;j++) if(sol_opt[i][j]) printf(" %i ",f[j]); printf("\n"); } }

Programare dinamic
Asigur soluia optimal. Problema cltorului: Un cltor trebuie s ajung din oraul A n oraul B avnd la dispoziie mai multe variante de cltorie cu preuri diferite.

Dac aplicm algoritmul Greedy obinem A25B, cost 11.

Programarea dinamic presupune o analiz a drumului care mai rmne de parcurs. Vom traversa i analiza toate cile n ordine invers.

Problema triunghiului: Fie dat un triunghi cu numere. Se cere coborrea din vrful triunghiului la baz, acumulnd o sum maximal. Se va permite coborrea linie cu linie pe vertical sau la dreapta. 4 2 6 8 5 3 6 7 9 5 8 4 9 2 6 7 9 5 6 4 6 Construim triunghiul cu sume pariale i suma maximal. Se copie ultimul rnd, si in fiecare celula (i, j) scriem maxim((i,j)+(i+1, j), (i,j)+(i+1, j+1)). La sfrit n vrful triunghiului vom avea suma maxim. 39 33 35 31 29 27 23 22 24 17 17 13 15 8 12 7 9 5 6 4 6 Programul urmtor se numete triunghi i rezolv aceast problem.
1. #include<stdio.h> 2. 3. void main() 4. { 5. int i,j,n,d; 6. int f[10][10]; 7. int drum[10][10]; 8. int t[10][10]; 9. 10. printf("\ndati n \n"); 11. scanf("%d",&n); 12. printf("introdu triunghiul\n"); 13. for(i=0;i<n;i++) 14. for(j=0;j<i+1;j++) 15. scanf("%d",&t[i][j]); 16. 17. for(j=0;j<n;j++)

18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. }

{ drum[n-1][j]=j; f[n-1][j]=t[n-1][j]; } for(i=n-2;i>-1;i--) for(j=0;j<i+1;j++) if (f[i+1][j]+t[i][j] > f[i+1][j+1]+t[i][j]) { drum[i][j]=j; f[i][j]=f[i+1][j]+t[i][j]; } else { drum[i][j]=j+1; f[i][j]=f[i+1][j+1]+t[i][j]; }; printf(" FUNCTIA F\n"); printf("\n\n"); for(i=0;i<n;i++) { for(j=0;j<i+1;j++) printf(" %d",f[i][j]); printf("\n"); } printf("Suma max este %d\n",f[0][0]); printf("Drumul este\n"); d=drum[0][0]; printf("d=%d ",d); for(i=1;i<n-1;i++) { printf("%d ",drum[i][d]); d=drum[i][d]; }

Branch and Bound


Algoritmul dat e asemntor cu BackTracking , gsete soluia optimal ntotdeauna i se deosebete de el prin modul de parcurgere al arborelui de cutare. Problem prototip: Jocul Perspico presupune c pe o tabl ptrat, din 16 ptrele, sunt 15 ptrele completate cu numerele de la 1-15. Se cere aranjarea numerelor n ordine cresctoare pe rnduri, ultimul ptrel e gol. Problem: Lampa lui Dario Uri. Se consider o tabl cu 4 butoane luminoase care pot fi aprinse sau stinse prin apsare. La fiecare schimbare a strii se schimb i starea butoanelor vecine. Fiind starea iniial, toate butoanele stinse, se cere s se aprind toate. 0 0 0 0 1 1 1 0 0 1 0 1 1 0 0 0 1 1 1 1

Divide et Impera
Metoda dat garanteaz soluia optimal i se bazeaz pe principiul: descompune problema dat n subprobleme pn ce se va vedea soluia direct, care ne va conduce la soluia final. Problem prototip: S se determine un numr ntreg din diapazonul dat prin metoda dat. Problem: Turnurile din Hanoi. Se consider 3 tije a, b, c. Pe o tij sunt mbrcate discuri cu diametre diferite. Discul cu diametrul maxim de pe tij st la baz. Se cere deplasarea discurilor de pe a pe b respectnd condiiile: 1. La o micare se mut doar un disc 2. E interzis mutarea unui disc cu diametru mai mare pe unul cu diametrul mai mic. Algoritmul aplicat se bazeaz pe o funcie recursiv h(n, a, b, c). Dac n=1 ab Dac n=2 ac, ab, cb Dac n>2, problema se complic dar aplicnd strategia Divide et Impera vom descompune problema n alte 2 subprobleme pn ce nu vom ajunge la o soluie absolut simpl. Mutarea a n discuri de pe a pe b e echivalent cu: Mutarea a n-1 discuri de pe a pe c Mutarea discului rmas de pe a pe b Mutarea a n-1 discuri de pe c pe b

n baza celor expuse obinem formula recursiv ( ) { ( ) ( )

Exemplu: n=3, h(3, a, b, c)=h(2, a, c, b), ab, h(2, c, b, a)=h(1, a, b, c), ac, h(1, b, c, a), ab, h(1, c, a, b), cb, h(1, a, b, c)=ab, ac, bc, ab, ca, cb, ab.

Algoritmi Euristici
Un algoritm, se numete Euristic dac are urmtoarele proprieti: De obicei, furnizeaz soluii "bune", dar nu neaprat optimale; E uor de implementat i permite obinerea rezultatelor ntr-un timp rezonabil (n orice caz mai scurt dect n cazul altui algoritm cunoscut); Soluia apare, de multe ori, intuitiv.

Problem prototip: Fie dat o staie de alimentare cu benzin, cu n pompe care au acelai debit i m automobile care trebuie alimentate. Se cunoate durata alimentrii fiecrui automobil. Se cere alimentarea tuturor automobilelor ntr-un timp minimal. Exemplu: n=3, m=11. T={6, 14, 20, 3, 8, 15, 19, 2, 15, 15, 7} Sortm descresctor, apoi punem n ordinea: 1,2,3,3,2,1,1,2,3,3,2,1 1 2 3 20, 14, 8, 19, 15, 7, 2 15, 15, 6, 3 42 43 39

Algoritmi probabilistici
Ei nu garanteaz soluia optimal. Se aplic tradiional n cazurile cnd datele problemei in de probabilistic. Se cunosc algoritmii: Las Vegas, Monte Carlo

Algoritmi genetici
Ultimii inventai

S-ar putea să vă placă și