Documente Academic
Documente Profesional
Documente Cultură
Metode Si Tehnici Clasice de Programare - Partea I
Metode Si Tehnici Clasice de Programare - Partea I
Proiect cofinanţat din Fondul Social European în cadrul POS DRU 2007-2013
Beneficiar – Centrul Naţional de Dezvoltare a Învăţământului Profesional şi Tehnic
str. Spiru Haret nr. 10-12, sector 1, Bucureşti-010176, tel. 021-3111162, fax. 021-3125498, vet@tvet.ro
2009
AUTOR:
ROMANA SĂLĂJAN – Profesor grad didactic I
COORDONATOR:
CONSULTANŢĂ:
Domeniul : Informatică
Calificarea : Analist programator
Nivelul de calificare : 3 avansat
Materialul cuprinde:
- fişe de documentare
- activităţi de învăţare
- glosar
Competenţa /
Rezultatul Teme
învăţării Elemente componente
Prezentul material de învăţare cuprinde diferite tipuri de resurse care pot fi folosite
de elevi:
- fişe de documentare
- activităţi de învăţare
Elevii pot folosi atât materialul prezent (în forma printată) cât şi varianta echivalentă
online.
Tema 1. Recursivitate- noţiuni generale
Fişa de documentare 1.1 Elementele recursivităţii
Recursivitatea este una din noţiunile fundamentale ale informaticii. Utilizarea frecventă
a recursivităţii s-a făcut după anii 80.
Definiţie
Procesul recursiv este procesul care în timpul execuţiei, generează apariţia unor
procese identice aflate în legătură directă cu procesul ce le generează. Aceste procese
pot fi finite si infinite.
Un proces recursiv finit este caracterizat printr-o acţiune care se repetă, un motor care
susţine această activitate şi o condiţie de oprire.
În cazul proceselor infinite lipseşte condiţia de oprire, acţiunea generându-se în mod
continuu.
Un proces recursiv poate fi descris printr- un subprogram.
Definiţie
Recursivitatea este un mecanism general de elaborare a programelor, care constă în
posibilitatea ca un subprogram să se autoapeleze.
A apărut din necesităţi practice date de transcrierea directă a formulelor matematice
recursive. Astăzi este utilizat în elaborarea multor algoritmi.
Sugestii metodologice
Caută exemple intuitive de procese recursive din realitatea cotidiană. De exemplu:
1. O cameră de luat vederi are în obiectiv un televizor care transmite imaginile primite
de la cameră. Evident, în televizor se va vedea un televizor iar în acesta, un
televizor…,ş.a.m.d.
Pe scurt, în orice televizor se vede un televizor.
2. În anumite restaurante întâlnim anunţul “ Azi nu se fumează “.
3. Respiraţia este un proces recursiv.
Sugestii metodologice
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să recunoşti un proces recursiv;
Durata: 10 minute
Sarcina de lucru
Care din imaginile următoare îţi sugerează procese recursive şi care procese
nerecursive?
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să determini ordinea de execuţie a apelurilor unei funcţii recursive care
are mai multe autoapeluri în corpul ei.
Să fii capabil să determini ce se memorează pe stivă de fiecare dată.
Durata: 20 minute
Tipul activităţii: Studiu de caz
Sugestii
Activitatea se poate face individual, un elev la câte un calculator, pe grupe sau în
perechi.
Sarcina de lucru
Se dă urmatorul program:
#include <iostream.h>
int v[6]=(3,5,1,8,4,9,10,12);
int impar(int n, int m)
{ if (n==m) return v[n]%2;
else return impar(n,(n+m)/2)+impar((n+m)/2+1,m);
}
void main()
{ cout<<impar(0,7);
}
Precizează ordinea de efectuare a autoapelurilor în acest caz şi valorile parametrilor
memoraţi pe stivă la fiecare nivel, indicând rezultatul obţinut.
Tema 2. Recursivitate şi iterativitate
Fişa de documentare 2.1 Algoritmi care implementează definiţii recursive
Definiţie
O definiţie recursivă este definiţia în care un obiect se defineşte prin el insuşi. Definiţia
conţine condiţia de părăsire a definiţiei şi o parte ce precizează definirea recursivă
propriu-zisă.
Definiţie
Sugestii metodologice
Aprofundează exemplele următoare, rulează-le în C++ pentru mai multe date de intrare
şi urmăreşte cu fereastra Watch ( Ctrl+F7) valorile parametrilor la fiecare apel al funcţiei
recursive.
Exemplu 1. Se dau două numere naturale a şi b.Se cere să se calculeze cel mai mare
divizor comun al lor folosind algoritmul lui Euclid.
Foloseşti definiţia recursivă a celui mai mare divizor comun pentru două numere
naturale a şi b.
a , a b
Cmmdc(a,b)=
cmmdc ( a b, b ), a
cmmdc ( a , b a ) , a
b
b
#include <iostream.h>
int cmmdc(int a,int b) {
if (a==b) return a;
else if(a>b) return cmmdc(a-b,b);
else return cmmdc(a,b-a);
}
void main(){
int a,b;
cout<<"Introduceti numerele: "; cin>>a>>b;
cout<<"cmmdc dintre "<<a<<" şi "<<b<<" este "<<cmmdc(a,b);
}
Exemplu 2.
Fie fib: N N. Să se calculeze fib(n), pentru n natural.
1, n 0
Fib(n)=
1, n 1
fib ( n 1) fib ( n 2), altfel
Exemplu 3.
Calculul funcţiei Manna-Pnueli pentru un x intreg.:
x 1, x. 12
F(x)=
F ( F ( x 2)), x 12
int manna(int x)
{ if(x>=12) return x-1;
else return manna(manna(x+2));
}
Exemplu 4.
Să se calculeze recursiv suma cifrelor unui număr natural.
Indicaţie: Se izolează ultima cifră, iar lui n i se atribuie câtul întreg dintre vechea valoare
şi 10. Astfel găsim o relaţie de recurenţă, necesară elaborării variantei recursive:
0, n 0
S(n)=
n %10 S ( n / 10), altfel
Avem programul:
#include <iostream.h>
int suma(long n){
if (n<10) return n;
else return n%10+suma(n/10);
}
void main(){
int n;
cout<<"n="; cin>>n;
cout<<"suma cifrelor este "<<suma(n);
}
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să identifici dacă o definiţie recursivă este corectă sau nu.
Durata: 10 minute
Sugestii
Activitatea se poate face individual pe caiet, sau toată clasa folosind tabla.
Sarcina de lucru
Se dau următoarele definiţii recursive:
a) f: N→ N
0 daca x 1
f(x)=
f (x 2 )
f (x) 5
daca
daca
x par
x im par
b) g: Z→Z
1 daca x 0
g(x)=
g(x - 1) 5 altfel
c) h: N→N
0 daca x 1
h(x)=
h(x - 1) 5 , altfel
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să găseşti condiţia de terminare într-un subprogram recursiv dat.
Să recunoşti principiul recursivităţii în programare şi să dobândeşti tehnica de realizare
a recursivităţii.
Durata: 10 minute
Sugestii
Activitatea se poate face individual, un elev la câte un calculator, pe grupe sau în
perechi.
Sarcina de lucru
Completează spaţiile libere din subprogramul recursiv prezentat mai jos cu o expresie
corespunzătoare, astfel încât în urma apelului f(12) să se afişeze şirul de valori:
12 6 3 1 1 3 6 12.
void f(int i)
{ if ( )
{ cout<<i<<” “;
f(12);
cout<<i<<” “;}}
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să interpretezi tehnica recursivă aplicată într-o problemă atunci când ţi se
dau datele de intrare.
Să fii capabil să determini rezultatul unui subprogram recursiv.
Durata: 10 minute
Sarcina de lucru
Se dă următorul subprogram:
void scrie (int x)
{ if (x>1)
scrie (x-2);
cout<<x%2;
}
Ce se afişează pe ecran la apelul scrie(12)?
a) 10101
b) 11111
c) 01010
d) 00000.
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să aplici tehnica recursivă la rezolvarea unei probleme atunci când ţi se dă
o definiţie recursivă.
Să fii capabil să identifici situaţiile în care poţi aplica principiul recursivităţii.
Durata: 20 minute
Ack(m,n)=
Ac k ( m 1,1), n 0
Ac k ( m 1, Ack ( m, n 1)), altfel
Definiţie
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să identifici situaţiile în care poţi aplica principiul recursivităţii.
Să fii capabil să aplici tehnica recursivă pentru rezolvarea unei probleme date.
Să fii capabil să determini o variantă de rezolvare.
Durata: 20 minute
gasit(x,i)=
false , daca x ai
Obiectivul vizat:
Să fii capabil să aplici tehnica recursivă pentru rezolvarea unei probleme date.
Să fii capabil să determine o altă variantă de rezolvare,când ţi se dă una.
Să fii capabil să determini instrucţiunea de apel corectă.
Durata: 20 minute
2
1 3
P
Tipul activităţii: Transformare
Sugestii
Activitatea se poate face individual, fiecare elev pe caiet, pe grupe sau în perechi.
Sarcina de lucru
Să se verifice dacă există într-un vector cu n elemente întregi, cel puţin un element cu
valoarea intreagă x. Fie vectorul a=(a1,a2,...,an) şi o variantă de rezolvare.
Varianta 1:
#include <iostream.h>
int a[100];
int gasit(int x, int i)
{if(i = = 0) return x = = a[0];
else return ((x = = a[i]) || gasit(x,i-1));}
void main()
{int x,i,n;
cout<<”n= ”;
cin>>n;
cout<<”x= ”;
cin>>x;
for(i=0;i<n;i++)
{cout<<”a[”<<i<<”]=”;
cin>>a[i];}
if(gasit(x,n-1))
cout<<”s-a gasit elementul”<<x;
else cout<<”nu s-a gasit elementul”<<x;}
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să determini o alta variantă de rezolvare, când ţi se dă una.
Să fii capabil să găsesti algoritmul optim.
Ce vreau?
Durata: 20 minute Ce ?
De ce vreau?
vreau?
Tipul activităţii: Starbursting
Cum? Pot?
Sugestii vreau?
Pot? Ce
Activitatea se poate face individual, fiecare elev pe caiet, pe grupe sau în perechi la
vreau?
teorie.
Sarcina de lucru
Să se verifice dacă există într-un vector cu n elemente întregi, cel puţin un element cu
valoarea intreagă x. Fie vectorul a=(a1,a2,...,an) şi o variantă de rezolvare a problemei.
Să se optimizeze această variantă de rezolvare răspunzând şi la întrebările din colţurile
steluţei.
Varianta 3 :
#include <iostream.h>
int a[100];
int gasit(int x, int i)
{if(i > n) return 0];
else if(x = = a[i]) return 1 ;
else return gasit(x,i+1);}
void main()
{int x,i,n;
cout<<”n= ”;
cin>>n;
cout<<”x= ”;
cin>>x;
for(i=1;i<=n;i++)
{cout<<”a[”<<i<<”]=”;
cin>>a[i];}
if(gasit(x,1))
cout<<”s-a gasit elementul”<<x;
else cout<<”nu s-a gasit elementul”<<x;}
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să determini datele de intrare.
Să fii capabil să determini datele de ieşire.
Să fii capabil să determini schema de rezolvare a problemei soluţionată de programul
dat.
Durata: 5 minute
B A
C
Sugestii
Activitatea se poate face individual, fiecare elev pe caiet, pe grupe sau în perechi, la
clasă.
Sarcina de lucru
Se dă programul de mai jos. Folosind limbajul pseudocod să se rescrie acest program.
#include <iostream.h>
int suma(int i, int j, int m, int a[20][20])
{if (i = = 0 && j = = 0)
if (a[0][0]%2==0) return a[0][0];
else return 0;
else if (a[i][j]%2==0)
if (j==0) return a[i][j]+suma(i-1,m-1,m,a);
else return a[i][j]+suma(i,j-1,m,a);
else if(j==0) return suma(i-1,m-1,m,a);
else return suma(i,j-1,m,a);}
void main()
{int n,m,a[20][20];
citeste(a,n,m); cout<<”suma este”<<suma(n-1,m-1,m,a)<<endl;}
Fişa de documentare 2.3 Tipuri de algoritmi de divizare
Definiţie
Tehnica divizării ("divide and conquer" sau “divide et impera”), este fundamentală în
elaborarea algoritmilor şi constă în descompunerea unei probleme complexe în mai
multe subprobleme a căror rezolvare e mai simplă şi din soluţiile cărora se poate
determina soluţia problemei iniţiale (exemple: găsirea minimului şi maximului valorilor
elementelor unui tablou, căutarea binară, sortare Quicksort, turnurile din Hanoi). Un
algoritm de divizare general se elaborează astfel: la un anumit nivel avem două
posibilităţi:
Se procedează astfel:
#include <iostream.h>
int v[10],n;
void main()
{cout<<”n=”;
cin>>n;
for(int i=1;i<=n;i++)
{cout<<”v[“<<i<<”]=”;
cin>>v[i];}
cout<<”max=”<<max(1,n);
}
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să determini ordinea de execuţie corectă a instrucţiunilor unui program.
Să fii capabil să-ţi însuşeşti logica programului.
Să fii capabil să determini ordinea corectă a instrucţiunilor programului.
Durata: 15 minute
Tipul activităţii: Reconstrucţie
Sugestii
Activitatea se poate face individual, fiecare elev pe caiet sau pe grupe.
Sarcina de lucru
Se dau instrucţiunile de mai jos reprezentând algoritmul căutarii binare ( care se referă
la următoarea problemă: se citeşte un vector cu n componente numere întregi, unde
numerele se presupun ordonate crescător şi o valoare intreagă nr. Să se decidă dacă nr
se găseşte sau nu printre numerele citite, iar în caz afirmativ să se tipărească indicele
componentei care conţine acea valoare.).
Instrucţiunile nu sunt in ordinea corectă de execuţie. Aranjează aceste instrucţiuni
pentru a obţine varianta corectă a programului.
#include <iostream.h>
cin>>n;
{cout<<”n=”;
if (nr<v[(i+j)/2])
caut(1,n);}
void main()
cin>>nr;
for(int i=1;i<=n;i++)
cout<<”gasit”<<’ ‘<<”indice “<<(i+j)/2;
cout<<”nr=”;
else caut ((i+j)/2+1,j);}}
else if(i<j)
void caut(int i,int j)
{cout<<”v[“<<i<<”]”;
int v[100],n,nr;
{if (nr==v[(i+j)/2])
caut (i,(i+j)/2-1);
cin>>v[i];}
Fişa de documentare 2.4 Tipuri de algoritmi recursivi cu revenire
Definiţie
Algoritmii cu revenire (algoritmi de tip backtracking) se aplică problemelor în care soluţia
se poate reprezenta sub forma unui vector x=(x1,x2,...xn) cu S=S1 x S2 x...x Sn, unde
mulţimile Si sunt finite, S numindu-se spaţiul soluţiilor posibile. În particular, Si sunt
identice având acelaşi număr M de elemente. Pentru fiecare problemă concretă sunt
date anumite relaţii între componentele vectorului x, numite condiţii interne.
Determinarea tuturor soluţiilor rezultat se poate face generând toate soluţiile posibile şi
verificând apoi dacă satisfac condiţiile interne. Dar timpul de calcul ar fi foarte mare
(dacă mulţimile Si ar avea numai câte 2 elemente, timpul ar fi proporţional cu 2 n).
Elementele vectorului x primesc valori pe rând, lui xi i se atribuie valori, doar dacă
x1,x2,...,xi-1 au primit deja valori, valorile atribuite trebuind să verifice condiţiile de
continuitate referitoare la x1,x2,...,xi. Doar apoi se trece la calculul lui xi+1. În cazul
neîndeplinirii condiţiilor de continuitate, se alege următoarea valoare posibilă pentru xi.
Dacă Si a fost epuizat, se micşorează i, încercând o altă alegere pentru xi-1.
Pe acestă metodă se bazează rezolvarea unor probleme clasice ca: permutări de n,
"opt regine", partiţii, "relaţii stabile", colorarea unei hărti, tăierea unui fir de lungime l în
părţi de lungimi date, etc.
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să execuţi pas cu pas algoritmul de afişare a permutărilor de n.
Să fii capabil să-ţi însuşeşti tehnica rutinei recursive a programului.
Să fii capabil să enunţi o situaţie reală in care se poate aplica acest algoritm.
Durata: 15 minute
Sugestii
Activitatea se poate face individual sau pe grupe.
Sarcina de lucru
#include <iostream.h>
int t[20],n;
void tipar()
{for(int i=1;i<=n;i++)
cout<<t[i];
cout<<endl;}
void perm(int k)
{int i,j,corect;
if (k==n+1) tipar();
else {for(i=t[k]+1;i<=n;i++)
{ t[k]=i;
corect=1;
for(j=1;j<=k-1;j++)
if(t[j]==t[k] )
corect=0;
if (corect) perm(k+1);}}
t[k]=0;}
void main()
{cout<<”n=”;
cin>>n;
perm(1);}
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să modifici algoritmul generării permutărilor astfel incât să rezolvi
problema aşezării damelor.
Să fii capabil să descoperi care este condiţia ca două dame să nu se atace pe o tablă
de şah.
Să fii capabil să aplici funcţionarea acestui algoritm pentru un caz particular dat.
Durata: 15 minute
Sugestii
Activitatea se poate face individual sau pe grupe la teorie sau laborator.
Sarcina de lucru
Se dau n dame pe o tablă de şah de dimensiune n*n. Să se afişeze toate soluţiile
posibile de aranjare a celor n dame pe tablă astfel încât să nu se atace. Exemplificare
pentru n=4
#include <iostream.h>
int t[20],n;
void tipar()
{for(int i=1;i<=n;i++)
cout<<t[i];
cout<<endl;}
void perm(int k)
{int i,j,corect;
if (k==n+1) tipar();
else {for(i=t[k]+1;i<=n;i++)
{ t[k]=i;
corect=1;
for(j=1;j<=k-1;j++)
if(t[j]==t[k] )
corect=0;
if (corect) perm(k+1);}}
t[k]=0;}
void main()
{cout<<”n=”;
cin>>n;
perm(1);}
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să deduci modul de funcţionare a funcţiei recursive din program care
calculează partiţia numărului dat.
Să fii capabil să înţelegi necesitatea celor doi parametri din funcţia recursivă şi
semnificaţia lor.
Să fii capabil să observi de ce ajungem cu siguranţă la soluţie.
Să fii capabil să determini ce face programul pentru o dată de intrare specificată.
Durata: 15 minute
#include <iostream.h>
int s[20],n;
void tipar(int k)
{for(int i=1;i<=k;i++)
cout<<s[i];
cout<<endl;}
void main()
{cout<<”n=”;
cin>>n;
part(1,n);}
Fişa de documentare 2.5 Algoritmi iterativi şi recursivi
Axioma
S-a demonstrat matematic că orice algoritm recursiv poate fi scris iterativ, şi reciproc.
Activitatea de învăţare 2.13 Metode iterative şi recursive
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să găseşti legătura între părţile precizate.
Să fii capabil să recunoşti definiţiile specificate.
Durata: 15 minute
Sugestii
Activitatea se poate face individual, un elev la câte un calculator, folosind fişa de lucru.
Activitatea se poate face şi pe grupe sau în perechi.
Sarcina de lucru
Se dau următoarele tipuri de informaţii: 1.iteraţie, 2.recursiv, 3.metodă, 4. subprogram,
5. programare.
Să se împerecheze corespunzător cu următoarele enunţuri: a. parte a unui program.
b. ansamblu de mijloace socotite proprii pentru realizarea unui scop; mod de executare
a unui lucru.
c. care poate fi repetat în mod nelimitat.
d. repetare a unui anumit procedeu de calcul prin aplicarea lui la rezultatul calculului din
etapa precedentă.
e. operaţia de elaborare a programului în vederea rezolvării unei probleme cu
calculatorul electronic.
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să transformi o definiţie recursivă intr-un algoritm iterativ.
Să fii capabil să găseşti asemănări între metoda iterativă şi recursivă.
Să fii capabil să găseşti diferenţe între metodele iterativă şi recursivă.
Durata: 15 minute
Sugestii
Activitatea se poate face individual sau pe grupe, la teorie, respectiv laborator.
Sarcina de lucru
Să se studieze cele două metode de rezolvare, iterativă şi recursivă, făcându-se o
tratare comparativă a lor pentru algoritmul lui Euclid:
a , a b
Cmmdc(a,b)=
cmmdc ( a b, b ), a
cmmdc ( a , b a ) , a
b
b
Tema 3. Avantajele şi dezavantajele recursivităţii
Fişa de documentare 3.1 Eliminarea recursivităţii
Avantaje
De multe ori, soluţia unei probleme poate fi elaborată mult mai uşor, mai clar şi mai
simplu de verificat, printr-un algoritm recursiv.
Dezavantaje
Varianta recursivă poate duce la timp de execuţie şi spaţiu de memorie prea mari,
transformarea în una nerecursivă, eliminând aceste dezavantaje.
Din aplicaţiile prezentate în fişele 2.1 şi 2.5 se observă diferenţele dintre cele două
metode de rezolvare astfel:
Avantajul recursivităţii constă în faptul că soluţile recursive sunt mult mai clare , mai
scurte şi mai uşor de urmărit, deci mult mai elegante. Ele sunt mult mai avantajoase
decât cele iterative dacă:
Soluţiile problemei sunt definite recursiv;
Cerinţele problemei sunt formulate recursiv;
În unele cazuri este foarte greu de definit o soluţie iterativă , cum este cazul algoritmilor
în care o funcţie recursivă apelează o altă funcţie recursivă care depinde de prima
funcţie (recursivitate indirectă) şi atunci în mod obligatoriu este preferabil algoritmul
recursiv.
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să enumeri dezavantajul folosirii recursivităţii în acest caz.
Să fii capabil să găseşti varianta ce elimină dezavantajele metodei recursive.
Durata: 30 minute
Tipul activităţii: Cubul
Sugestii
Activitatea se face pe 6 grupe la clasă, sau individual.
Sarcina de lucru
Problemă nostimă:
Câte perechi de iepuri se pot obţine în n luni dintr-o singură pereche ştiind că:
- la momentul iniţial, iepurii din prima pereche sunt nou-născuţi;
- fiecare nouă pereche de iepuri devine fertilă după o lună;
- fiecare pereche produce o pereche de descendenţi în fiecare lună;
- nici un iepure nu moare.
Numărul perechilor de iepuri din fiecare lună este descris de şirul:
Luna 0 1 2 3 4 5 6 7 8 …….
Nr. perechi 1 1 2 3 5 8 1 2 3 ………
Fiecare grupă va rezolva cerinţa fiecărei feţe.
Faţa 1: ce tip de problemă este?
Faţa 2: scrie formula ce rezolvă problema.
Faţa 3: ce variante avem pentru rezolvare?
Faţa 4: scrie varianta cea mai avantajoasă.
Faţa 5: argumentează alegerea variantei.
Faţa 6: enumeră un dezavantaj al variantei neutilizate.
Competenţa:
Aplică principiile recursivităţii şi iterativităţii în rezolvarea problemelor
Obiectivul vizat:
Să fii capabil să elaborezi programul ce rezolvă cerinţa problemei date.
Să fii capabil să enumeri necesitatea folosirii recursivităţii în acest caz.
Durata: 45 minute
Sugestii
Activitatea se poate face individual, în perechi sau pe grupe la laborator.
Sarcina de lucru
Se consideră şirurile definite recurent astel:
a0=a; b0=b; a,b>0:
a bn 1
a n n 1 , bn a n 1bn 1
2
Să se scrie un program care să citească a,b şi n şi să se calculeze an şi bn.(Dacă două
şiruri sau mai multe se apelează reciproc avem recursivitate indirectă sau încrucişată.)
Tema 4. Tehnica de programare Divide et Impera
Fişa de documentare 4.1 Descriere generală
Divide et impera este o tehnică specială prin care se pot rezolva anumite probleme.
Divide. Problema dată este împărţită în două sau mai multe subprobleme de
acelaşi tip, dar de dimensiuni mai mici. Subproblemele se rezolvă direct, dacă
dimensiunea lor permite aceasta (cazuri elementare), sau, fiind de acelaşi tip, se
rezolvă în mod recursiv, prin acelaşi procedeu.
Impera. Se combină soluţiile subproblemelor pentru a obţine soluţia problemei
iniţiale.
Restricţii
Tehnica Divide et Impera se poate aplica în rezolvarea unei probleme care îndeplineşte
următoarele condiţii :
- se poate descompune în ( două sau mai multe) subprobleme ;
- aceste subprobleme sunt independente una faţă de alta (o subproblemă nu se rezolvă
pe baza alteia şi nu se foloseşte de rezultatele celeilalte);
- aceste subprobleme sunt similare cu problema iniţială;
- la rândul lor subproblemele se pot descompune (dacă este necesar) în alte
subprobleme mai simple;
- aceste subprobleme simple se pot soluţiona imediat prin algoritmul simplificat.
Numărul problemelor care se rezolvă prin această metodă este relativ mic, tocmai
datorită restricţiilor de mai sus.
Schema generală
Tehnica Divide et Impera admite o implementare recursivă, deoarece subproblemele
sunt similare problemei iniţiale, dar de dimensiuni mai mici.
Principiul fundamental al recursivităţii este autoapelarea unui subprogram când acesta
este activ; ceea ce se intamplă la un nivel, se intamplă la orice nivel, având grijă să
asigurăm condiţia de terminare a apelurilor repetate. Asemănător se intâmplă şi în cazul
tehnicii Divite et Impera ; la un anumit nivel sunt doua posibilităţi:
s-a ajuns la o (sub)problemă simplă ce admite o rezolvare imediată, caz în care
se rezolvă (sub)problema şi se revine din apel (la subproblema anterioară, de
dimensiuni mai mari);
s-a ajuns la o (sub)problemă care nu admite o rezolvare imediată, caz în care o
descompunem în două sau mai multe subprobleme şi pentru fiecare din ele se
continuă apelurile recursive (ale funcţiei).
Rezolvarea subproblemelor
Se rezolvă subproblema directă.
Combinarea soluţiilor
După rezolvarea celor două subprobleme se execută faza de combinare a rezultatelor
în vederea rezolvării întregii probleme. Se face prin interclasarea soluţiilor.
Subprogramul divide
Subprogram DivImp(V,p,q)
Daca q-p <= 1 atunci Rezolva(V,p,q)
altfel m=(p+q) div 2
DivImp(V,p,m)
DivImp(V,m+1,q)
Combina(V,p,m,q)
Sf_Daca
Sf_subprogram.
Apelul subprogramului
Iniţial p=1, q=n, rezultă DivImp(V,1,n).
Obiectivul vizat:
Să fii capabil să precizezi etapele tehnicii Divide et Impera.
Să fii capabil să explici rolul funcţional al fiecărei etape.
Durata: 15 minute
Sugestii
Activitatea se poate face individual sau pe grupe mici ( 2 – 3 elevi ), la clasă.
Sarcina de lucru
Realizaţi o modalitate de a organiza informaţiile necesare tehnicii Divide et Impera,
ţinându-se cont de rolul lor în cadrul ei.
Fişa de documentare 4.2 Aplicaţii practice
main( )
{ cout<<”n=”;cin>>n;
for (int i=1;i<=n;i++)
{cout<<”v[“<<i<<”]=”;cin>>v[i]; }
cout<<”max=”<<max(1,n);
}
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să descrii pas cu pas algoritmul din fişa de documentare 4.2.
Să înţelegi algoritmul ce descrie tehnica Divide et Impera.
Durata: 15 minute
Tipul activităţii: Urmează paşii
Sugestii : Elevii se pot organiza în grupe mici ( 2-3 elevi) sau pot lucra individual
Sarcina de lucru
Urmând exemplul din fişa de documentare 4.2 să se descrie pas cu pas algoritmul
prezentat pentru şirul 89, 10, 11, 23, -1, 78, 4. Care este numărul de comparări?
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să compari timpul de obţinere a rezultatului cu tehnica Divide et Impera
faţă de alte metode.
Să înţelegi şi însuşeşti algoritmul prezentat.
Durata: 45 minute
Sarcina de lucru:
Se citeşte un vector cu n componente numere întregi, ordonate crescător şi o valoare
întreagă - nr. Să se decidă dacă nr se găseşte sau nu printre numerele citite, iar în caz
afirmativ să se tipărească indicele componentei care conţine acea valoare (Căutare
binară).
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să înţelegi şi însuşeşti algoritmul prezentat.
Să fii capabil să determini numărul maxim de comparaţii.
Durata: 45 minute
Sarcina de lucru:
În aplicaţie, funcţia sort sortează un vector cu maximum două elemente; funcţia interc
interclasează rezultatele; divimp implementează strategia generală a tehnicii studiate.
#include<iostream.h>
int a[10],n;
void sort (int p,int q, int a[10] )
{
int m;
if (a[p]>a[q])
{
m=a[p];
a[p]=a[q];
a[q]=m;}
}
void interc (int p,int q, int m, int a[10])
{
int b[10],i,j,k;
i=p; j=m+1; k+1;
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să determini o formulă recursivă pentru problema dată.
Să exemplifici pentru un n dat, ordinea mutărilor.
Să fii capabil să scrii programul corespunzător.
Durata: 35 minute
Tipul activităţii: Problematizare
Sugestii: Elevii vor lucra individual fiecare la un calculator sau pe grupe la laborator.
Sarcina de lucru:
Se dau 3 tije simbolizate prin a,b,c. Pe tija a se găsesc n discuri de diametre diferite,
aşezate în ordine descrescătoare a diametrelor privite de jos în sus. Se cere să se mute
de pe tija a pe b, utilizând ca tijă intermediară tija c, respectând următoarele reguli:
la fiecare pas se mută un singur disc ;
nu este permis să se aşeze un disc cu diametrul mai mare peste un disc cu
diametrul mai mic.
Concret:
- se alege primul element x1, ce aparţine lui 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 mulţimea A k+1. Apar
două posibilităţi :
1) Nu s-a găsit un astfel de element, caz în care se reia căutarea considerând
generate elementele x1,x2 …,xk+1 , iar aceasta se reia de la următorul element al
mulţimii Ak rămas netestat;
2) A fost găsit, caz în care se testează dacă acesta îndeplineşte anumite condiţii
de continuare apărând astfel două posibilităţi:
- îndeplineşte, caz în care se testează dacă s-a ajuns la soluţie şi apar din nou
două posibilităţi:
- s-a ajuns la soluţie, se tipăreşte soluţia şi se reia algoritmul considerând
generate elementele x1,x2 …,xk , (se caută în continuare, un alt element al mulţimii A k ,
rămas netestat);
- nu s-a ajuns la soluţie, caz în care se reia algoritmul considerând generate
elementele x1,x2 …,xk , şi se caută un prim element xk+2 € Ak.
- nu le îndeplineşte, caz în care se reia algoritmul considerând generate
elementele x1,x2 …,xk , iar elementul xk-1 se caută între elementele mulţimii A, rămase
netestate.
Algoritmul se termină atunci când nu există nici un element x 1 € A1 netestat.
ST
…
void back () {
int as;
k=1;
init();
while (k>0)
{
do {} while ((as=am_succesor()) && !e_valid());
if (as)
if (solutie()) tipar();
else {k++; init();}
else k--;
}
}
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să precizezi funcţiile subrutinei back.
Să fii capabil să explici rolul fiecărei funcţii din subrutina back.
Durata: 15 minute
Tipul activităţii: Harta tip traseu
Sugestii: Elevii vor lucra individual sau pe grupe la teorie.
Sarcina de lucru:
Să realizezi o hartă tip traseu pornind de la tehnica Backtracking în care să se
regăsească toate funcţiile componente rutinei back, ţinând cont de rolul avut de acestea
în cadrul metodei.
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să identifici ce reprezintă ce pui pe stivă şi ce reprezintă nivelul stivei
pentru problema dată.
Să fii capabil să scrii conţinutul funcţiilor ce apar în rutina back, relativ la problema
damelor.
Durata: 20 minute
Sarcina de lucru:
Fiind dată o tablă de şah, de dimensiune n x n, se cere să se scrie conţinutul funcţiilor
standard din rutina back ce generează toate soluţiile de aranjare a n dame, astfel încât
să nu se afle două dame pe aceeaşi linie, coloană sau diagonală (damele să nu se
atace ). Precizaţi ce punem pe stivă şi ce reprezintă nivelul stivei în acest caz, precum
şi funcţiile programului.
Fişa de documentare 5.2 Aplicaţii practice
Se exemplifică mai întâi problemele de bază, din care, prin mici modificări, se obţin
probleme mai complexe. Se foloseşte metoda Backtracking standard ( cu funcţiile
prezentate în fişa 5.1 de la tema 5).
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să înţelegi algoritmul prezentat.
Să fii capabil să exemplifici pe algoritm pentru o valoare mică dată lui n.
Să fii capabil să identifici condiţia de oprire a algoritmului
Durata: 25 minute
Sarcina de lucru:
Se citeşte un număr natural n. Să se genereze toate permutările mulţimii {1,2,…,n}.
Generarea permutărilor se face ţinând cont că orice permutare va fii alcătuită din
elemente distincte ale mulţimii A={1,2,..,n}. Exemplifică pentru n=3 pe programul de mai
jos. Până când se continuă algoritmul?
#include<iostream.h>
int st[10],n,k;
void init()
{ st[k]=0;}
int am_succesor()
{ if (st[k]<n)
{ st[k]++;
return 1;}
else
return 0;}
int e_valid()
{ for(int i=1;i<k;i++)
if (st[i]==st[k])
return 0;
return 1;}
int solutie()
{ return k==n;}
void tipar()
{ for(int i=1;i<=n;i++)
cout<<st[i];
cout<<endl;}
void back()
{ int as;
k=1;init();
while(k>0)
{ do{} while((as=am_succesor()) && !e_valid());
if(as)
if(solutie()) tipar();
else
{ k++;
init();}
else k--;
}}
main()
{ cout<<"n=";
cin>>n;
back();
}
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să determini asemănări şi deosebiri între algoritmul de generare a
permutărilor şi cel al aranjamentelor.
Să fii capabil să modifici un program pentru a rezolva un alt tip de problemă
asemănător.
Durata: 15 minute
2
1 3
P
Tipul activităţii: Transformare
Sugestii: Elevii vor lucra individual fiecare la un calculator sau pe grupe la laborator.
Sarcina de lucru:
Se citesc n şi p. Să se genereze toate aranjamentele de n luate câte p. Care sunt
asemănarile şi deosebirile cu generarea permutărilor?
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să scrii corect un program cu tehnica Backtracking standard.
Să fii capabil să găseşti un algoritm cu care se aseamănă.
Durata: 25 minute
Sugestii: Elevii vor lucra individual fiecare la un calculator sau pe grupe la laborator.
Sarcina de lucru:
Se citesc n şi p numere naturale, n ≥ p. Se cere să se genereze toate submulţimile cu p
elemente ale mulţimii {1,2,...,n}.
Pentru rezolvarea problemei trebuie ţinut cont de următoarele:
Stiva are inalţimea p
Elementele aflate pe niveluri diferite ale stivei trebuie să fie distincte.
Pentru a evita repetiţia, elementele se aşează în ordine crescătoare: pe nivelul
k, se va afla o valoare mai mare decat pe nivelul k-1 şi mai mică sau egală cu
n-p+k.
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să înţelegi şi să-ţi însuşeşti algoritmul prezentat.
Să fii capabil să exemplifici pe algoritm pentru o valoare dată n.
Durata: 25 minute
Sarcina de lucru:
Fiind dată o hartă cu n ţări, se cer toate soluţiile de colorare a hărţii, utilizând cel mult 4
culori, astfel încât 2 ţări cu frontiera comună să fie colorate diferit. Este demonstrat
matematic faptul că sunt suficiente numai 4 culori pentru ca orice hartă să fie colorată
astfel.
4
3
2
5
Pentru exemplificare, vom considera harta de mai sus unde ţările sunt numerotate cu
cifre cuprinse între 1 şi 5:
An , n
Harta este furnizată programului cu ajutorul unei matrice (tablou) .
1, tara i are frontiera cu tara j
A(i , j )
0, altfel
#include<iostream.h>
int st[10],a[20][20],n,k;
void init()
{st[k]=0;}
int am_succesor()
{if(st[k]<4)
{st[k]++;
return 1;}
else return 0; }
int e_valid()
{for(int i=1;i<=k-1;i++)
if(st[i]==st[k] && a[i][k]==1) return 0;
return 1; }
int solutie()
{return k==n;}
void tipar()
{cout<<"Varianta"<<endl;
for(int i=1;i<=n;i++) cout<<"Tara"<<i<<"culoarea"<<st[i]<<endl;
cout<<endl; }
void back()
{int as;
k=1;Init();
while(k>0)
{ do {} while ((as=am_succesor()) && !e_valid());
if (as)
if (solutie()) tipar();
else {k++;Init();}
else k--; } }
main()
{cout<<"Numar de tari";cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=i-1;j++)
{cout<<"a["<<i<<","<<j<<"]=";cin>>a[i][j];
a[j][i]=a[i][j]; }
back(); }
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să scrii corect un program cu tehnica Backtracking standard.
Să fii capabil să identifici un algoritm cu care se aseamănă.
Să fii capabil să implementezi algoritmul găsit.
Durata: 25 minute
Sarcina de lucru:
Un comis-voiajor trebuie să viziteze un număr de n oraşe. Iniţial, acesta se află într-unul
dintre ele, notat 1. Comis-voiajorul doreşte să nu treacă de două ori prin acelaşi oraş,
iar la intoarcere sa revină în oraşul 1. Cunoscând legăturile existente între oraşe, se
cere să se tipărească toate drumurile posibile pe care le poate efectua comis-voiajorul.
În figura de mai jos sunt simbolizate, pentru n=6, cele 6 oraşe, precum şi drumurile
existente între ele.
2 3
1
4
6 5
În fişa suport 5.1 am prezentat tehnica Backtracking clasic, iterativ, iar în fişa suport 5.2
am rezolvat câteva probleme cu această tehnică. Pentru tehnica Backtracking recursiv,
soluţiile finale st[i] sunt generate în cadrul funcţiei back_recursiv(int k), unde k
reprezintă nivelul până la care s-a ajuns pe stivă. Adică la fiecare execuţie din lanţul de
auto-apeluri, funcţia back_recursiv tratează nivelul k al stivei.
Întrun ciclu, prin variabila contor vor trece pe rând toate valorile din intervalul <v1> la
<vn> care ar putea fi încercate pe nivelul k al stivei. La fiecare pas al ciclului, pentru
fiecare dintre valorile variabilei contor:
Se memorează pe nivelul k valoarea contor prin st[k]←contor. Se obţine astfel
soluţia parţială(st[1],st[2],…,st[k]).
Se verifică dacă această soluţie este validă prin funcţia valid(k). Dacă da atunci
se verifică dacă soluţia este finală :
- Dacă este soluţie finală atunci se apelează funcţia tipar;
- În caz contrar, avem o soluţie validă dar care nu este şi finală.Vom .
urca la nivelul următor în stivă prin apelul back_recursiv(k+1).
Algoritmul se reia de lacapăt, dar cu k+1 în loc de k.
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să înţelegi şi să-ţi însuşeşti algoritmul de backtracking recursiv prezentat.
Să determini modul de iniţializare al stivei, găsirea succesorului şi ajungerea la soluţie.
Să fii capabil să exemplifici pe algoritm pentru o valoare dată n.
Durata: 35 minute
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să identifici probleme a căror rezplvare necesită tehnica Backtracking recursiv.
Să fii capabil să aplici tehnica Backtracking recursiv.
Să identifici algoritmul de rezolvare.
Să implementezi algoritmul găsit.
Să găseşti date de intrare corespunzătoare tuturor cazurilor problemei pentru testarea
programulului.
Durata: o săptămână
Sarcina de lucru:
Să se realizeze un portofoliu de minim 7 probleme ce au ca algoritm de rezolvare
tehnica Backtracking recursiv. Se va urmări:
- concordanţă temă- realizare
- capacitate de analiză şi sinteză a informaţiei
- originalitate
- prezenţa comentariilor în program
- testarea datelor de intrare şI soluţiile obţinute
- lucrul în echipă
- design
- prezentarea proiectului
Tema 6. Tehnica de programare Greedy
Fişa de documentare 6.1 Descrierea tehnicii
Este practic imposibil să fie dată forma generală, a unei probleme rezolvabile cu tehnica
Greedy, totuşi.
Să considerăm o mulţime A cu n elemente. Se cere o submulţime a sa cu m<=n
elemente (în cazul m=n este importantă ordinea alegerii elementelor), astfel încât să fie
îndeplinite anumite condiţii (acestea diferă de la o problemă la alta).
Definiţie
Tehnica Greedy poate fi privită ca o particularizare a tehnicii Backtracking, în care se
renunţă la mecanismul de întoarcere.
Consecinţa 1.
Este necesar ca cel care elaborează un algoritm Greedy să ştie faptul că, procedând în
modul ales de el, ajunge la rezultatul dorit. Pentru fiecare problemă în parte, după ce se
identifică un algoritm, este obligatoriu să se demonstreze că acesta conduce la soluţia
optimă. Demonstraţia faptului că se ajunge la soluţia optimă este specifică fiecărei
probleme în parte.
Avantajul tehnicii
Avantajul timpului polinomial, conduce la necesitatea utilizării tehnicii Greedy. Pentru
problemele pentru care nu se cunosc algoritmi care necesită timp polinomial, se caută
soluţii, chiar dacă nu optime, dar apropiate de acestea, dar care au fost obţinute în timp
util. Multe din aceste soluţii sunt obţinute cu Greedy.
Concluzii
Metoda rezolvă probleme de optim în care soluţia se construieşte pe parcurs. Optimul
global se determină prin estimări succesive ale optimului local. Dintr-o mulţime de
elmente A trebuie determinată o submulţime B, care verifică anumite condiţii şi care, de
obicei, este soluţia unei probleme de optimizare. Soluţia problemei se construieşte
treptat. Iniţial B este mulţimea vidă. Se adaugă în B succesiv elemente din A,
atingându-se de fiecare dată un optim local. Dar, această contruire nu asigură
întodeauna atingerea unui optim global. De aceea tehnica Greedy nu poate fi aplicată
decât dacă se demonstrează că modul de construire a mulţimii B duce la obţinerea unui
optim global.
Datorită modului de construire a soluţiei, tehnica se mai numeşte tehnica optimului
local.
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să-ţi fixezi anumite informaţii prezentate.
Durata: 10 minute
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să înţelegi şi să-ţi însuşeşti algoritmul Greedy prezentat.
Să fii capabil să exemplifici pe algoritm pentru o valoare dată n.
Durata: 35 minute
Sarcina de lucru:
Într-o sală, într-o zi, trebuie planificate n spectacole. Pentru fiecare spectacol se
cunoaşte intervalul în care se desfăşoară:[st, sf]. Se cere să se planifice un număr
maxim de spectacole astfel încât să nu se suprapună. Exemplificaţi pentru n=5, cu
unele spectacole care au ora de terminare peste ora de început a altora.
Rezolvare
Fie o planificare optimă a spectacolelor(un număr maxim k de spectacole i 1,i2,...ik, unde
i1,i2,...ik є {1,2,..n} şi spectacolul ij are lor înaintea spectacolului i j+1).O astfel de
planificare îndeplineşte condiţia: spectacolul i j+1 începe după terminarea spectacolului ij.
O consecinţă imediată a condiţiei de mai sus este: spectacolul i j ia sfârşit înaintea
terminării spectacolului ij+1 (consecinţa nu implică un efort de gândire deosebit).
Vom construi o soluţie după următorul algoritm:
1) sortăm spectacolele după ora terminării lor;
2) primul spectacol programat este cel care se termină cel mai devreme;
3) alegem primul spectacol dintre cele care urmează în şir ultimului spectacol
programat, care îndeplineşte condiţia că începe după ce s-a terminat ultimul
spectacol programat;
4) dacă tentativa de mai sus a eşuat (nu am găsit un astfel de spectacol) algoritmul
se termină, altfel se programează spectacolul găsit şi algoritmul se reia de la
pasul 3.
#include<iostream.h>
int s[2][10],o[10],n,I,h1,m1,h2,m2,ora;
void sortare()
{ int gata,m,i;
do
{ gata=1;
for(i=1;i<=n-1;i++)
if (s[1][o[i]]>s[1][o[i+1]])
{ m=o[i] ; o[i]=o[i+1]; o[i+1]=m;
gata=0;}
} while (!gata);
}
main()
{int i;
cout<<"n=";cin>>n;
for(i=1;i<=n;i++)
{o[i]=i;
cout<<"ora de inceput pentru spectacol "<<i<<" (hh mm)=";
cin>>h1>>m1;
s[0][i]=h1*60+m1;
cout<<"ora de sfarsit pentru spectacolul "<<i<<" (hh mm)=";
cin>>h2>>m2;
s[1][i]=h2*60+m2;
}
sortare();
cout<<"ordinea spectacolelor este"<<endl<<o[1]<<endl;
ora=s[1][o[1]];
for(i=2;i<=n;i++)
if (s[0][o[i]]>=ora)
{cout<<o[i]<<endl;
ora=s[i][o[i]];}
}
Competenţa:
Utilizează tehnicile de programare
Obiectivul vizat:
Să fii capabil să scrii un algoritm când se descrie modul de rezolvare al problemei.
Să fii capabil să implementezi algoritmul.
Să fii capabil să testezi programul pentru valori date.
Durata: 45 minute
Sarcina de lucru:
O persoană are un rucsac cu care poate transporta o greutate maximă G. Persoana are
la dispoziţie n obiecte şi cunoaşte pentru fiecare obiect greutatea şi câştigul care se
obţine în urma transportului său la destinaţie. Se cere să se precizeze ce obiecte
trebuie să transporte persoana în aşa fel încât câştigul sa fie maxim ştiind că obiectele
se pot tăia.
Să se exemplifice pentru:
Greutatea care poate fi transportată cu ajutorul rucsacului aste 3
Avem la dispoziţie 3 obiecte. Greutatea şi câştigul pentru fiecare obiect sunt prezentate
mai jos:
III. Glosar
Algoritm: metodă sau o procedură de calcul, alcătuită din paşi elementari necesari
pentru rezolvarea unei probleme sau categorii de probleme.
Apel: chemare.
Backtracking: o tehnică de rezolvare a unor probleme ce au soluţia sub formă de
vector şi la care se cer toate soluţiile. Se construieşte soluţia pas cu pas x1,x2,…xn,
dacă se constată că pentru o valoare aleasă, nu avem cum să ajungem la soluţie, se
renunţă la acea valoare şi se reia căutarea din punctul în care am rămas.
Divide et Impera: o tehnică specială prin care se pot rezolva anumite probleme. Divide
et Impera se bazează pe un principiu extrem de simplu: descompunem problema în
două sau mai multe subprobleme (mai uşoare), care se rezolvă, iar soluţia pentru
problema iniţială se obţine combinând soluţiile problemelor în care a fost descompusă.
Greedy: tehnică de rezolvare a unor probleme, asemănătoare cu tehnica Backtracking,
însă nu are mecanismul de revenire şi generează doar o singură soluţie.
Iteraţie: care poate fi repetat în mod nelimitat;
Metodă: ansamblu de mijloace socotite proprii pentru realizarea unui scop; mod de
executare a unui lucru;
Program: reprezintă un set de instrucţiuni prin care se comunică unui calculator cum să
efectueze un anumit grup de operaţii.
Programare: operaţia de elaborare a programului în vederea rezolvării unei probleme
cu calculatorul electronic;
Recursiv: repetare a unui anumit procedeu de calcul prin aplicarea lui la rezultatul
calculului din etapa precedentă;
Stivă: tip special de listă în care toate inserţiile şi suprimările de noduri au loc la un
singur capăt, numit vârf.
Subprogram: parte a unui program;
Tehnică: metode şi capacităţi pentru aplicaţii practice ale ştiinţelor naturii.
IV. Bibliografie