Documente Academic
Documente Profesional
Documente Cultură
An1 Sem2 Curs2 Seriaa 2015
An1 Sem2 Curs2 Seriaa 2015
Semestrul 2
Curs 2
Cuprins
2. Metode de programare
recursive/nerecursive
2.1. Metoda backtracking
2.2. Metoda divide et impera
2. Metode de programare
recursive/nerecursive
2.1. Metoda backtracking
Exist aplicaii pentru care trebuie determinat
configuraia unui set de date de intrare ce maximizeaz
sau minimizeaz o anumit funcie
Astfel de probleme se numesc probleme de optimizare,
iar funcia respectiv se numete funcie criteriu sau
funcie obiectiv
Principiul:
In backtracking se traverseaz
spaiul soluiilor pn la gsirea
unei soluii finale cu revenire
pe urma lsat
Caracteristici:
soluia final se construiete secvenial;
se pornete cu un vector gol i la fiecare pas se extinde
vectorul parial cu o nou valoare pentru acea
component;
pe msura utilizrii unei noi valori la o component, se
evalueaz funcia criteriu;
dac valoarea adugat conduce la o soluie posibil,
se trece la urmtoarea component
8
Caracteristici:
dac valoarea considerat nu conduce la o soluie
plauzibil, se alege o alt valoare din alternativele
posibile pentru acea component ;
procesul continu secvenial pan se obine o soluie
final.
10
11
Concluzie:
La orice problem de backtracking stabilim:
1.
k = 0,,n-1, numrul de componente ale soluiei;
2.
x[k]=1,,h, domeniul valorilor posibile ale unei
componente;
3.
posibil(k), condiia de continuitate
12
13
Varianta nerecursiv
//initializari pas si componente solutie
k = 0;
x[k] = 0;
15
Varianta recursiv
void Backtracking(int k)
{
// pentru toate valorile pe care le poate lua x[k]
for(int i=1; i <= h; i++)
{
x[k] = i;
// daca solutia partiala este posibila
if ( posibil(k)) {
if ( k == n-1) // solutie completa
AfiseazaSolutia(X);
else
Backtracking(k+1); // apel recursiv
}
}
}
16
Apel n main( ):
// initializari
Backtracking(0);
17
Exemple:
1. colorarea benzilor unui drapel cu n benzi avnd h culori
disponibile, benzile alturate avnd culori diferite (numr
fix de componente)
2. descompunerea unui numr n, n sum de numere
naturale (numr variabil de componente)
3. problema comis-voiajorului
18
k=0;
x[k]=0;
do
{
while(x[k] < h) // mai sunt valori posibile pentru
// componenta k
{
x[k]++; //trec la urmatoarea valoare
if(posibil(k))
if(k==(n-1)) afis_sol(); //e gata solutie
else {k++; x[k]=0; }
// trec la urmatoarea
// componenta cu
// valori de la zero
}//while
k--; // nu mai sunt valori pentru componenta k. Revin la
// componenta k-1
}while(!(k<0));
// m-am intors mai mult decit se putea,
// sau k>=0
}//main
20
int posibil(int k)
{
if(k==0)return 1;
if(x[k-1]==x[k]) return 0;
return 1;
}//posibil
void afis_sol(void)
{
for(int i=0;i<n;i++)
void dr_rec(int k)
{
for(int i=1;i<=h;i++)
{ x[k]=i;
if(posibil(k))
if(k==(n-1)) afis_sol(); //solutie finala
else dr_rec(k+1); //trec la urmatoarea
//componenta
}
}//dr_rec
23
24
do {
while(x[k] < n)
{
x[k]++;
if(posibil(k, sum)) {
if(sum == n) // solutia finala
afis_sol(k);
else {
k++;
x[k] = 0;
}
}
} // bucla valori componenta
k--; // pas inapoi
} while(!(k < 0)); // bucla componente
}
25
void back_SubSet(int k)
{
int sum;
x[k] = 0;
// pentru toate valorile pe care le poate lua x[k]
while(x[k] < n)
{
x[k]++;
if(posibil(k, sum))
// solutie posibila
{
if(sum == n)
// solutie completa
afis_sol(k);
else
back_SubSet(k+1);
}
}
}
27
28
29
void main(void)
{
int k;
printf("Introdu dim matrice costuri(nr.orase) <=7\n");
scanf("%d",&n);
printf("Introdu si afis matricea costurilor C\n");
cit(COST,n);
afis(COST,n);
cost_M=(n+1)*(long)max_cost(COST,n)+1;
// printf("Cost maxim= %ld\n",cost_M);
k=0;
printf("Introdu orasul initial (0 ~ n-1)");
scanf("%d",&x[k]);
gene(1);
afis_sol(cost_M); //e gata solutie
}//main
30
int posibil(int k)
{
if(k==0)return 1;
if(COST[x[k-1]][x[k]]!=0){//drum direct
for(int i=0;i<k;i++) //orasul nu a mai fost ales
if(x[k]==x[i]) return 0;
return 1;
}
return 0;
}//posibil
31
void gene(int k)
{
for(int i=0;i<n;i++) // valori intre 0 si n-1
{
x[k]=i;
if(posibil(k))
if((k==(n-1))&& (COST[x[n-1]][x[0]]!=0)){
C=0;// stabilire cost pentru solutia determinata
for(int i=0;i<n-1;i++) C+=COST[x[i]][x[i+1]];
C+=COST[x[n-1]][x[0]];
if(C<cost_M){
for(int i=0;i<n;i++)
Y[i]=x[i];
cost_M=C; //salvare solutie cost minim
}
}
else gene(k+1);
} //for
} // end gene
32
Concluzii
Soluia se determin printr-o cutare sistematic n
spaiul soluiilor
Se construiete vectorul soluie (tabloul
unidimensional) component cu component i se
testeaz la fiecare pas dac vectorul parial are
anse de succes:
dac da, se continu
dac nu, vectorul parial este ignorat
33
Concluzii:
Etape specifice metodei backtracking:
Specificarea vectorului soluie X[N]:
dimensiunea N,
semnificaia elementelor X[i],
domeniului valorilor pentru X[i](constrangeri
explicite),
valoarea de pornire a0,
constrngerile (implicite) pentru componentele
vectorului (ce satisfac obtinerea soluiei)
Se implementeaz funcia posibil() ce va verifica
respectarea constrngerilor implicite
Metoda nu se aplic acolo unde dimensiunea vectorului
soluie ar putea fi foarte mare datorit timpului mare de
determinare a soluiilor
34
35
36
2. METODE DE PROGRAMARE
RECURSIVE/NERECURSIVE
2.2. Metoda divide et impera
Principiul propus de metod:
se descompune problema n subprobleme, n mod
recursiv, pn cnd ajungem la o subproblem pe
care o putem rezolva direct
soluiile subproblemelor se vor combina obinnd
soluia final a problemei
37
Cutarea binar
Fie un ir de elemente ordonat. Se pune problema gsirii
unui element (cheia) n ir.
Descompunerea problemei :
se compar cheia cu valoarea din mijloc
dac avem egalitate am gsit poziia n ir
dac nu, vom ti n care din cele dou jumti de ir
trebuie s cutm mai departe pornind de la valoarea
comparat
se continu n acest mod pn cnd gsim elementul n
ir sau pn cnd vom ajunge la un ir vid
38
Valoarea cutat: 23
39
Valoarea cutat: 88
40
41
42
43
44
45
46
47
49
50
Maximul unui ir
Abordarea recursiv:
se descompune irul n 2 subiruri
se determin maximul pentru fiecare subir
se determin maximul dintre cele dou maxime
pentru fiecare subir se procedeaz n acelai mod
pn cnd ajungem la un ir de lungime 1
51
52
#define MAX 8
void citire_sir(int*, int);
void tip_sir(int*, int);
int m_max(int*, int, int);
void main( )
{
int n, Maxim;
int vect[MAX];
cout << "Numarul de elemente mai mic de " << MAX <<"
este=";
cin >> n;
cout << "Introduceti cele n elemente\n";
citire_sir(vect,n);
Maxim=m_max(vect, 0, n);
cout << "Maximul sirului este " << Maxim <<'\n';
cout <<"Tipareste elementele sirului\n";
tip_sir(vect,n);
}
53
55