Biblioteca
Tutora
BibliotecaInformatică și TIC › clasa a IX-a

Metode de programare – introducere

Prezentarea unor metode elementare de rezolvare a problemelor: metoda forței brute și metoda greedy la nivel introductiv.

Bacalaureat

De la problemă la metodă: de ce nu ajunge o singură rețetă

Până acum ai scris algoritmi punctuali: suma cifrelor, minimul unui vector. O metodă de programare este un nivel deasupra: o strategie generală de atac, aplicabilă unei familii întregi de probleme. Când primești o problemă nouă, întrebarea corectă nu este „ce instrucțiuni scriu?”, ci „ce tip de strategie se potrivește?”.

Cele trei strategii studiate în clasa a IX-a, la nivel introductiv:

Diferența dintre ele nu este de sintaxă, ci de garanții și cost: forța brută găsește sigur soluția, dar poate dura enorm; greedy este rapid, dar nu întotdeauna corect; divide et impera este rapid și corect, dar se aplică doar problemelor care se lasă sparte natural în bucăți.

La examen, recunoașterea metodei dintr-un algoritm dat este o cerință în sine — de aceea merită să reții pentru fiecare metodă tiparul ei, nu doar un exemplu memorizat.

Metoda forței brute: generează și verifică

Forța brută (căutarea exhaustivă) parcurge tot spațiul soluțiilor posibile și testează fiecare candidat. Schema generală: pentru fiecare candidat posibil, dacă îndeplinește condițiile problemei, îl reții sau îl afișezi.

Exemple tipice pentru clasa a IX-a:

Avantajele: corectitudine garantată (nu ai cum să ratezi soluția dacă verifici tot) și simplitate — algoritmul se scrie ușor și e ușor de demonstrat.

Dezavantajul decisiv: explozia numărului de candidați. Pentru perechi ai n la pătrat candidați, pentru triplete n la cub; la n = 1000, tripletele înseamnă deja un miliard de verificări. De aceea forța brută este mereu punctul de plecare — soluția de siguranță — iar restul metodelor există tocmai ca să evite parcurgerea întregului spațiu atunci când se poate.

Metoda Greedy: alege mereu ce pare cel mai bun acum

Greedy (lacom) construiește soluția pas cu pas: la fiecare pas alege varianta care aduce câștigul maxim în acel moment, iar alegerea făcută nu se mai revizuiește niciodată. De aici vin și viteza, și riscul metodei.

Exemplul clasic: plata unei sume cu număr minim de bancnote din sistemul 1, 5, 10, 50, 100. Strategia: ia mereu cea mai mare bancnotă care încape în suma rămasă. Pentru 130 alegi 100, apoi 10, 10, 10 — patru bancnote, optim.

Alte aplicații standard: problema spectacolelor (alegerea numărului maxim de spectacole care nu se suprapun, ordonându-le după ora de încheiere) și amestecuri de tip maximizarea sumei: alegi cele mai mari k elemente dintr-un vector sortat.

Partea critică, cerută explicit la teorie: greedy nu garantează întotdeauna optimul. Alegerea local optimă poate bloca soluția global optimă. Contraexemplul canonic: cu bancnote de 1, 3 și 4, pentru suma 6 greedy alege 4 + 1 + 1 (trei bancnote), deși optimul este 3 + 3 (două). Metoda dă optimul doar pentru probleme cu o anumită structură — iar la nivelul clasei a IX-a reții că fiecare aplicare greedy trebuie justificată, nu presupusă corectă.

Tiparul recunoscut la examen: sortare după un criteriu + parcurgere cu alegeri definitive = aproape sigur greedy.

Divide et Impera: împarte și stăpânește

Divide et impera rezolvă o problemă în trei timpi:

Exemplul emblematic la acest nivel: căutarea binară într-un vector sortat. Compari valoarea căutată cu elementul din mijloc: dacă e egală, ai terminat; dacă e mai mică, repeți căutarea doar în jumătatea stângă; altfel doar în dreapta. La fiecare pas dimensiunea se înjumătățește, deci într-un vector cu un milion de elemente ajung circa 20 de comparații — față de un milion la căutarea secvențială. Condiția de aplicare este esențială și des uitată: vectorul trebuie să fie sortat; pe un vector neordonat căutarea binară dă rezultate greșite.

Alte exemple pe același schelet: minimul/maximul unui vector determinat prin împărțirea în două jumătăți, iar în clasele următoare sortările rapide (MergeSort, QuickSort).

Recunoașterea la examen: funcție recursivă cu parametrii stânga și dreapta (capetele unei porțiuni), care calculează mijlocul și se autoapelează pe jumătăți — acesta e tiparul divide et impera.

Cât de repede merge? Primele noțiuni de eficiență

Doi algoritmi corecți pot diferi enorm în timpul de execuție. Eficiența se estimează numărând operațiile dominante (comparații, atribuiri repetate) în funcție de dimensiunea datelor n — nu cronometrând pe un calculator anume.

Ordinele de mărime pe care trebuie să le recunoști:

Două comparații care fixează intuiția: căutarea binară (logaritmică) bate zdrobitor căutarea secvențială (liniară), dar cere vector sortat; iar un algoritm liniar isteț bate unul pătratic naiv de îndată ce n depășește câteva mii.

Morala practică, în spiritul subiectelor de examen care cer „algoritm eficient”: eficiența se câștigă din idee (alt algoritm, altă metodă), nu din cosmetizarea codului. A muta o instrucțiune sau a redenumi variabile nu schimbă ordinul de mărime; a înlocui generarea tuturor perechilor cu o parcurgere unică, da.

De reținut

metodă de programare
strategie generală de rezolvare aplicabilă unei familii de probleme, precum forța brută, greedy sau divide et impera
forța brută (căutare exhaustivă)
metoda care generează toate soluțiile candidate și o verifică pe fiecare; garantează corectitudinea, dar poate fi foarte lentă
metoda greedy
metoda care construiește soluția pas cu pas, alegând la fiecare pas varianta optimă local, fără a reveni asupra alegerilor făcute
optim local vs. optim global
alegerea cea mai bună la pasul curent (local) nu conduce întotdeauna la cea mai bună soluție de ansamblu (global) — de aceea greedy nu garantează mereu optimul
divide et impera
metoda care împarte problema în subprobleme de același tip mai mici, le rezolvă recursiv și combină rezultatele
căutare binară
căutarea într-un vector sortat prin compararea cu elementul din mijloc și continuarea doar în jumătatea care poate conține valoarea
caz de bază
subproblema suficient de mică pentru a fi rezolvată direct, la care se opresc apelurile recursive ale metodei divide et impera
algoritm liniar
algoritm al cărui număr de operații crește proporțional cu dimensiunea n a datelor, de exemplu o singură parcurgere a unui vector
algoritm pătratic
algoritm cu două bucle imbricate pe datele de intrare, al cărui timp crește de patru ori la dublarea lui n, precum sortările elementare
algoritm logaritmic
algoritm care reduce dimensiunea problemei la jumătate la fiecare pas, precum căutarea binară; numărul de pași rămâne mic chiar pentru n foarte mare

Greșeli frecvente

Greșit: Greedy ar garanta întotdeauna soluția optimă
Corect: Greedy garantează doar rapiditate; optimul depinde de structura problemei — cu bancnote de 1, 3, 4 și suma 6, greedy dă trei bancnote (4+1+1), deși optimul e două (3+3)
Greșit: Căutarea binară s-ar putea aplica pe orice vector
Corect: Căutarea binară funcționează numai pe vectori sortați; pe un vector neordonat compararea cu mijlocul elimină jumătăți care pot conține chiar valoarea căutată
Greșit: Pentru a verifica dacă n este prim ar trebui testați toți divizorii până la n-1
Corect: E suficient până la radical din n: dacă n = a·b cu a <= b, atunci a <= radical din n; testarea până la n-1 e corectă, dar inutil de lentă și punctată ca ineficientă la cerințele de eficiență
Greșit: Un algoritm care merge repede pe un exemplu mic ar fi eficient
Corect: Eficiența se judecă după creșterea numărului de operații cu n: un algoritm pătratic pare rapid la n = 100, dar devine inutilizabil la n = 1.000.000, unde unul liniar sau logaritmic rămâne instantaneu
Greșit: Divide et impera ar însemna orice împărțire a programului în funcții
Corect: Metoda cere subprobleme de același tip cu problema inițială, rezolvate de regulă recursiv și combinate; simpla organizare a codului în subprograme este proiectare modulară, nu divide et impera

Test — 6 întrebări ca la examen

1. Un algoritm care generează toate perechile (i, j) dintr-un vector și verifică fiecare pereche folosește metoda:
  1. greedy
  2. divide et impera
  3. forței brute
  4. programării dinamice
Vezi răspunsul
forței brute. Generarea și verificarea tuturor candidaților este exact definiția forței brute. Greedy — distractorul frecvent — nu generează tot, ci face la fiecare pas o singură alegere definitivă, fără să exploreze restul variantelor.
2. Plătind suma 130 cu bancnote de 100, 50, 10, 5, 1 prin strategia „ia mereu cea mai mare bancnotă care încape”, câte bancnote folosești?
  1. 3
  2. 4
  3. 5
  4. 2
Vezi răspunsul
4. 100 + 10 + 10 + 10 = 130, deci patru bancnote. Varianta 3 e capcana pentru cei care presupun că există o bancnotă de 30 sau combină 100 + 50 uitând că 150 depășește suma; greedy ia 100, apoi de trei ori 10.
3. Care condiție este obligatorie pentru aplicarea căutării binare într-un vector?
  1. vectorul să aibă un număr par de elemente
  2. vectorul să fie sortat
  3. vectorul să conțină doar numere pozitive
  4. vectorul să nu conțină elemente egale
Vezi răspunsul
vectorul să fie sortat. Doar într-un vector sortat compararea cu elementul din mijloc permite eliminarea sigură a unei jumătăți. Numărul de elemente, semnul valorilor sau duplicatele nu împiedică metoda — distractorii mizează pe detalii care par tehnice, dar sunt irelevante.
4. Într-un vector sortat cu 1024 de elemente, căutarea binară face în cazul cel mai defavorabil aproximativ:
  1. 1024 de comparații
  2. 512 comparații
  3. 10 comparații
  4. 2 comparații
Vezi răspunsul
10 comparații. La fiecare pas dimensiunea se înjumătățește: 1024 → 512 → ... → 1, adică 10 pași (2 la puterea 10 = 1024). Varianta 512 e tentantă pentru că înjumătățește o singură dată; 1024 descrie căutarea secvențială, nu binară.
5. Cu bancnote de 1, 3 și 4, pentru suma 6, strategia greedy „cea mai mare bancnotă mai întâi” dă:
  1. soluția optimă, 2 bancnote
  2. 3 bancnote, deși optimul este 2
  3. 2 bancnote, deși optimul este 3
  4. nicio soluție
Vezi răspunsul
3 bancnote, deși optimul este 2. Greedy alege 4, apoi 1 și 1 — trei bancnote; optimul este 3 + 3, două bancnote. Este contraexemplul standard care arată că alegerea optimă local poate rata optimul global; prima variantă e capcana pentru cine crede că greedy e mereu corect.
6. Pentru a verifica eficient dacă numărul natural n > 1 este prim, este suficient să îi cauți divizori proprii:
  1. de la 2 până la n - 1
  2. de la 2 până la n / 2
  3. de la 2 până la radical din n
  4. doar printre numerele impare
Vezi răspunsul
de la 2 până la radical din n. Dacă n = a·b cu a <= b, atunci a <= radical din n, deci orice număr compus are un divizor cel mult egal cu radicalul său. Varianta n/2 e corectă logic, dar mult mai lentă — la cerințele de eficiență se punctează limita radical; iar testarea doar a imparelor ratează divizorul 2.
Deschide varianta interactivă — cu AI care îți explică
← SubprogrameSisteme de calcul →
BiologieChimieEconomieFilosofieFizicăGeografieInformatică și TICIstorieLogică și argumentareMatematicăPsihologieLimba și literatura română