?? ? Divide et impera ? Divide et impera  maxim dintr-o mulțime MetodăDeterminarea de rezolvareelementului a unor probleme Maxim(a, n)  Maxim(a, p, u) Caracteristici probleme x = Maxim(a, n-1) x1 = Maxim(a,

Download Report

Transcript ?? ? Divide et impera ? Divide et impera  maxim dintr-o mulțime MetodăDeterminarea de rezolvareelementului a unor probleme Maxim(a, n)  Maxim(a, p, u) Caracteristici probleme x = Maxim(a, n-1) x1 = Maxim(a,

?? ?
Divide et impera
?
Divide et impera

maxim dintr-o mulțime
MetodăDeterminarea
de rezolvareelementului
a unor probleme
Maxim(a, n)

Maxim(a, p, u)
Caracteristici probleme
x = Maxim(a, n-1)
x1 = Maxim(a, p, (p+u)/2)
fi descompuse
probleme cu
mică
max =pot
x>a[n-1]
? x : îna[n-1]
x2complexitate
= Maxim(a,mai
(p+u)/2+1,
u)
▪ de același tip / cu soluție cunoscută max = x1>x2 ? x1 : x2
▪ descompunerea este finită – problemă primitivă / condiție de terminare
▪ cîte probleme?
▪ cum se face împărțirea? Metoda bisecției
 rezolvarea noilor probleme este mai ușoară
 soluțiile combinate  soluția problemei inițiale

Descompunere propriu-zisă / reducere
Divide et impera

Algoritm recursiv
 Implementarea este de obicei recursivă
 Forma generală
▪ S=∅
▪ determină o modalitate de descompunere a problemei P => P1, P2, … Pn
▪ pentru fiecare i=1:n
▪ aplică recursiv algoritmul, pentru rezolvarea problemei Pi => Si
▪ S=S ∪ Si
Divide et impera

Exemple
 Probleme de parcurgere
 Problema turnurilor din Hanoi
 Problema tăieturilor
 Probleme de căutare
▪ secvențială / binară
 Probleme de sortare
▪
▪
▪
▪
prin interclasare
prin inserare
rapidă (quick sort)
metoda micșorării incrementului (Shell sort)
Divide et impera

Probleme de parcurgere


o mulțime a, cu n elemente => P(a, 0, n)
P(a, i, n) se descompune în
 prelucrare a[i]
 P(a, i+1, n)
void parcurge(float *v, int i, int n)
{ if( i!=n )
{ printf("%7.2f ",v[i]);
parc(v,i+1,n);
}
}
Divide et impera

Problema turnurilor din Hanoi

H(n, S, D, I)
 H(n-1, S, I, D)
 mută un disc de pe S pe D
 H(n-1, I, D, S)
void hanoi(int n, char s, char d, char i)
{ if(n>0)
{ hanoi(n-1,s,i,d);
Sursă
Destinație
Intermediar
printf("\nMuta un disc de pe %c pe %c",s,d);
hanoi(n-1,i,d,s);
}
}
hanoi( 5, ‘a’, ‘b’, ‘c’);
Divide et impera
1
3
4
2
b
void taietura(int **c, int x, int y, int a, int b,
int *xm,
int *ym, int
int *bm)
 Problema
tăieturilor
x, y,*am,
a, b, c[2,n]
{ int i,gasit;
1: x, c[1,i]
a, y+b-c[1,i]
for( i=gasit=0; (i<n)&&!gasit;
)
a
if((c[0][i]>x)&&(c[0][i]<x+a) && (c[1][i]>y)&&(c[1][i]<y+b))
y+b
2: x, y
a, c[1,i]-y
gasit=1;
else
3: x, y
c[0,i]-x, b
i++;
if(gasit)
x+a-c[0,i], b
c[1,i] { taietura(c, x,c[1][i], a,b-c[1][i]+y, xm,ym,am,bm);4: c[0,i], y
taietura(c, x,y,
a,c[1][i]-y,
xm,ym,am,bm);
taietura(c, x,y,
c[0][i]-x,b,
xm,ym,am,bm);
taietura(c, c[0][i],y, a-c[0][i]+x,b, xm,ym,am,bm); xmax, ymax
y}
amax=0, bmax=0
else
if(a*b>(*am)*(*bm))
{ *am=a;
x *bm=b;
c[0,i]
x+a
*xm=x; *ym=y;
}
}
Divide et impera

Probleme de căutare
 Secvențială  problemă de parcurgere (mulțimi sortate sau nesortate)
 Mulțime
Binarănesortată
(mulțimi sortate)
Mulțime sortată
C(x, a, p, u, poz)
dacă
C(x, p>u
a, i, n, poz)
C(x, a, i, n, poz)
poz=-1
dacă i==n
dacă i==n || a[i]>x
altfel
poz=-1
poz=-1
m=(p+u)/2
altfel
altfel
dacă
x==a[m]
dacă
x==a[i]
dacă x==a[i]
poz=m
poz=i
poz=i
altfel
altfel
altfel
daca
x<a[m]
C(x,
a, i+1, n, poz)
C(x, a, i+1, n, poz)
C(x, a, p, m-1, poz)
altfel
 Nu există
să se
C(x, riscul
a, m+1,
u,obțină
poz) poziția -1 chiar dacă elementul căutat se
află în mulțime, deoarece în momentul găsirii lui, nu se mai face nici un
apel recursiv și nu se mai modifică valoarea lui poz
Divide et impera

Sortare prin interclasare
S(0, 14)
 S(a, n) => S(a, 0, n-1)
15 ▪ 7dacă
13p<u5 11
3
1
8 14
6 12
4 10
▪ m=(p+u)/2 S(0, 7)
S(8, 14)
▪ S(a, p, m)
15
7 ▪ S(a,
13 m+1,
5 u)11
3
1
8 14
6 12
4 10
▪ interclasează a[p:m] cu a[m+1:u]
2
9
2
9
…
1
3
5
7
8
11
13
15
2
4
6
9
10
12
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Divide et impera

Sortare rapidă
Q(0, n-1)
 Q(x,
x[0]
x[1]p,u)
x[2] … x[k-2] x[k-1] x[k] x[k+1] x[k+2] … x[n-1]
▪ dacă p<u
Q(0, p,
k-1)
Q(k+1, n-1)
▪ poziționare(x,
u, k)
▪ Q(x, p, k-1)
x[0] x[1] x[2] … x[k-2] x[k-1] x[k] x[k+1] x[k+2] … x[n-1]
▪ Q(x, k+1, u)
10
0 1
9
19
15
3
17
4
1
-1
0
Divide et impera

Sortare prin micșorarea incrementului (Shell sort)
 generalizare a sortării prin inserție
 vector k-sortat
 secvență de pași : valori descrescătoare, ultima este 1
 Algoritm

pentru fiecare pas din secvență
▪ pentru fiecare i=pas..n-1
▪ j=i-pas
▪ cît timp j>0 și v[j]<v[j+pas]
 v[j] <->v[j+pas]
 j-=pas
Divide et impera

Sortare prin micșorarea incrementului (Shell sort)
indici
n=15
Initial:
Dupa pasul
7:
Dupa pasul
3:
Dupa pasul
1:
0
38
3
3
3
1
13
13
5
5
2
85
71
9
9
3
98
40
10
10
4
5
5
13
13
5
70
9
44
38
6
45
10
40
40
7
44
38
38
44
8
68
68
44
44
void sort_shell(double v[], int l)
{ int i,j,inc;
double a;
for(inc=l/2; inc>0; inc=inc/2)
for(i=inc; i<l; i++)
for(j=i-inc; (j>=0)&&(v[j]>v[j+inc]); j=j-inc)
{ a=v[j];
v[j]=v[j+inc];
v[j+inc]=a;
}
}
9
71
85
70
45
10
40
98
45
68
11
44
44
68
70
12
9
70
85
71
13
10
45
98
85
14
3
44
71
98