Documente Academic
Documente Profesional
Documente Cultură
2017
Tematica
2 Metoda Greedy 22
2.1 Descrierea metodei. Algoritmi generali . . . . . . . . . . . . . 22
2.2 Aplicat, ii ale Inegalităt, ii rearanjamentelor . . . . . . . . . . . . 25
2.2.1 Inegalitatea rearanjamentelor . . . . . . . . . . . . . . 25
2.2.2 Produs scalar maxim/minim . . . . . . . . . . . . . . . 27
2.2.3 Memorarea optimă a textelor pe benzi . . . . . . . . . 31
2.3 Problema rucsacului, varianta continuă . . . . . . . . . . . . . 33
2.4 Problema planificării spectacolelor . . . . . . . . . . . . . . . . 40
2.5 Arbori part, iali de cost minim . . . . . . . . . . . . . . . . . . 47
2.6 Distant, e s, i drumuri minime. Algoritmul lui Dijkstra . . . . . . 53
2.7 Fluxuri maxime ı̂n ret, ele . . . . . . . . . . . . . . . . . . . . . 62
3 Metoda Backtracking 85
3.1 Descrierea metodei. Algoritmi generali . . . . . . . . . . . . . 85
3.2 Colorarea grafurilor . . . . . . . . . . . . . . . . . . . . . . . . 93
3.3 Problema celor n dame pe tabla de s, ah . . . . . . . . . . . . . 96
3.4 Problema nebunilor pe tabla de s, ah . . . . . . . . . . . . . . . 100
3.5 Generarea obiectelor combinatoriale . . . . . . . . . . . . . . . 109
3.5.1 Preliminarii . . . . . . . . . . . . . . . . . . . . . . . . 109
3.5.2 Produs cartezian . . . . . . . . . . . . . . . . . . . . . 110
3.5.3 Submult, imi . . . . . . . . . . . . . . . . . . . . . . . . 111
3.5.4 Aranjamente cu repetit, ie . . . . . . . . . . . . . . . . . 113
3.5.5 Aranjamente . . . . . . . . . . . . . . . . . . . . . . . 114
3.5.6 Permutări . . . . . . . . . . . . . . . . . . . . . . . . . 117
3.5.7 Combinări . . . . . . . . . . . . . . . . . . . . . . . . . 119
3.5.8 Combinări cu repetit, ie . . . . . . . . . . . . . . . . . . 122
3.5.9 Permutări cu repetit, ie . . . . . . . . . . . . . . . . . . 124
1
TEMATICA 2
3
Bibliografie
[1] A.V. Aho, J.E. Hopcroft, J.D. Ullman, Data Structures and Algorithms, Addison-
Wesley, Massachusetts, 2009.
[2] Gh. Barbu, V. Păun, Programarea ı̂n limbajul C/C++, Editura Matrix Rom,
Bucures, ti, 2011.
[3] Gh. Barbu, V. Păun, Calculatoare personale s, i programare ı̂n C/C++, Editura Di-
dactică s, i Pedagogică, Bucures, ti, 2005.
[4] Gh. Barbu, I. Văduva, M. Bolos, teanu, Bazele informaticii, Editura Tehnică,
Bucures, ti, 1997.
[5] C. Bălcău, Combinatorică s, i teoria grafurilor, Editura Universităt, ii din Pites, ti,
Pites, ti, 2007.
[6] O. Bâscă, L. Livovschi, Algoritmi euristici, Editura Universităt, ii din Bucures, ti,
Bucures, ti, 2003.
[7] E. Cerchez, M. S, erban, Programarea ı̂n limbajul C/C++ pentru liceu. Vol. 2: Metode
s, i tehnici de programare, Ed. Polirom, Ias, i, 2005.
[8] E. Ciurea, L. Ciupală, Algoritmi. Introducere ı̂n algoritmica fluxurilor ı̂n ret, ele, Ed-
itura Matrix Rom, Bucures, ti, 2006.
[10] T.H. Cormen, C.E. Leiserson, R.L. Rivest, C. Stein, Introduction to Algorithms, MIT
Press, Cambridge, 2009.
[11] C. Croitoru, Tehnici de bază ı̂n optimizarea combinatorie, Editura Universităt, ii ”Al.
I. Cuza”, Ias, i, 1992.
[12] N. Dale, C. Weems, Programming and problem solving with JAVA, Jones & Bartlett
Publishers, Sudbury, 2008.
[13] D. Du, X. Hu, Steiner Tree Problems in Computer Communication Networks, World
Scientific Publishing Co. Pte. Ltd., Hackensack, 2008.
4
5
[15] H. Georgescu, Tehnici de programare, Editura Universităt, ii din Bucures, ti, Bucures, ti,
2005.
[16] C.A. Giumale, Introducere ı̂n analiza algoritmilor. Teorie s, i aplicat, ii, Ed. Polirom,
Ias, i, 2004.
[18] F.V. Jensen, T.D. Nielsen, Bayesian Networks and Decision Graphs, Springer, New
York, 2007.
[20] D.E. Knuth, The Art Of Computer Programming. Vol. 4A: Combinatorial Algo-
rithms, Addison-Wesley, Massachusetts, 2011.
[22] R. Lafore, Data Structures and Algorithms in Java, Sams Publishing, Indianapolis,
2002.
[23] A. Levitin, Introduction to The Design and Analysis of Algorithms, Pearson, Boston,
2012.
[25] D. Logofătu, Algoritmi fundamentali ı̂n C++: Aplict, ii, Ed. Polirom, Ias, i, 2007.
[28] N. Popescu, Data structures and algorithms using Java, Editura Politehnica Press,
Bucures, ti, 2008.
[33] S, . Tănasă, C. Olaru, S, . Andrei, Java de la 0 la expert, Ed. Polirom, Ias, i, 2007.
6
[34] T. Toadere, Grafe. Teorie, algoritmi s, i aplicat, ii, Editura Albastră, Cluj-Napoca,
2002.
[37] I. Tomescu, Data structures, Editura Universităt, ii din Bucures, ti, Bucures, ti, 2004.
[38] M.A. Weiss, Data Structures and Algorithm Analysis in Java, Addison-Wesley, New
Jersey, 2012.
[39] ***, Handbook of combinatorics, edited by R.L. Graham, M. Grőtschel and L. Lovász,
Elsevier, Amsterdam, 1995.
[40] ***, Handbook of discrete and combinatorial mathematics, edited by K.H. Rosen,
J.G. Michaels, J.L. Gross, J.W. Grossman and D.R. Shier, CRC Press, Boca Raton,
2000.
Tema 1
Elemente de complexitatea
algoritmilor s, i teoria grafurilor
Observat, ia 1.1.1. De cele mai multe ori, mult, imea A est de forma
A= {0, 1, 2, . . . , k} , unde k ∈ N.
| {z }
primele numere naturale
√
(3n4 + n + 3) n − 5
Exemplul 1.1.1. Funct, ia f : D → R, f (n) = , unde
(5n + 1)(n − 8)
D = {n ∈ N | n ≥ 5, n 6= 8}, este asimptotic pozitivă, deoarece D = N \ A
cu A = {0, 1, 2, 3, 4, 8} (mult, ime finită) s, i f (n) > 0, ∀ n ≥ 9.
ln(n5 + 1) − n
Exemplul 1.1.2. Funct, ia g : N \ {1, 6} → R, g(n) = , nu este
(n − 1)(n − 6)
asimptotic pozitivă, deoarece (n − 1)(n − 6) > 0, ∀ n ≥ 7, dar lim [ln(n5 +
n→∞
1) − n] = −∞, deci ∃ n0 ∈ N, n0 ≥ 7 a.ı̂. g(n) < 0, ∀ n ≥ n0 .
7
TEMA 1. ELEMENTE DE COMPLEX. ALG. S, I TEOR. GRAF. 8
dacă
f (n)
∃ lim = 1.
n→∞ g(n)
Definit, ia 1.1.3. Fie g o funct, ie a.p. (asimptotic pozitivă). Definim mult, imea
de funct, ii O (g) (sau O (g(n))) ca fiind
O (g) = f f = funct, ie a.p., ∃ c > 0, ∃ n0 ∈ N a.ı̂.
f (n) ≤ c · g(n), ∀ n ≥ n0 .
• Se cites, te:
Observat, ia 1.1.2. Ilustrarea grafică a notat, iei f ∈ O (g), s, i anume că pentru
n ≥ n0 graficul funct, iei c · g se află deasupra graficului funct, iei f , este dată
ı̂n Figura 1.1.1.
Definit, ia 1.1.4. Fie g o funct, ie a.p. (asimptotic pozitivă). Definim mult, imea
de funct, ii Ω(g) (sau Ω(g(n))) ca fiind
Ω(g) = f f = funct, ie a.p., ∃ c > 0, ∃ n0 ∈ N a.ı̂.
c · g(n) ≤ f (n), ∀ n ≥ n0 .
Figura 1.1.1:
• Se cites, te:
Observat, ia 1.1.3. Ilustrarea grafică a notat, iei f ∈ Ω(g), s, i anume că pentru
n ≥ n0 graficul funct, iei c · g se află sub graficul funct, iei f , este dată ı̂n Figura
1.1.2.
Definit, ia 1.1.5. Fie g o funct, ie a.p. (asimptotic pozitivă). Definim mult, imea
de funct, ii Θ(g) (sau Θ(g(n))) ca fiind
Θ(g) = f f = funct, ie a.p., ∃ c1 , c2 > 0, ∃ n0 ∈ N a.ı̂.
c1 · g(n) ≤ f (n) ≤ c2 · g(n), ∀ n ≥ n0 .
• Se cites, te:
Figura 1.1.2:
Observat, ia 1.1.4. Ilustrarea grafică a notat, iei f ∈ Θ(g), s, i anume că pentru
n ≥ n0 graficul funct, iei f este cuprins ı̂ntre graficele funct, iilor c1 · g s, i c2 · g,
este dată ı̂n Figura 1.1.3.
Figura 1.1.3:
atunci
a) f (n) = O (nk ), ∀ k ≥ p;
b) f (n) = Ω(nk ), ∀ k ≤ p;
c) f (n) = Θ(np ).
Observat, ia 1.1.6. Algoritmii polinomiali sunt, ı̂n general, acceptabili ı̂n prac-
tică. Algoritmii care necesită un timp de calcul exponent, ial sunt utilizat, i
numai ı̂n cazuri except, ionale s, i doar pentru date de intrare de dimensiuni
relativ mici.
• dacă nodul curent vi are succesori direct, i (adică noduri vj pentru care
există muchie sau arc de la vi la vj ) nevizitat, i, atunci se vizitează primul
astfel de nod vj ; nodul vj devine nod curent s, i se continuă procedeul de
parcurgere pornind din acest nod;
• dacă nodul curent nu mai are nici succesori direct, i nevizitat, i, nici prede-
cesor direct (deci este chiar radăcina x), atunci parcurgerea se ı̂ncheie.
1 2
3 4
Figura 1.2.1:
DF (2) : 2, 3, 1, 4, 5
(considerând că ordinea dintre succesorii direct, i ai fiecărui nod este ordinea
crescătoare). Arborele DF corespunzător acestei parcurgeri este reprezentat
ı̂n Figura 1.2.2.
TEMA 1. ELEMENTE DE COMPLEX. ALG. S, I TEOR. GRAF. 14
2 1
3 4 5 2
1 4 5
if ((A[x][y]>=1)&&(VIZ[y]==0))
{ TATA[y]=x;
DF_recursiv(y);
}
}
void main()
{ int x,i;
clrscr();
citire_graf();
for(i=1;i<=n;i++)
{ VIZ[i]=0; TATA[i]=0;
}
cout<<"Nodul de pornire: x=";cin>>x;
cout<<"Parcurgerea DF: ";
DF_recursiv(x);
cout<<"\nArborele DF este dat de vectorul TATA: ";
for (i=1;i<=n;i++) cout<<TATA[i]<<" ";
getch();
}
Exemplul 1.2.2. Pentru graful din Figura 1.2.1, fis, ierul de intrare ”graf2.dat”
folosit la citirea grafului ı̂n programul anterior cont, ine datele:
5 7 //5 noduri s, i 7 arce
1 2 //arcul (1, 2)
2 3 //arcul (2, 3)
2 4 //arcul (2, 4)
2 5 //arcul (2, 5)
3 1 //arcul (3, 1)
3 2 //arcul (3, 2)
5 4 //arcul (5, 4).
Algoritmul 1.2.2 (parcurgerea DF, nerecursiv). Fie din nou G = (V, E)
un graf având mult, imea de noduri V = {1, . . . , n} s, i matricea de adiacent, ă
A = (aij )i,j=1,n . Fie x ∈ V un nod arbitrar fixat. Pentru implementarea nere-
cursivă a parcurgerii DF (x) vom utiliza vectorii V IZ s, i T AT A cu aceleas, i
semnificat, ii ca ı̂n algoritmul anterior, un vector URM cu semnificat, ia
DF(x) :
VIZITEAZĂ(x); // se vizitează x, de exemplu se afis, ează x
V IZ[x] ← 1; // x a fost vizitat
T AT A[x] ← 0;
varf ← 1; S[varf ] ← x; // x se introduce ^ ın v^
arful stivei
while (varf > 0) do // stiva este nevidă
i ← S[varf ]; // i este nodul din v^ arful stivei
j ← URM[i] + 1; // j va fi următorul succesor direct
// nevizitat al lui i, dacă există
while (a[i, j] = 0) and (j ≤ n) do j ← j + 1;
if (j > n) then
// nodul i nu mai are succesori direct, i nevizitat, i
varf ← varf − 1; // s-a ^ıncheiat prelucrarea lui i
// s, i ^
ıl eliminăm din stivă
else
URM[i] ← j; // j este următorul succesor direct
// al lui i
if (V IZ[j] = 0) then // j nu a fost vizitat
VIZITEAZĂ(j); // se vizitează j
V IZ[j] ← 1; // j a fost vizitat
T AT A[j] ← i;
varf ← varf + 1;
S[varf ] ← j; // se introduce j ^ ın v^
arful stivei
unde funct, ia DF(i) este cea din Algoritmul 1.2.1 sau cea din Algoritmul
1.2.2, adăugând instruct, iunea CC[i] ← nrc ı̂n funct, ia VIZITEAZĂ(i).
Observat, ia 1.2.4. Algoritmul anterior poate fi utilizat s, i pentru determinarea
componentelor conexe ale unui graf orientat, ı̂nlocuind condit, ia ”axy ≥ 1” din
funct, ia DF RECURSIV(x) cu ”axy ≥ 1 sau ayx ≥ 1”, respectiv condit, ia
”aij = 0” din funct, ia DF(x) cu ”aij = 0 s, i aji = 0” (deoarece ı̂n determinarea
componentelor conexe nu se t, ine cont de orientarea arcelor).
Observat, ia 1.2.5. Dacă G = (V, E) este un graf orientat, atunci pentru orice
nod x ∈ V componenta tare-conexă a nodului x este (indusă de) mult, imea
nodurilor y vizitate prin parcurgerea DF (x) a grafului G cu proprietatea că
y este vizitat s, i ı̂n parcurgerea DF (x) a grafului
2 3
3 4 5 1 2
1 4 5
BF (3) : 3, 1, 2, 4, 5,
BF(x) :
VIZITEAZĂ(x);
V IZ[x] ← 1;
T AT A[x] ← 0;
coada ← 1; // nodurile se adaugă la S pe pozit, ia "coada "
varf ← 1; // s, i se elimină de pe pozit, ia "varf "
S[coada] ← x;
while (varf ≤ coada) do // coada este nevidă
i ← S[varf ];
j ← URM[i] + 1;
while (a[i, j] = 0) and (j ≤ n) do j ← j + 1;
if (j > n) then
varf ← varf + 1;
else
URM[i] ← j;
if (V IZ[j] = 0) then
VIZITEAZĂ(j);
V IZ[j] ← 1;
T AT A[j] ← i;
coada ← coada + 1;
S[coada] ← j;
Metoda Greedy
În continuare sunt prezentate două scheme de lucru, care urmează aceeas, i
idee, diferent, iindu-se doar prin ordinea de efectuare a unor operat, ii:
Algoritmul 2.1.1 (Metoda Greedy, varianta I).
22
TEMA 2. METODA GREEDY 23
• Dacă includerea elementului ales ı̂n solut, ia part, ială construită ante-
rior conduce la o solut, ie posibilă, atunci construim noua solut, ie prin
adăugarea elementului ales.
GREEDY1(A, n, B) :
B ← ∅;
for i = 1, n do
x ←ALEGE(A, i, n);
if SOLUTIE POSIBILA (B, x) then
B ← B ∪ {x};
Observat, ia 2.1.1.
• Funct, ia ALEGE este cea mai dificil de realizat, deoarece trebuie să
implementeze criteriul conform căruia alegerea la fiecare pas a câte
unui candidat să conducă ı̂n final la obt, inerea solut, iei optime.
GREEDY2(A, n, B) :
PRELUCREAZA (A, n);
B ← ∅;
for i = 1, n do
if SOLUTIE POSIBILA (B, ai ) then
B ← B ∪ {ai };
• Metoda Greedy nu caută să determine toate solut, iile posibile s, i apoi
să aleagă pe cea optimă conform criteriului de optimizare dat (ceea ce
ar necesita ı̂n general un timp de calcul s, i spat, iu de memorie mari), ci
constă ı̂n a alege pe rând câte un element, urmând să-l ”ı̂nghită” even-
tual ı̂n solut, ia optimă. De aici vine s, i numele metodei (Greedy = lacom).
• Astfel, dacă trebuie determinat maximul unei funct, ii de cost depinzând
de a1 , . . . , an , ideea generală a metodei este de a alege la fiecare pas acel
element care face să crească cât mai mult valoarea acestei funct, ii. Din
acest motiv metoda se mai numes, te s, i a optimului local.
• Optimul global se obt, ine prin alegeri succesive, la fiecare pas, ale op-
timului local, ceea ce permite rezolvarea problemelor fără revenire la
deciziile anterioare (as, a cum se ı̂ntâmplă la metoda backtracking).
• În general metoda Greedy oferă o solut, ie posibilă s, i nu ı̂ntotdeauna
solut, ia optimă. De aceea, dacă problema cere solut, ia optimă, algorit-
mul trebuie să fie ı̂nsot, it s, i de justificarea faptului că solut, ia generată
este optimă. Pentru aceasta, este frecvent ı̂ntâlnit următorul procedeu:
– se demonstrează prin induct, ie matematică faptul că pentru orice
pas i ∈ {0, 1, . . . , n}, dacă Bi este solut, ia posibilă construită la
pasul i, atunci există o solut, ie optimă B ∗ astfel ı̂ncât Bi ⊆ B ∗ ;
– se arată că pentru solut, ia finală, Bn , incluziunea Bn ⊆ B ∗ devine
egalitate, Bn = B ∗ , deci Bn este solut, ie optimă.
Exemplul 2.1.1. Se dă o mult, ime A = {a1 , a2 , . . . , an } cuPai ∈ R, i = 1, n. Se
cere să se determine o submult, ime B ⊆ A, astfel ı̂ncât b să fie maximă.
b∈B
Rezolvare. Dacă B ⊆ A s, i b0 ∈ B, cu b0 ≤ 0, atunci
X X
b≤ b.
b∈B b∈B\{b0 }
Rezultă că putem ı̂nt, elege prin solut, ie posibilă o submult, ime B a lui A
cu toate elementele strict pozitive.
Vom aplica metoda Greedy, ı̂n varianta I, ı̂n care
• funct, ia ALEGE furnizează x = ai ;
• funct, ia SOLUTIE POSIBILA returnează 1 (adevărat) dacă x > 0
s, i 0 (fals) ı̂n caz contrar.
TEMA 2. METODA GREEDY 25
ALEGE (A, i, n) :
x ← ai ;
returnează x;
SOLUTIE POSIBILA(B, x) :
if x > 0 then
returnează 1; // adevărat
else
returnează 0; // fals
a1 ≤ a2 ≤ . . . ≤ an s, i b1 ≤ b2 ≤ . . . ≤ bn , n ∈ N∗ .
Fie
M = max s(p). (2.2.2)
p∈Sn
(deoarece j > k, p(k) > k, iar s, irurile (ai )i=1,n s, i (bi )i=1,n sunt crescătoare).
Deci s(p′ ) ≥ s(p) = M.
Cum, conform (2.2.2), avem s(p′ ) ≤ M, rezultă că
s(p′ ) = s(p) = M
s(e) = M, (2.2.4)
a1 ≤ a2 ≤ . . . ≤ an s, i − bn ≤ −bn−1 ≤ . . . ≤ −b1
TEMA 2. METODA GREEDY 27
rezultă că n n
X X
ai · (−bp(i) ) ≤ ai · (−bn+1−i ),
i=1 i=1
adică n n
X X
ai · bn+1−i ≤ ai · bp(i) .
i=1 i=1
a1 , a2 , . . . , an s, i b1 , b2 , . . . , bn , n ∈ N∗ .
Se cere să se determine două permutări aq(1) , aq(2) , . . . , aq(n) s, i bp(1) , bp(2) , . . . , bp(n)
ale celor două s, iruri, q, p ∈ Sn (Sn = grupul permutărilor de ordin n), astfel
X n
ı̂ncât suma aq(i) · bp(i) să fie
i=1
a) maximă;
b) minimă.
n
X
Observat, ia 2.2.1. Suma aq(i) · bp(i) reprezintă produsul scalar al vecto-
i=1
rilor (aq(i) )i=1,n s, i (bp(i) )i=1,n . Astfel problema anterioară cere determinarea
unor permutări ale elementelor vectorilor (a1 , a2 , . . . , an ) s, i (b1 , b2 , . . . , bn ) ast-
fel ı̂ncât după permutare produsul lor scalar să fie maxim, respectiv minim.
Observat, ia 2.2.2. Algoritmul necesită câte două comparat, ii s, i câte cel mult
patru atribuiri pentru fiecare pereche de indici (i, j) cu i ∈ {1, 2, . . . , n} s, i
j ∈ {i + 1, i + 2, . . . , n}. Numărul acestor perechi este (n − 1) + (n − 2) +
n(n − 1)
···+2+1 = , deci algoritmul are complexitatea Θ(n2 ).
2
Algoritmul 2.2.2. Conform Teoremei 2.2.1 obt, inem s, i următoarea strategie
Greedy ı̂n varianta a II-a pentru rezolvarea problemei:
L1 , L2 , . . . , respectiv Ln .
La citirea unui text de pe bandă, trebuie citite s, i textele aflate ı̂naintea lui.
Presupunând că frecvent, a de citire a celor n texte este aceeas, i, se cere
să se determine o ordine de pozit, ionare (memorare) optimă a acestora pe
bandă, adică o pozit, ionare astfel ı̂ncât timpul mediu de citire să fie minim.
Modelarea problemei
• Evident, orice pozit, ionare a celor n texte pe bandă este o permutare a
vectorului (T1 , T2 , . . . , Tn ), adică are forma
• Evident, timpul de citire doar a unui text Tk este direct proport, ional cu
lungimea lui, deci putem considera că acest timp este egal cu lungimea
Lk a textului.
TEMA 2. METODA GREEDY 32
Modelarea problemei
• O solut, ie (solut, ie posibilă) a problemei este orice vector x = (x1 , . . . , xn )
astfel ı̂ncât
xi ∈ [0, 1], ∀ i ∈ {1, . . . , n},
Pn
xi gi ≤ G,
i=1
• Încărcăm obiectele ı̂n rucsac, ı̂n această ordine, cât timp nu se depăs, es, te
greutatea maximă G. Încărcarea obiectelor se face ı̂n ı̂ntregime, cât
timp este posibil; ı̂n acest fel doar ultimul obiect adăugat poate fi
ı̂ncărcat part, ial.
xi = x∗i , ∀ i a.ı̂. 1 ≤ i ≤ k − 1
xk ≥ x∗k .
xi = x∗∗
i , ∀ i ∈ {1, . . . , k},
deci relat, ia (2.3.4) este adevărată pentru k, ceea ce ı̂ncheie demonstrat, ia prin
induct, ie a acestei relat, ii.
Luând k = n ı̂n această relat, ie rezultă că există o solut, ie optimă x∗ =
(x∗1 , . . . , x∗n ) pentru care
f (x) = 50 + 40 + 20 + 33 + 4 = 147.
x′ = (1, 1, 1, 0, 1, 0, 1, 0, 0, 0),
f (x′ ) = 50 + 40 + 20 + 27 + 11 = 148.
Modelarea problemei
• O solut, ie (solut, ie posibilă) a problemei este orice submult, ime P ⊆
{I1 , . . . , In } astfel ı̂ncât
Ii ∩ Ij = ∅, ∀ Ii , Ij ∈ P, i 6= j
deci
a′1 < b′1 < a′2 < b′2 < · · · < a′m < b′m .
Rezultă că
Ii′ ∩ Ij′ = ∅, ∀ i, j ∈ {1, . . . , m}, i 6= j,
deci submult, imea P = {I1′ , . . . , Im ′
} a intervalelor selectate de algoritm este
o solut, ie a problemei. Rămâne să demonstrăm optimalitatea acestei solut, ii.
Demonstrăm prin induct, ie după k ∈ {0, 1, . . . , m} că există o solut, ie
optimă P ∗ = {I1∗ , . . . , Ip∗ } a problemei, p ∈ N∗ , cu
I1∗ = [a∗1 , b∗1 ], I2∗ = [a∗2 , b∗2 ], . . . , Ip∗ = [a∗p , b∗p ], b∗1 < b∗2 < · · · < b∗p , (2.4.2)
pentru care
Ii′ = Ii∗ , ∀ i a.ı̂. 1 ≤ i ≤ k. (2.4.3)
Pentru k = 0 afirmat, ia este evidentă, luând P ∗ orice solut, ie optimă a
problemei (s, i sortând intervalele componente Ii∗ crescător după extremităt, ile
b∗i ).
Presupunem (2.4.3) adevărată pentru k − 1, adică există o solut, ie optimă
P ∗ = {I1∗ , . . . , Ip∗ } a problemei, ce verifică (2.4.2), pentru care
p ≥ m ≥ k.
a∗1 < b∗1 < a∗2 < b∗2 < · · · < a∗k−1 < b∗k−1 < a∗k < b∗k <
< a∗k+1 < b∗k+1 < · · · < a∗p < b∗p . (2.4.7)
Pentru k ≥ 2 avem a′k > b′k−1 (din descrierea algoritmului) s, i b′k−1 = b∗k−1
′ ∗
(deoarece Ik−1 = Ik−1 ), deci
a′k > b∗k−1 . (2.4.8)
Din (2.4.7), (2.4.8) s, i (2.4.5) rezultă că
a∗1 < b∗1 < a∗2 < b∗2 < · · · < a∗k−1 < b∗k−1 < a′k < b′k <
< a∗k+1 < b∗k+1 < · · · < a∗p < b∗p
b∗∗ ∗∗ ∗∗
1 < b2 < · · · < bp .
TEMA 2. METODA GREEDY 44
Cum
card (P ∗∗ ) = p = card (P ∗)
s, i P ∗ este solut, ie optimă, rezultă că s, i P ∗∗ este solut, ie optimă.
Conform (2.4.6) s, i (2.4.4) avem
deci relat, ia (2.4.3) este adevărată pentru k, ceea ce ı̂ncheie demonstrat, ia prin
induct, ie a acestei relat, ii.
Luând k = m ı̂n această relat, ie rezultă că există o solut, ie optimă P ∗ =
{I1∗ , . . . , Ip∗ } pentru care
P = {I1′ , . . . , Im
′
} = {I1∗ , . . . , Ip∗ } = P ∗
Spectacol S1 S2 S3 S4 S5 S6 S7
Timp de ı̂ncepere ai 8:00 8:10 8:15 8:50 9:10 9:20 9:20
Timp de ı̂ncheiere bi 9:10 9:00 9:00 10:20 10:40 10:30 11:00
Spectacol S8 S9 S10 S11 S12 S13 S14
Timp de ı̂ncepere ai 10:45 11:00 12:00 12:10 12:30 13:00 13:40
Timp de ı̂ncheiere bi 12:00 12:30 13:30 14:00 13:50 14:30 15:00
Spectacol S2 S3 S1 S4 S6 S5 S7
Timp de ı̂ncepere ai 8:10 8:15 8:00 8:50 9:20 9:10 9:20
Timp de ı̂ncheiere bi 9:00 9:00 9:10 10:20 10:30 10:40 11:00
Spectacol S8 S9 S10 S12 S11 S13 S14
Timp de ı̂ncepere ai 10:45 11:00 12:00 12:30 12:10 13:00 13:40
Timp de ı̂ncheiere bi 12:00 12:30 13:30 13:50 14:00 14:30 15:00
Aplicarea strategiei Greedy din algoritmul de mai sus conduce la solut, ia
optimă dată de selectarea (vizionarea), ı̂n ordine, a spectacolelor:
• S2 (primul, ı̂n ordinea impusă),
• S6 (primul situat după S2 s, i care are timpul de ı̂ncepere mai mare decât
timpul de ı̂ncheiere al lui S2 ),
• S8 (primul situat după S6 s, i care are timpul de ı̂ncepere mai mare decât
timpul de ı̂ncheiere al lui S6 ),
• S12 (primul situat după S8 s, i care are timpul de ı̂ncepere mai mare
decât timpul de ı̂ncheiere al lui S8 ), după care nu mai urmează niciun
spectacol care să ı̂nceapă după ı̂ncheierea lui S12 , deci selectarea se
termină.
Numărul maxim de spectacole ce pot fi vizionate este deci egal cu 4.
Observat, ia 2.4.1. Algoritmul 2.4.1 are complexitatea O (n log2 n), deoarece
este necesară sortarea spectacolelor crescător după timpul lor de ı̂ncheiere,
iar blocul ”for” prin care se parcurg spectacolele se execută de n ori (câte
o dată pentru fiecare spectacol) s, i necesită de fiecare dată o comparat, ie, cel
mult o adunare s, i cel mult 3 operat, ii de atribuire.
Algoritmul 2.4.2. O altă rezolvare a problemei spectacolelor se obt, ine prin
utilizarea următoarei strategie Greedy, similară cu cea de mai sus.
• Ordonăm spectacolele descrescător după timpul lor de ı̂ncepere:
a1 ≥ a2 ≥ · · · ≥ an .
Observat, ia 2.5.1. Un graf ponderat are arbori part, iali de cost minim dacă s, i
numai dacă este conex.
Problema determinării arborilor part, iali de cost minim are numeroase
aplicat, ii practice. Prezentăm ı̂n continuare doi algoritmi fundamentali pentru
rezolvarea acestei probleme.
Algoritmul 2.5.1 (Kruskal). Fie (G, c) un graf ponderat conex cu G =
(V, E), V = {v1 , . . . , vn }. Algoritmul are n − 1 pas, i.
Algoritmul 2.5.2 (Prim). Fie (G, c) un graf ponderat conex cu G = (V, E),
V = {v1 , . . . , vn }. Algoritmul are n pas, i.
Ci = [xj , w0 , . . . , wk , xi , xj ]
µi = [xj , w0 , . . . , wk , xi ]
(obt, inut din ciclul Ci prin eliminarea muchiei ei ) cont, ine o muchie e′i = [x′ , y ′]
astfel ı̂ncât x′ este ı̂n aceeas, i componentă conexă cu xj ı̂n pădurea Ti−1 , iar y ′
nu este ı̂n această componentă conexă. Evident, rezultă că e′i nu este muchie
TEMA 2. METODA GREEDY 49
a lui Ti−1 , adică e′i 6∈ {e1 , . . . , ei−1 }, iar graful Ti′ = Ti−1 + e′i nu cont, ine
cicluri. De asemenea, e′i 6= ei , deci e′i ∈ F ∗ .
Pe de o parte, din descrierea Algoritmului Kruskal deducem că
c(ei ) ≤ c(e′i )
(deoarece muchia e′i nu formează cicluri cu {e1 , . . . , ei−1 }, deci ei fiind muchia
selectată la pasul i verifică această inegalitate).
Pe de altă parte, din descrierea Algoritmului Prim deducem că la pasul
i nodul x′ era deja selectat la un pas anterior (fiind ı̂n aceeas, i componentă
conexă cu xj ı̂n Ti−1 ), iar nodul y ′ nu era selectat la un pas anterior (nefiind
ı̂n acea componentă conexă), deci din nou avem
c(ei ) ≤ c(e′i )
T ⋆⋆ = (T ⋆ + ei ) − e′i
graful part, ial al lui G obt, inut din T ⋆ prin adăugarea muchiei ei s, i eliminarea
muchiei e′i , adică T ⋆⋆ = (V, F ⋆⋆ ), unde F ⋆⋆ = F ⋆ ∪ {ei } \ {e′i }.
Evident, T ⋆⋆ este conex (T ⋆ este conex iar ı̂ntre nodurile x′ s, i y ′ după eli-
minarea muchiei e′i rămâne lant, ul obt, inut din ciclul Ci prin eliminarea acestei
muchii) s, i are n−1 muchii (deoarece T ⋆ are n−1 muchii). Conform Teoremei
numărului ciclomatic rezultă că T ⋆⋆ este un arbore part, ial al grafului G.
Deoarece c(ei ) ≤ c(e′i ) obt, inem
c(T ⋆⋆ ) ≤ c(T ⋆ )
s, i cum T ⋆ este un APM rezultă că s, i T ⋆⋆ este un APM (s, i, ı̂n plus, c(T ⋆⋆ ) =
c(T ⋆ )). Cum Ti ⊆ T ⋆⋆ , demonstrat, ia prin induct, ie a relat, iei (2.5.1) este
completă.
Luând i = n − 1 ı̂n această relat, ie obt, inem că T ⊆ T ⋆ , unde T = Tn−1 =
(V, F ), F = {e1 , . . . , en−1 } (mult, imea muchiilor selectate de algoritm) iar T ⋆
este un APM. Dar T s, i T ⋆ au fiecare câte n − 1 muchii, deci T = T ⋆ s, i astfel
T este un APM al grafului dat.
Exemplul 2.5.1. Fie graful ponderat (G, c) reprezentat ı̂n Figura 2.5.1, unde
costul fiecărei muchii este scris lângă segmentul corespunzător acesteia.
TEMA 2. METODA GREEDY 50
30 50 100
1 2 3 4
20
90
70 60 6
110 70 120
0
15
5 80
40
10
7 8 9 10
100 30 130
Figura 2.5.1:
30 50
1 2 3 4
20
90
60 6
120
5
10
7 8 9 10
100 30
Figura 2.5.2:
TEMA 2. METODA GREEDY 51
Aplicarea Algoritmului Prim pentru acelas, i graf este evident, iată ı̂n ur-
mătorul tabel:
Pas Muchia selectată Costul ei Nodul selectat
0 - - 1
1 [1, 2] 30 2
2 [2, 3] 50 3
3 [3, 6] 20 6
4 [2, 5] 60 5
5 [5, 8] 10 8
6 [8, 9] 30 9
7 [6, 4] 90 4
8 [8, 7] 100 7
9 [4, 10] 120 10
Arborele part, ial de cost minim obt, inut este deci acelas, i cu cel obt, inut
prin aplicarea Algoritmului Kruskal.
Observat, ia 2.5.2. Algoritmii Kruskal s, i Prim sunt specifici metodei de
programare Greedy. Algoritmul Kruskal selectează muchii, ı̂n ordinea
crescătoare a costurilor, subgrafurile induse pe parcurs de acestea nefiind
neapărat conexe. Algoritmul Prim selectează muchii s, i noduri, nu neapărat
ı̂n ordinea crescătoare a costurilor muchiilor, iar subgrafurile induse pe par-
curs de muchiile selectate sunt conexe.
În implementări optime, se poate arăta că Algoritmul Kruskal are com-
plexitatea O (m ln n) (fiind necesară sortarea muchiilor după cost), iar Algo-
ritmul Prim are complexitatea O (n2 ) ı̂n cazul memorării grafului prin ma-
tricea de adiacent, ă (o astfel de implementare va fi prezentată ı̂n continuare),
unde n s, i m reprezintă numerele de noduri, respectiv de muchii ale grafului
dat. Graful fiind conex, m ≥ n − 1.
Pentru grafuri simple, m ≤ n(n−1) 2
. Folosind s, i inegalitatea ln n ≤ n − 1,
obt, inem că Algoritmul Kruskal este mai eficient pentru grafuri ”sărace” ı̂n
muchii, iar Algoritmul Prim este mai eficient pentru grafuri ”bogate” ı̂n
muchii.
Observat, ia 2.5.3. Pentru implementarea Algoritmului Kruskal, memorăm
graful ponderat conex (G, c), unde G = (V, E), V = {1, . . . , n}, E =
{e1 , . . . , em }, ı̂ntr-o matrice cu 3 linii s, i m coloane P = (pik ) i = 1, 3 având
k = 1, m
semnificat, ia:
Definit, ia 2.6.1. Fie (G, c) un graf ponderat, unde G = (V, E), V = {v1 , . . . ,
vn } iar c : E → R+ .
Exemplul 2.6.1. Fie graful ponderat (G, c) reprezentat ı̂n Figura 2.6.1.
10
5
5 5
3 5 4
15
10
5
Figura 2.6.1:
Observat, ia 2.6.5. Evident, pentru orice graf neorientat atât matricea distan-
t, elor directe cât s, i matricea distant, elor minime sunt matrice simetrice.
TEMA 2. METODA GREEDY 56
Observat, ia 2.6.6. Conform Observat, iei 2.6.1, putem să ı̂nlocuim termenul de
”drum” cu cel de ”drum elementar” ı̂n definit, ia anterioară.
Conform Observat, iei 2.6.2, punctul b) din definit, ia anterioară este o ex-
tindere a definit, iei distant, ei minime de la punctul b) al Definit, iei 2.6.1.
Conform Observat, iei 2.6.3, c⋆ii = 0 ∀ i ∈ {1, . . . , n}.
Exemplul 2.6.2. Matricele distant, elor directe, respectiv minime asociate gra-
fului din Exemplul 2.6.1 sunt
0 15 10 5 ∞ 0 15 10 5 10
∞ 0 ∞ ∞ ∞ ∞ 0 ∞ ∞ ∞
⋆
C = ∞ 5 0 ∞ 5 , C =
10 5 0 15 5 .
∞ 10 ∞ 0 5 10 10 20 0 5
5 5 ∞ ∞ 0 5 5 15 10 0
tjk + cjk ik = min{tj + cji |vj ∈ {vi1 , . . . , vik−1 }, vi ∈ V \ {vi1 , . . . , vik−1 }}.
(2.6.1)
Se ia
s, i se trece la pasul k + 1.
TEMA 2. METODA GREEDY 57
ti = c⋆si , ∀ i ∈ {1, . . . , n}
tik = c⋆sik ,
Deci
tik = c⋆sik
prin reducere la absurd. Într-adevăr, ı̂n caz contrar conform (2.6.3) am avea
c⋆sik < tik .
Cum q > k, din descrierea algoritmului avem tiq ≥ tik (deoarece valorile
tik sunt monoton crescătoare de la un pas la altul, induct, ie!). Utilizând
(2.6.4) am obt, ine
c⋆sik < tik ≤ tiq ≤ c⋆siq ,
ceea ce contrazice faptul că are loc inegalitatea c⋆siq ≤ c⋆sik (conform principiu-
lui optimalităt, ii al lui Bellman pentru subdrumul dintre vs s, i viq al drumului
minim µ⋆ ).
Demonstrat, ia prin induct, ie este ı̂ncheiată.
Evident, pentru orice nod vi rămas neselectat ı̂n urma executării ultimului
pas al algoritmului avem ti = ∞ = c⋆si .
Într-adevăr, dacă ar exista un drum elementar minim
µ = (vs = y0 , y1 , . . . , yp = vi ),
DIJKSTRA(s) :
for i = 1, n do // init, ializări
S[i] ← 0; t[i] ← ∞; T AT A[i] ← ∞;
t[s] ← 0; T AT A[s] ← 0; // s este nodul sursă
repeat
// selectăm următorul nod x, ^ ın ordinea crescătoare
// a distant, elor minime de la s la x
min ← ∞;
for i = 1, n do
if (S[i] = 0) and (t[i] < min) then
min ← t[i];
x ← i;
if (min < ∞) then // există x, ı
^l selectăm
S[x] ← 1;
for i = 1, n do // actualizăm vectorii t s, i T AT A
if (S[i] = 0) and (cxi < ∞) then
if (t[i] > t[x] + cxi ) then
t[i] ← t[x] + cxi ;
T AT A[i] ← x;
30 50 100
1 2 3 4
20
70 6
110
5
40
10
7 8 9 10
130
Figura 2.6.2:
• de la 1 la 1: [1];
• de la 1 la 2: [1, 2];
• de la 1 la 3: [1, 2, 3];
• de la 1 la 4: [1, 2, 3, 4];
• de la 1 la 5: [1, 5];
• de la 1 la 6: [1, 2, 3, 6];
• de la 1 la 7: [1, 7];
• de la 1 la 8: [1, 5, 8];
• de la 1 la 9: [1, 5, 9];
Exemplul 2.7.1. În Figura 2.7.1 este reprezentată o ret, ea R, capacităt, ile fiind
ment, ionate pe arce. Considerăm că această ret, ea are intrarea s = 1 s, i ies, irea
t = 6.
Figura 2.7.1:
TEMA 2. METODA GREEDY 63
Definit, ia 2.7.2. Fie R = (G, s, t, c) o ret, ea, unde G = (V, E). Un flux
ı̂n ret, eaua R este o funct, ie f : V × V → R ce verifică următoarele două
proprietăt, i:
f (i, j) = 0 ∀(i, j) 6∈ E,
deci, analog funct, iei capacitate c, s, i funct, ia flux f poate fi definită (restrânsă)
doar pe mult, imea arcelor ret, elei (adică f : E → R).
Observat, ia 2.7.2. Definit, iile s, i rezultatele din această sect, iune sunt valabile
s, i pentru ret, ele formate cu grafuri orientate oarecare (nu neapărat simple).
În acest caz general funct, iile capacitate s, i flux se definesc neapărat doar pe
colect, ia (multisetul) E a arcelor ret, elei.
Observat, ia 2.7.3. În particular, f (i, j) = 0 ∀i, j ∈ V este un flux ı̂n orice
ret, ea, numit fluxul nul.
Exemplul 2.7.2. Pentru ret, eaua din Figura 2.7.1, un exemplu de flux este
reprezentat ı̂n Figura 2.7.2. Pe fiecare arc (i, j) sunt ment, ionate fluxul f (i, j)
s, i capacitatea c(i, j), ı̂n această ordine.
Figura 2.7.2:
TEMA 2. METODA GREEDY 64
Lema 2.7.1. Fie R = (G, s, t, c) o ret, ea, unde G = (V, E). Pentru orice flux
f ı̂n ret, eaua R are loc egalitatea
!
X X X X
f (i, t) − f (t, i) = − f (i, s) − f (s, i) .
i∈V i∈V i∈V i∈V
Definit, ia 2.7.3. Fie R = (G, s, t, c) o ret, ea, unde G = (V, E). Pentru orice
flux f ı̂n ret, eaua R, numărul
!
X X X X
v(f ) = f (i, t) − f (t, i) = − f (i, s) − f (s, i)
i∈V i∈V i∈V i∈V
Definit, ia 2.7.7. Fie f un flux ı̂n ret, eaua R = (G, s, t, c) s, i fie µ un C-lant,
ı̂n ret, eaua R relativ la fluxul f .
b) Numărul
r(µ) = min{rµ (i, j) | (i, j) = arc al lui µ}
se numes, te capacitatea reziduală (reziduul) a C-lant, ului µ.
Observat, ia 2.7.4. Conform definit, iilor anterioare, pentru orice C-lant, µ avem
r(µ) > 0.
Exemplul 2.7.5. Pentru ret, eaua s, i fluxul reprezentate ı̂n Figura 2.7.2, lant, ul
µ = [1, 2, 3, 4, 5, 6] este un C-lant, . Reziduurile pe arcele acestui C-lant, sunt
rµ (4, 5) = 3 − 2 = 1, rµ (5, 6) = 7 − 2 = 5,
deci reziduul pe acest C-lant, este r(µ) = 1.
Definit, ia 2.7.8. Fie f un flux ı̂n ret, eaua R = (G, s, t, c). Un C-lant, de la s
la t ı̂n ret, eaua R relativ la fluxul f se numes, te lant, de cres, tere (ı̂n ret, eaua
R relativ la fluxul f ).
Exemplul 2.7.6. Lant, ul µ = [1, 2, 3, 4, 5, 6] din exemplul anterior este un lant,
de cres, tere.
Lema 2.7.2. Fie R = (G, s, t, c) o ret, ea, unde G = (V, E). Fie f un flux ı̂n
ret, eaua R s, i fie µ un lant, de cres, tere ı̂n ret, eaua R relativ la fluxul f . Atunci
funct, ia f ′ : V × V → R definită prin
f (i, j) + r(µ), dacă (i, j) este arc direct al lui µ,
′
f (i, j) = f (i, j) − r(µ), dacă (i, j) este arc invers al lui µ,
f (i, j), dacă (i, j) nu este arc al lui µ
Observat, ia 2.7.5. În contextul lemei anterioare, conform Observat, iei 2.7.4
avem
v(f ′ ) = v(f ) + r(µ) > v(f ).
Inegalitatea justifică denumirea lui µ drept lant, de cres, tere a fluxului f , iar
egalitatea justifică denumirea lui r(µ) drept capacitatea reziduală a lant, ului
µ.
Definit, ia 2.7.9. Fluxul f ′ definit ı̂n lema anterioară se numes, te fluxul
obt, inut prin mărirea fluxului f de-a lungul lant, ului de cres, tere
µ s, i se notează cu
f ′ = f ⊕ r(µ).
Exemplul 2.7.7. Pentru ret, eaua R s, i fluxul f reprezentate ı̂n Figura 2.7.2,
lant, ul µ = [1, 2, 3, 4, 5, 6] este un lant, de cres, tere având reziduul r(µ) = 1.
Fluxul f ′ = f ⊕ r(µ) obt, inut prin aplicarea lemei anterioare este reprezentat
ı̂n Figura 2.7.3. Valoarea acestui flux este v(f ′ ) = v(f ) + r(µ) = 8 + 1 = 9.
Figura 2.7.3:
Definit, ia 2.7.10. Fie R = (G, s, t, c) o ret, ea, unde G = (V, E). O sect, iune
(tăietură) ı̂n ret, eaua R este o pereche (S, T ), S, T ⊆ V , ce verifică urmă-
toarele proprietăt, i:
S ∪ T = V, S ∩ T = ∅,
s ∈ S, t ∈ T.
Observat, ia 2.7.6. Dacă (S, T ) este o sect, iune ı̂n ret, eaua R = (G, s, t, c), unde
G = (V, E), atunci V = S ∪ T este o partit, ie a mult, imii V a nodurilor ret, elei
(adică V = S ∪ T , S 6= ∅, T 6= ∅, S ∩ T = ∅) a.ı̂. s ∈ S s, i t ∈ T . Rezultă
TEMA 2. METODA GREEDY 67
că numărul de sect, iuni ale ret, elei R este egal cu numărul de submult, imi
S \ {s} ⊆ V \ {s, t}, deci cu
Definit, ia 2.7.11. Fie R = (G, s, t, c) o ret, ea, unde G = (V, E). Pentru
orice sect, iune (S, T ) ı̂n ret, eaua R, numărul
XX
c(S, T ) = c(i, j)
i∈S j∈T
Lema 2.7.3. Fie R = (G, s, t, c) o ret, ea. Pentru orice flux f s, i orice sect, iune
(S, T ) ı̂n ret, eaua R avem
XX
v(f ) = (f (i, j) − f (j, i))
i∈S j∈T
(adică valoarea fluxului este egală cu fluxul net ce traversează sect, iunea).
Lema 2.7.4. Fie R = (G, s, t, c) o ret, ea.
a) Pentru orice flux f s, i orice sect, iune (S, T ) ı̂n ret, eaua R avem
v(f ) ≤ c(S, T ).
b) Dacă f ∗ este un flux s, i (S ∗ , T ∗) este o sect, iune ı̂n ret, eaua R astfel ı̂ncât
v(f ∗ ) = c(S ∗ , T ∗ ),
deci conform Lemei 2.7.4 rezultă că f este un flux de valoare maximă ı̂n
ret, eaua R (iar (S, T ) este o sect, iune de capacitate minimă ı̂n ret, eaua R).
Observat, ia 2.7.8. Dacă se cunoas, te un flux f de valoare maximă ı̂ntr-o ret, ea
R, atunci formulele (2.7.4) determină o sect, iune (S, T ) de capacitate minimă,
deci orice algoritm pentru determinarea unui flux de valoare maximă bazat
pe caracterizarea dată ı̂n teorema anterioară rezolvă s, i problema determinării
unei sect, iuni de capacitate minimă.
TEMA 2. METODA GREEDY 69
Definit, ia 2.7.12. Fie f un flux ı̂n ret, eaua R = (G, s, t, c), unde G = (V, E).
Funct, ia r : V × V → R+ definită prin
c(i, j) − f (i, j), dacă f (i, j) < c(i, j),
r(i, j) = f (j, i), dacă f (j, i) > 0 s, i f (i, j) = c(i, j),
0, ı̂n rest
Exemplul 2.7.9. Pentru ret, eaua R s, i fluxul f ′ reprezentate ı̂n Figura 2.7.3,
graful rezidual Gf ′ este reprezentat ı̂n Figura 2.7.4, capacităt, ile reziduale
fiind ment, ionate pe arce.
(1, 4, 2, 3, 6) este un drum elementar ı̂n graful rezidual Gf ′ , deci µ′ =
[1, 4, 2, 3, 6] este un lant, de cres, tere ı̂n ret, eaua R relativ la fluxul f ′ .
TEMA 2. METODA GREEDY 70
Figura 2.7.4:
Conform rezultatelor de mai sus obt, inem următorul algoritm pentru de-
terminarea unui flux de valoare maximă ı̂ntr-o ret, ea.
Algoritmul 2.7.1 (Ford-Fulkerson). Fie R = (G, s, t, c) o ret, ea, unde G =
(V, E).
Conform Teoremei 2.7.1, schit, a algoritmului, descrisă ı̂n pseudocod, are
următoarea formă.
FORD FULKERSON :
f ← 0; // sau f ← f0 , unde f0 este un flux
// disponibil init, ial
repeat
if (EXISTĂ LANT , DE CRES , TERE) then
// există lant, uri de cres, tere
// relativ la fluxul curent f
µ ← LANT , DE CRES , TERE; // se determină
// un astfel de lant, de cres, tere
f ← f ⊕ r(µ); // se măres, te valoarea fluxului curent,
// de-a lungul lant, ului de cres, tere
while (EXISTĂ LANT , DE CRES , TERE);
// nu mai există lant, uri de cres, tere,
// deci fluxul curent este de valoare maximă
AFIS, ARE(f ); // se afis, ează fluxul de valoare maximă
În continuare detaliem implementarea acestui algoritm. Presupunem că
V = {1, 2, . . . , n}, s = 1, t = n,
TEMA 2. METODA GREEDY 71
cu n ≥ 2.
Pentru depistarea s, i memorarea eventualelor lant, uri de cres, tere relativ la
fluxul curent vom utiliza doi vectori SEL s, i T AT A având semnificat, ia
1, dacă există un C-lant, de la nodul s = 1 la nodul i,
SEL[i] =
0, ı̂n caz contrar,
∀i ∈ {1, . . . , n}.
Algoritmul descris ı̂n pseudocod are următoarea formă (detaliată).
TEMA 2. METODA GREEDY 72
FORD FULKERSON :
CITIRE RET , EA; // se cites, te ret, eaua dată
for i = 1, n do
for j = 1, n do fij ← 0; // fluxul init, ial
vmax ← 0; // valoarea fluxul maxim
repeat // se caută lant, uri de cres, tere a fluxului curent,
// folosind Observat, ia 2.7.9
CALCUL REZIDUURI; // se determină reziduul s, i
// graful rezidual ale ret, elei relativ la fluxul curent
SEL[1] ← 1; // se selectează nodul sursă
for i = 2, n do SEL[i] ← 0;
T AT A[1] ← 0; // pt. memorarea C-lant, urilor
// ce pornesc din nodul sursă
DF(1); // se parcurge graful rezidual, memor^ and
// C-lant, urile ce pornesc din nodul sursă;
// parcurgerea DF, poate fi ı ^nlocuită cu
// parcurgerea BF (Algoritmul Edmonds-Karp )
if (SEL[n] = 1) then // s-a selectat nodul destinat, ie,
// deci există lant, de cres, tere a fluxului
rmin ← ∞; // reziduul minim, de-a lungul
// lant, ului de cres, tere
DET LANT CR; // se determină lant, ul de cres, tere
// a fluxului s, i reziduul minim
MĂRIRE FLUX; // se măres, te fluxul curent, de-a
// lungul lant, ului de cres, tere
vmax ← vmax + rmin;; // se actualizează valoarea
// fluxului curent
while (SEL[n] = 1);
// nu mai există lant, uri de cres, tere a fluxului,
// deci fluxul curent este maxim
AFIS, ARE REZULTATE;
// se afis, ează fluxul maxim s, i valoarea sa,
// eventual s, i sect, iunea de capacitate minimă,
// calculată conform (2.7.4) astfel:
// S = {i ∈ {1, . . . , n} | SEL[i] = 1},
// T = {i ∈ {1, . . . , n} | SEL[i] = 0}
Funct, iile utilizate sunt descrise ı̂n continuare.
TEMA 2. METODA GREEDY 73
CALCUL REZIDUURI :
for i = 1, n do
for j = 1, n do
if (fij < cij ) then
rij ← cij − fij ;
else
if (fji > 0) then
rij ← fji ;
else
rij ← 0;
DF(i) : // recursiv
for j = 1, n do
if (rij > 0 and SEL[j] = 0) then
T AT A[j] ← i; SEL[j] ← 1;;
DF(j);
Fie f0 fluxul init, ial. Presupunem că toate componentele fluxului f0 sunt
numere ı̂ntregi, adică
f0 (i, j) ∈ N, ∀(i, j) ∈ E,
Deci
unde
cmax = max{c(i, j) | (i, j) ∈ E}
(capacitatea maximă a arcelor ret, elei). Conform Lemei 2.7.4 avem
Figura 2.7.5:
Figura 2.7.6:
TEMA 2. METODA GREEDY 76
Figura 2.7.7:
Figura 2.7.8:
Figura 2.7.9:
TEMA 2. METODA GREEDY 77
Figura 2.7.10:
Lant, urile succesive de cres, tere relativ la fluxul curent sunt evident, iate
prin ı̂ngros, are, s, i anume:
µ1 = [1, 2, 3, 5, 6],
µ2 = [1, 2, 3, 6],
µ3 = [1, 4, 3, 6],
µ4 = [1, 4, 5, 3, 6],
µ5 = [1, 4, 5, 6].
Fluxul reprezentat ı̂n Figura 2.7.10 este de valoare maximă, deoarece nu mai
există lant, uri de cres, tere ı̂n R relativ la acest flux. Valoarea acestui flux este
11.
Pentru acest flux maxim, avem C-lant, uri de la nodul sursă s = 1 doar
la nodurile 1 s, i 4, aceste C-lant, uri sunt evident, iate prin ı̂ngros, are ı̂n Figura
2.7.10. Conform (2.7.4) rezultă că
(S, T ) = ({1, 4}, {2, 3, 5, 6})
este o sect, iune de capacitate minimă ı̂n R.
Observat, ia 2.7.10. Algoritmul Ford-Fulkerson este specific metodei de pro-
gramare Greedy. Pentru o ret, ea cu n noduri s, i m arce având toate ca-
pacităt, ile numere ı̂ntregi s, i pentru un flux init, ial având toate componentele
numere ı̂ntregi, de exemplu fluxul nul, conform demonstrat, iei Teoremei 2.7.2
rezultă că numărul de lant, uri de cres, tere necesare măririi succesive a flux-
ului init, ial, până se ajunge la un flux de valoare maximă, este de cel mult
(n − 1)cmax , unde cmax este capacitatea maximă a arcelor ret, elei. Pentru
fiecare flux curent, algoritmul necesită calculul reziduurilor celor m arce,
parcurgerea acestora pentru depistarea unui eventual lant, de cres, tere, deter-
minarea acestui lant, (de lungime cel mult m) s, i mărirea fluxului curent de-a
TEMA 2. METODA GREEDY 78
lungul lant, ului de cres, tere, operat, ii având complexitatea O (m). Rezultă că
Algoritmul Ford-Fulkerson are complexitatea O (mncmax ).
Observat, ia 2.7.11. Pentru o ret, ea având toate capacităt, ile numere rat, ionale,
putem aplica Algoritmul Ford-Fulkerson astfel:
• se ı̂nmult, esc toate capacităt, ile arcelor cu numitorul lor comun M,
obt, inându-se o ret, ea având toate capacităt, ile numere ı̂ntregi;
• se determină un flux de valoare maximă ı̂n această ret, ea, aplicând Algo-
ritmul Ford-Fulkerson (pentru un flux init, ial având toate componentele
numere ı̂ntregi, de exemplu fluxul nul);
• se ı̂mpart toate componentele acestui flux prin M, obt, inându-se un flux
de valoare maximă ı̂n ret, eaua init, ială.
Evident, toate componentele acestui flux maxim s, i valoarea lui sunt numere
rat, ionale.
Teorema 2.7.3 (Ford-Fulkerson). Fie R = (G, s, t, c) o ret, ea. Are loc
egalitatea
max{v(f ) | f = flux ı̂n R} = min{c(S, T ) | (S, T ) = sect, iune ı̂n R}
(adică ı̂n orice ret, ea valoarea maximă a unui flux este egală cu capacitatea
minimă a unei sect, iuni).
Demonstrat, ie. Fie G = (V, E) s, i V = {v1 , . . . , vn }, cu v1 = s s, i vn = t.
(f )
Pentru orice flux f ı̂n R, notăm cu X (f ) = (Xij )i,j=1,n ∈ Rn×n matricea
definită prin
(f )
Xij = f (vi , vj ), ∀i, j ∈ {1, . . . , n}.
Conform Definit, iei 2.7.2 avem
(f )
0 ≤ Xij ≤ Cij , ∀i, j ∈ {1, . . . , n},
n
X (f ) X n
(f )
Xji = Xij , ∀i ∈ {2, . . . , n − 1},
j=1 j=1
unde
Cij = c(vi , vj ), ∀i, j ∈ {1, . . . , n}.
Deci X (f ) ∈ D, unde
(
n×n
D= X ∈R 0 ≤ Xij ≤ Cij , ∀i, j ∈ {1, . . . , n},
n n
)
X X
Xji − Xij = 0, ∀i ∈ {2, . . . , n − 1} .
j=1 j=1
TEMA 2. METODA GREEDY 79
avem v(f ) = F (X (f ) ).
Rezultă că un flux f ı̂n R este un flux de valoare maximă ı̂n R dacă s, i
numai dacă matricea X (f ) este un punct de maxim al funct, iei F (pe domeniul
D). F este o funct, ie reală de n2 variabile reale.
Cum F este o funct, ie continuă, iar mult, imea D este compactă (adică
ı̂nchisă s, i marginită), rezultă că F este mărginită s, i ı̂s, i atinge marginile, deci
există un punct de maxim X ∗ al funct, iei F (pe domeniul D).
∗
Rezultă că fluxul f ∗ definit prin X (f ) = X ∗ , adică
f ∗ : V × V → R, f ∗ (vi , vj ) = Xij∗ , ∀i, j ∈ {1, . . . , n},
este un flux de valoare maximă ı̂n ret, eaua R.
Conform Teoremei 2.7.1 rezultă că nu există lant, uri de cres, tere ı̂n ret, eaua
R relativ la fluxul f ∗ . Fie
(
S ∗ = {i ∈ V | există C-lant, uri de la s la i ı̂n R relativ la f ∗ },
T ∗ = {i ∈ V | nu există C-lant, uri de la s la i ı̂n R relativ la f ∗ }.
Conform demonstrat, iei Teoremei 2.7.1 rezultă că (S ∗ , T ∗ ) este o sect, iune ı̂n
ret, eaua R s, i
v(f ∗ ) = c(S ∗ , T ∗ ),
deci conform Lemei 2.7.4 rezultă că (S ∗ , T ∗ ) este o sect, iune de capacitate
minimă ı̂n ret, eaua R. Astfel avem
max{v(f ) | f = flux ı̂n R} = v(f ∗ ) = c(S ∗ , T ∗ )
= min{c(S, T ) | (S, T ) = sect, iune ı̂n R}
Acest lucru este realizat prin parcurgerea ı̂n lăt, ime (BF), pornind din
nodul sursă, a grafului rezidual relativ la fluxul curent.
Pentru a demonstra corectitudinea Algoritmului Edmonds-Karp, vom uti-
liza următoarea definit, ie.
Definit, ia 2.7.13. Fie f un flux ı̂n ret, eaua R = (G, s, t, c), unde G = (V, E).
Pentru orice două noduri i, j ∈ V notăm
min{l(µ) | µ = C-lant, de la i la j ı̂n R relativ la f }, dacă există
lf (i, j) = C-lant, uri de la i la j ı̂n R relativ la f ,
∞, ı̂n caz contrar,
Figura 2.7.11:
Figura 2.7.12:
Figura 2.7.13:
TEMA 2. METODA GREEDY 83
Figura 2.7.14:
Figura 2.7.15:
Lant, urile succesive de cres, tere relativ la fluxul curent sunt evident, iate
prin ı̂ngros, are, s, i anume:
µ1 = [1, 2, 3, 6],
µ2 = [1, 4, 3, 6],
µ3 = [1, 4, 5, 6],
µ4 = [1, 4, 3, 5, 6].
Fluxul reprezentat ı̂n Figura 2.7.15 este de valoare maximă, deoarece nu mai
există lant, uri de cres, tere ı̂n R relativ la acest flux. Valoarea acestui flux este
11.
Pentru acest flux maxim, avem C-lant, uri de la nodul sursă s = 1 doar
la nodurile 1 s, i 4, aceste C-lant, uri sunt evident, iate prin ı̂ngros, are ı̂n Figura
TEMA 2. METODA GREEDY 84
Pentru o ret, ea cu n noduri s, i m arce având toate capacităt, ile numere reale
s, i pentru un flux init, ial dat, de exemplu fluxul nul, conform Teoremei 2.7.4
rezultă că numărul de lant, uri de cres, tere necesare măririi succesive a fluxului
init, ial, până se ajunge la un flux de valoare maximă, este de cel mult mn 2
. Ca
s, i ı̂n cazul Algoritmului Ford-Fulkerson, pentru fiecare flux curent Algorit-
mul Edmonds-Karp necesită calculul reziduurilor celor m arce, parcurgerea
acestora (ı̂n lăt, ime) pentru depistarea unui eventual lant, de cres, tere, deter-
minarea acestui lant, (de lungime cel mult m) s, i mărirea fluxului curent de-a
lungul lant, ului de cres, tere, operat, ii având complexitatea O (m). Rezultă că
Algoritmul Edmonds-Karp are complexitatea O (m2 n).
Tema 3
Metoda Backtracking
x = (x1 , x2 , . . . , xn ) ∈ S1 × S2 × · · · × Sn ,
unde:
85
TEMA 3. METODA BACKTRACKING 86
Obt, inerea tuturor solut, iilor rezultat poate constitui o etapă intermediară
ı̂n rezolvarea unei alte probleme, urmând ca, ı̂n continuare, dintre acestea să
fie alese solut, iile care optimizează (minimizează sau maximizează) o anumită
funct, ie obiectiv dată.
Observat, ia 3.1.3. O variantă de determinare a solut, iilor rezultat ar putea fi
următoarea metodă, numită metoda fort, ei brute:
• se generează succesiv toate solut, iile posibile, adică toate elementele pro-
dusului cartezian S1 × S2 × · · · × Sn ;
• pentru fiecare solut, ie posibilă se verifică dacă sunt satisfăcute condit, iile
interne;
Această variantă are dezavantajul că timpul de execut, ie este foarte mare.
De exemplu, dacă card (Si ) = 2, i = 1, n, atunci spat, iul solut, iilor posibile
ar avea 2n elemente, iar complexitatea ar fi de ordinul Ω(2n ) (nesatisfăcătoa-
re!!).
Metoda Backtracking urmăres, te să evite generarea tuturor solut, iilor posibile,
ceea ce duce la scurtarea timpului de execut, ie.
Definit, ia 3.1.2. Fie k ∈ {1, . . . , n}. Un set de relat, ii definite pentru com-
ponenta xk ∈ Sk prin intermediul unor eventuale componente ale vectorului
(x1 , . . . , xk−1 ) ∈ S1 × S2 × · · · × Sk−1 repreintă condit, ii de continuare
pentru xk ı̂mpreună cu (x1 , . . . , xk−1 ) dacă:
adică
Sk = {ak , ak + rk , ak + 2rk , . . . , bk }, ∀ k = 1, n.
Pentru acest caz particular, vom prezenta ı̂n continuare s, ase variante pen-
tru schema Backtracking: s, i anume două variante iterative s, i patru variante
recursive.
Algoritmul 3.1.1 (Schema Backtracking iterativă, varianta 1).
BACKTRACKING1 :
k ← 1;
x[1] ← a[1] − r[1];// pregătim introducerea valorii init, iale a1
// pentru x1
while k > 0 do
if x[k] < b[k] then
// mai există valori netestate pentru xk
x[k]
← x[k] + r[k]; // Căutare
if (x[1], . . . , x[k]) verifică condit, iile de continuare then
if k = n then
// (x1 , . . . , xn ) este solut, ie rezultat
PRELUCREAZĂ(x[1], . . . , x[n]);
(*) // STOP, dacă se dores, te
// o singură solut, ie rezultat,
// sau k ← k − 1 (revenire fort, ată) dacă
// nu mai există valori valide pentru xn
else
k ← k + 1; // Avansare
x[k] ← a[k] − r[k]; // pregătim introducerea
// valorii init, iale ak pentru xk
else
// nu mai există valori netestate pentru xk
k ← k − 1; // Revenire
TEMA 3. METODA BACKTRACKING 90
Observat, ia 3.1.10. Schemele Backtracking de mai sus generează toate solut, iile
problemei date. Dacă se dores, te obt, inerea unei singure solut, ii, atunci ı̂n loc
de (∗) se poate insera o comandă de oprire (STOP).
Algoritmul 3.1.3 (Schema Backtracking recursivă, varianta 1).
TEMA 3. METODA BACKTRACKING 91
Apelare: BACKR1(1).
Următoarea schemă este echivalentă cu cea de mai sus.
Algoritmul 3.1.4 (Schema Backtracking recursivă, varianta 2).
BACKR2(k) :
if k ≤ n then
x[k] ← a[k] − r[k];
while x[k] < b[k] do
← x[k] + r[k];
x[k]
if (x[1], . . . , x[k]) verifică condit, iile de continuare then
BACKR2(k + 1);
else
PRELUCREAZĂ(x[1], . . . , x[n]);
Apelare: BACKR2(1).
Algoritmul 3.1.5 (Schema Backtracking recursivă, varianta 3).
TEMA 3. METODA BACKTRACKING 92
BACKR3(k) :
for v = a[k], b[k], r[k] do // Căutarea lui x[k] ^ ın mult, imea Sk
x[k]
← v;
if (x[1], . . . , x[k]) verifică condit, iile de continuare then
if k = n then
// (x[1], . . . , x[n]) este solut, ie rezultat
PRELUCREAZĂ(x[1], . . . , x[n]);
else
BACKR3(k + 1); // Avansare, adică
// se generează, RECURSIV, (x[k + 1], . . . , x[n]).
// La ^ ıncheierea apelului BACKR3(k + 1) se produce
// revenirea la funct, ia BACKR3(k)
Apelare: BACKR3(1).
Următoarea schemă este echivalentă cu cea de mai sus.
Algoritmul 3.1.6 (Schema Backtracking recursivă, varianta 4).
BACKR4(k) :
if k ≤ n then
for v = a[k], b[k], r[k] do
← v;
x[k]
if (x[1], . . . , x[k]) verifică condit, iile de continuare then
BACKR4(k + 1);
else
PRELUCREAZĂ(x[1], . . . , x[n]);
Apelare: BACKR4(1).
Observat, ia 3.1.11. Schemele Backtracking din Algoritmii 3.1.1, 3.1.2, 3.1.3 s, i
3.1.4 pot fi usor adaptate s, i pentru situat, i ı̂n care elementele fiecărei mult, imi
Sk nu sunt ı̂n progresie aritmetică.
Observat, ia 3.1.12. În oricare din cele s, ase scheme de mai sus, verificarea
(validarea) condit, ilor de continuare
considerându-se astfel că orice solut, ie posibilă verifică condit, iile interne, a-
tunci se vor obt, ine ca solut, ii rezultat ale problemei toate elementele produsu-
lui cartezian S1 × S2 × · · · × Sn .
Modelarea problemei
Orice solut, ie a problemei se poate scrie sub forma
x = (x1 , x2 , . . . , xn ),
xi 6= xj , ∀ [i, j] ∈ E.
TEMA 3. METODA BACKTRACKING 94
Modelarea problemei
Oricărei hărt, i i se poate asocia un graf neorientat simplu astfel:
• ı̂ntre două noduri există muchie dacă s, i numai dacă ele corespund unor
t, ări ce au frontieră comună.
2
1 2 1
4 5 3
4 3
5
6 6
Figura 3.2.1:
Modelarea problemei
În orice solut, ie rezultat, conform demonstrat, iei propozit, iei anterioare obt, inem
că pe fiecare linie a tablei se află exact o damă. Rezultă că orice solut, ie pentru
problema celor n dame se poate reprezenta sub forma unui vector
x = (x1 , x2 , . . . , xn ),
x = (1, 3, 5, 2, 4),
Figura 3.3.1:
Altfel spus, dacă avem solut, ia part, ială x = (x1 , . . . , xk−1 ), atunci xk nu
verifică condit, iile de continuare (nu este valid ) dacă
Considerat, ii
• Pentru n = 2 problema nu are solut, ie, deoarece două dame as, ezate
pe linii s, i coloane diferite se află pe aceeas, i diagonală, deci se atacă
reciproc.
• Nici pentru n = 3 problema nu are solut, ie, deoarece orice două dame
as, ezate pe o aceeas, i culoare se atacă reciproc.
TEMA 3. METODA BACKTRACKING 99
adică se as, ează o damă ı̂n colt, ul din dreapta sus (pătrăt, elul de coordonate
(1, n)) iar celelalte n − 1 dame se as, ează conform Cazului 3 ı̂n subtabla de
dimensiune (n − 1) × (n − 1) rămasă prin eliminarea primei linii s, i ultimei
coloane.
Conform Teoremei 3.3.1, Propozit, iei 3.3.1 s, i cazurilor n = 2 s, i n = 3
considerate mai sus obt, inem următorul rezultat.
TEMA 3. METODA BACKTRACKING 100
• Problema a fost expusă init, ial pentru tabla de s, ah obis, nuită 8 × 8 ı̂n
anul 1848 de către s, ahistul german Max Bezzel.
• Emil Pauls a fost primul care a demonstrat existent, a solut, iei pentru
orice n ≥ 4, ı̂n anul 1874, prin construct, ia din demonstrat, ia teoremei
de mai sus.
N = D1 ∪ D2 ∪ · · · ∪ Dn−1 , unde
Dk = {(l, c) | l + c = 2k + 1, 1 ≤ l ≤ n, 1 ≤ c ≤ n}, ∀k = 1, n − 1. (3.4.1)
TEMA 3. METODA BACKTRACKING 101
Rezultă că oricum as, ezăm mai mult de n − 1 nebuni pe pătrăt, ele de culoare
neagră există cel put, in doi nebuni as, ezat, i pe o aceeas, i diagonală Dk , s, i aces, tia
se atacă reciproc.
Pe de altă parte, mult, imea A a pătrăt, elelor de culoare albă poate fi parti-
t, ionată ı̂n următoarele diagonale (având, de asemenea, direct, ia stânga-jos →
dreapta-sus s, i ordonate crescător după distant, a fat, ă de colt, ul din stânga-sus):
A = D1 ∪ D2 ∪ · · · ∪ D n , unde
D k = {(l, c) | l + c = 2k, 1 ≤ l ≤ n, 1 ≤ c ≤ n}, ∀k = 1, n. (3.4.2)
Rezultă că oricum as, ezăm mai mult de n − 1 nebuni pe pătrăt, ele de culoare
albă, fie există cel put, in doi nebuni as, ezat, i pe o aceeas, i diagonală D k s, i aces, tia
se atacă reciproc, fie există câte cel put, in un nebun pe fiecare diagonală D k
s, i atunci nebunii de pe diagonalele D1 = {(1, 1)} s, i Dn = {(n, n)} se atacă
reciproc.
Modelarea problemei
Cazul 1) Considerăm cazul as, ezării celor n − 1 nebuni pe pătrăt, ele de culoare
neagră.
Pentru orice solut, ie rezultat, conform demonstrat, iei propozit, iei anterioare
obt, inem că pe fiecare din cele n − 1 diagonale Dk definite prin relat, ia (3.4.1)
se află exact un nebun.
Fiecare diagonală Dk , k = 1, n − 1. poate fi rescrisă astfel
Dk = {(l, c) | l + c = 2k + 1, 1 ≤ l ≤ n, 1 ≤ c ≤ n}
= {(l, 2k + 1 − l) | 1 ≤ l ≤ n, 1 ≤ 2k + 1 − l ≤ n}
= {(l, 2k + 1 − l) | 1 ≤ l ≤ n, 2k + 1 − n ≤ l ≤ 2k}
= {(l, 2k + 1 − l) | max{2k + 1 − n, 1} ≤ l ≤ min{2k, n}},
deci
hni
{(l, 2k + 1 − l) | 1 ≤ l ≤ 2k}, dacă 1 ≤ k ≤
,
Dk = 2
hni
{(l, 2k + 1 − l) | 2k + 1 − n ≤ l ≤ n}, dacă <k ≤n−1
2
([t] reprezintă partea ı̂ntreagă a numărului t ∈ R).
Pentru orice k ∈ {1, 2, . . . , n − 1}, coloana pe care se află nebunul de pe
diagonala Dk este
c = 2k + 1 − l,
TEMA 3. METODA BACKTRACKING 102
Figura 3.4.1:
xi − xj 6= ci − cj , ∀ i 6= j, i, j = 1, n − 1,
sau, echivalent,
xi − xj 6= 2i + 1 − xi − 2j − 1 + xj , ∀ i 6= j, i, j = 1, n − 1,
adică
xi − xj 6= i − j, ∀ i 6= j, i, j = 1, n − 1.
Condit, iile de continuare:
Dacă avem solut, ia part, ială (x1 , . . . , xk−1 ), atunci xk verifică condit, iile de
continuare (este valid ) dacă
xk − xi 6= k − i, ∀ i = 1, k − 1.
Altfel spus, dacă avem solut, ia part, ială x = (x1 , . . . , xk−1 ), atunci xk nu
verifică condit, iile de continuare (nu este valid ) dacă
NEBUNI1 (n) :
k ← 1;
x[1] ← 0;
ult ← 2; // ult este valoarea finală bk pentru xk
while k > 0 do
if x[k] < ult then
x[k] ← x[k] + 1;
if VALID1(x, k) then
if k = n − 1 then
AFISARE(x);
else
k ← k + 1;
// pregătim introducerea valorii init, iale ak s, i
// actualizăm valoarea finală bk pentru xk
n
if k ≤ then
2
x[k] ← 0;
ult ← 2k;
else
x[k] ← 2k − n;
ult ← n;
else
k ← k − 1;
// actualizăm valoarea finală bk pentru xk
n
if k ≤ then
2
ult ← 2k;
else
ult ← n;
Dk = {(l, c) | l + c = 2k, 1 ≤ l ≤ n, 1 ≤ c ≤ n}
= {(l, 2k − l) | 1 ≤ l ≤ n, 1 ≤ 2k − l ≤ n}
= {(l, 2k − l) | 1 ≤ l ≤ n, 2k − n ≤ l ≤ 2k − 1}
= {(l, 2k − l) | max{2k − n, 1} ≤ l ≤ min{2k − 1, n}},
deci
n+1
{(l, 2k − l) | 1 ≤ l ≤ 2k − 1}, dacă 2 ≤ k ≤ ,
2
Dk =
n + 1
{(l, 2k − l) | 2k − n ≤ l ≤ n}, dacă
< k ≤ n − 1.
2
y = (y1, y2 , . . . , yn−1),
unde
(
1, dacă primul nebun se află pe pătrăt, elul (1, 1),
y1 =
n, dacă primul nebun se află pe pătrăt, elul (n, n),
yi − yj 6= i − j, ∀ i 6= j, i, j = 2, n − 1.
În plus,
y1 ∈ {1, n} s, i yi 6= i, ∀ i = 2, n − 1
(nebunul de pe diagonala Di i = 2, n − 1, nu se poate afla pe diagonala dintre
pătrăt, elele (1, 1) s, i (n, n), deoarece s-ar ataca cu nebunul aflat pe unul din
aceste două pătrăt, elele).
Condit, iile de continuare:
Dacă avem solut, ia part, ială (y1 , . . . , yk−1 ), cu k ≥ 2, atunci yk verifică
condit, iile de continuare (este valid ) dacă
yk 6= k s, i yk − yi 6= k − i, ∀ i = 2, k − 1.
Altfel spus, dacă avem solut, ia part, ială (y1 , . . . , yk−1 ), cu k ≥ 2, atunci yk
nu verifică condit, iile de continuare (nu este valid ) dacă
else
k ← k − 1;
// actualizăm valoarea finală bk pentru yk
n+1
if k ≤ then
2
ult ← 2k − 1;
else
ult ← n;
VALID2(y, k) :
if y[k] = k then
returnează 0; // fals
for i = 2, k − 1 do
if y[k] − y[i] = k − i then
returnează 0; // fals
returnează 1; // adevărat
Considerat, ii
Teorema 3.4.1. Pentru orice n ≥ 2 problema nebunilor are cel put, in o
solut, ie.
Demonstrat, ie. Avem din nou următoarele două cazuri.
Cazul 1) Cei n − 1 nebuni trebuie as, ezat, i pe pătrăt, ele de culoare neagră.
Atunci o solut, ie este dată de as, ezarea celor n − 1 nebuni ı̂n pătrăt, elele de
coordonate (l, c) ce apart, in mult, imii
n−1 n−1
(1, 2i) | 1 ≤ i ≤ ∪ (n, 2i) | 1 ≤ i ≤ , dacă n este impar,
2 2
respectiv mult, imii
n no n no
(1, 2i) | 1 ≤ i ≤ ∪ (n, 2i − 1) | 2 ≤ i ≤ , dacă n este par.
2 2
Cazul 2) Cei n − 1 nebuni trebuie as, ezat, i pe pătrăt, ele de culoare albă.
Atunci o solut, ie este dată de as, ezarea celor n − 1 nebuni ı̂n pătrăt, elele de
coordonate (l, c) ce apart, in mult, imii
n+1 n−1
(1, 2i − 1) | 1 ≤ i ≤ ∪ (n, 2i − 1) | 2 ≤ i ≤ , dacă n este
2 2
impar, respectiv mult, imii
n no n no
(1, 2i − 1) | 1 ≤ i ≤ ∪ (n, 2i − 2) | 2 ≤ i ≤ , dacă n este par.
2 2
Conform Teoremei 3.4.1 s, i Propozit, iei 3.4.1 obt, inem următorul rezultat.
Corolarul 3.4.1. Numărul maxim de nebuni ce pot fi as, ezat, i pe pătrăt, ele de
aceeas, i culoare ale unei table de s, ah de dimensiune n × n, n ≥ 2, astfel ı̂ncât
oricare doi nebuni să nu se atace reciproc este egal cu n − 1.
TEMA 3. METODA BACKTRACKING 109
Evident, orice doi nebuni as, ezat, i pe pătrăt, ele de culori diferite nu se atacă
reciproc. Astfel, conform corolarului anterior obt, inem următorul rezultat.
Corolarul 3.4.2. Numărul maxim de nebuni ce pot fi as, ezat, i pe o tablă de
s, ah de dimensiune n × n, n ≥ 2, astfel ı̂ncât oricare doi nebuni să nu se
atace reciproc este egal cu 2n − 2.
Observat, ia 3.4.2. Pentru generarea tuturor modalităt, ilor de aranjare a 2n−2
nebuni pe o tablă de s, ah de dimensiune n × n astfel ı̂ncât oricare doi nebuni
să nu se atace reciproc putem proceda astfel:
Pentru aceasta putem utiliza funct, ia NEBUNI2 (n) din Algoritmul 3.4.2
ı̂n care ı̂nlocuim funct, ia AFISARE(y) cu funct, ia NEBUNI1 (n) din Algo-
ritmul 3.4.1.
a = a1 a2 . . . an , cu a1 , a2 , . . . , an ∈ A,
A1 × A2 × . . . × An = {(x1 , x2 , . . . , xn )|x1 ∈ A1 , x2 ∈ A2 , . . . , xn ∈ An }.
Exemplul 3.5.1. {a, b}×{+, −}×{c} = {(a, +, c), (a, −, c), (b, +, c), (b, −, c)}.
Propozit, ia 3.5.1 (de numărare a produsului cartezian). Fie n ∈ N⋆ s, i
A1 , A2 , . . . , An mult, imi finite. Atunci card (A1 × A2 × . . . × An ) = card (A1 ) ·
card (A2 ) · . . . · card (An ).
Demonstrat, ie. Se utilizează metoda induct, iei matematice după n.
Algoritmul 3.5.1 (de generare a produsului cartezian prin metoda
Backtracking). Fie mult, imile standard
x = (x1 , x2 , . . . , xn ) ∈ S1 × S2 × · · · × Sn ,
unde
S1 = A1 , S2 = A2 , · · · , Sn = An .
As, adar, mult, imile Sk , cont, in termeni succesivi ai unei progresii aritmeti-
ce, ı̂n care
ak = 1,
rk = 1, ∀ k = 1, n.
bk = mk ,
TEMA 3. METODA BACKTRACKING 111
Definim funct, iile α : P(A) → {1, 2}n s, i β : {1, 2}n → P(A) prin:
1, dacă ai ∈ B,
• ∀B ∈ P(A), α(B) = (x1 , x2 , . . . , xn ), unde xi =
2, dacă ai 6∈ B;
SUBMULT , IMI(a, n) :
k ← 1;
x[1] ← 0;
while k > 0 do
if x[k] < 2 then
x[k] ← x[k] + 1;
if k = n then
AFISARE(x, a, n);
else
k ← k + 1;
x[k] ← 0;
else
k ← k − 1;
3.5.5 Aranjamente
Propozit, ia 3.5.4 (de numărare a aranjamentelor). Fie m, n ∈ N.
Atunci numărul de cuvinte de lungime n cu litere distincte peste un alfa-
bet cu m litere este egal cu [m]n .
Demonstrat, ie. Fie A = {1, 2, . . . , m} s, i
Avem
n
C1 = (x1 , x2 , . . . , xn )|x1 ∈ {1, . . . , m},
x2 ∈ {1, . . . , m} \ {x1 },
x3 ∈ {1, . . . , m} \ {x1 , x2 },
...,
o
xn ∈ {1, . . . , m} \ {x1 , . . . , xn−1 } ,
[m]n = m . . . (m − m) . . . (m − n + 1) = 0.
(1, 2), (1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1), (3, 2), (3, 4), (4, 1), (4, 2), (4, 3).
x = (x1 , x2 , . . . , xn ) ∈ S1 × S2 × · · · × Sn ,
unde
S1 = S2 = · · · = Sn = A.
As, adar, mult, imile Sk , cont, in termeni succesivi ai unei progresii aritmeti-
ce, ı̂n care
ak = 1,
rk = 1, ∀ k = 1, n.
bk = m,
Condit, iile interne:
xi 6= xj , ∀ i 6= j, i, j = 1, n.
ARANJAMENTE1(m, n) :
k ← 1;
x[1] ← 0;
while k > 0 do
if x[k] < m then
x[k] ← x[k] + 1;
if VALID(x, k) then
if k = n then
AFISARE(x, n);
else
k ← k + 1;
x[k] ← 0;
else
k ← k − 1;
TEMA 3. METODA BACKTRACKING 116
VALID(x, k) :
for i = 1, k − 1 do
if x[k] = x[i] then
returnează 0; // fals
returnează 1; // adevărat
Funct, ia de afis, are este, din nou:
AFISARE(x, n) :
for i = 1, n do
afis, ează x[i];
Algoritmul 3.5.5 (de generare a aranjamentelor prin metoda Back-
tracking, varianta 2). Putem ı̂mbunătăt, i algoritmul anterior prin uti-
lizarea unui vector (y1 , y2 , . . . , ym ) cu semnificat, ia: dacă avem solut, ia part, ială
(x1 , . . . , xk−1 ), atunci
(
1, dacă i ∈ {x1 , . . . , xk−1 },
yi = ∀i = 1, m.
0, dacă i 6∈ {x1 , . . . , xk−1 },
yxk = 0.
ARANJAMENTE2(m, n) :
for i = 1, m do y[i] ← 0; // init, ial, solut, ia part, ială este
// vectorul vid
k ← 1;
x[1] ← 0;
while k > 0 do
if x[k] < m then
x[k] ← x[k] + 1;
if y[x[k]] = 0 then // x[k] verifică condit, iile
// de continuare
if k = n then
AFISARE(x, n);
else
y[x[k]] ← 1; // ^
ınainte de avansare, se adaugă
// x[k] la solut, ia part, ială
k ← k + 1;
x[k] ← 0;
else
k ← k − 1;
y[x[k]] ← 0; // după revenire, se elimină
// x[k] din solut, ia part, ială
3.5.6 Permutări
Propozit, ia 3.5.5 (de numărare a permutărilor). Fie n ∈ N. Atunci
numărul de cuvinte ce cont, in exact o dată fiecare literă a unui alfabet cu n
litere este egal cu n!, unde
n! = 1 · 2 · 3 · · · · · n (n factorial), 0! = 1.
TEMA 3. METODA BACKTRACKING 118
VALID(x, k) :
for i = 1, k − 1 do
if x[k] = x[i] then
returnează 0; // fals
returnează 1; // adevărat
TEMA 3. METODA BACKTRACKING 119
3.5.7 Combinări
Propozit, ia 3.5.6 (de numărare a combinărilor). Fie m, n ∈ N. Atunci
numărul de cuvinte strict crescătoare de lungime n peste un alfabet (or-
donat) cu m litere
= numărul de submult, imi cu n elemente ale unei mult, imi cu m elemente
TEMA 3. METODA BACKTRACKING 120
[m]n def m
= = .
n! n
Demonstrat, ie. Fie A = {1, 2, . . . , m}. Notăm mult, imile din enunt, astfel:
Aceste funct, ii sunt inverse una celeilalte, deci sunt bijective s, i astfel
(c1 , c2 , c3 ) ∈ C3 S ∈ S3
(1,2,3) {1, 2, 3}
(1,2,4) {1, 2, 4}
(1,2,5) {1, 2, 5}
(1,3,4) {1, 3, 4}
(1,3,5) {1, 3, 5}
(1,4,5) {1, 4, 5}
(2,3,4) {2, 3, 4}
(2,3,5) {2, 3, 5}
(2,4,5) {2, 4, 5}
(3,4,5) {3, 4, 5}.
5 [5]3 5·4·3
Deci avem = = = 10 combinări.
3 3! 1·2·3
Algoritmul 3.5.8 (de generare a combinărilor prin metoda Backtrack-
ing). Fie mult, imea standard A = {1, 2, . . . , m} s, i n ≤ m.
Vom utiliza metoda Backtracking. Fie solut, ia (combinarea)
x = (x1 , x2 , . . . , xn ).
deci
xn ≤ m, xn−1 ≤ m − 1, xn−2 ≤ m − 2, . . . , x2 ≤ m − n + 2, x1 ≤ m − n + 1.
Astfel
x1 ∈ S1 = {1, 2, . . . , m − n + 1},
x2 ∈ S2 = {x1 + 1, x1 + 2, . . . , m − n + 2},
...
xk ∈ Sk = {xk−1 + 1, xk−1 + 2, . . . , m − n + k},
...
xn ∈ Sn = {xn−1 + 1, xn−1 + 2, . . . , m}.
As, adar, mult, imile Sk , cont, in termeni succesivi ai unei progresii aritmeti-
ce, ı̂n care
ak = xk−1 + 1,
rk = 1, ∀ k = 1, n,
bk = m − n + k,
TEMA 3. METODA BACKTRACKING 122
considerând x0 = 0.
Prin alegerea mult, imilor S1 , S2 , . . . , Sn am eliminat verificarea condit, iilor
de continuare.
COMBINĂRI(m, n) :
k ← 1;
x[1] ← 0;
while k > 0 do
if x[k] < m − n + k then
x[k] ← x[k] + 1;
if k = n then
AFISARE(x, n);
else
k ← k + 1;
x[k] ← x[k − 1];
else
k ← k − 1;
considerând x0 = 1.
Prin alegerea mult, imilor S1 , S2 , . . . , Sn am eliminat verificarea condit, iilor
de continuare.
COMBINĂRI CU REPETIT , IE(m, n) :
k ← 1;
x[1] ← 0;
while k > 0 do
if x[k] < m then
x[k] ← x[k] + 1;
if k = n then
AFISARE(x, n);
else
k ← k + 1;
x[k] ← x[k − 1] − 1;
else
k ← k − 1;
• pentru fiecare alegere de mai sus, alegem cei t2 indici (din restul de
n − t1
n − t1 ) ai literelor egale cu 2, rezultă moduri posibile, deci
t2
n n − t1
obt, inem moduri posibile de alegere a indicilor literelor
t1 t2
1 s, i 2;
• ...
• pentru fiecare alegere de mai sus, alegem cei tm indici (din restul de
n − t1 − . . . − tm−1
n−t1 −. . .−tm−1 ) ai literelor egale cu m; rezultă
tm
moduri posibile, deci obt, inem
n n − t1 n − t1 − . . . − tm−1
...
t1 t2 tm
Astfel
n n − t1 n − t1 − . . . − tm−1
card (C5 ) = ...
t1 t2 tm
n! (n − t1 )! (n − t1 − . . . − tm−1 )!
= · ·...·
t1 !(n − t1 )! t2 !(n − t1 − t2 )! tm !(n − t1 − . . . − tm )!
n!
=
t1 !t2 ! . . . tm !
(deoarece (n − t1 − . . . − tm )! = 0! = 1).
Definit, ia 3.5.9. Cuvintele numărate ı̂n propozit, ia anterioară se numesc
permutări cu repetit, ie (anagrame)
de nluate câte t1 , t2 , . . . , tm . De
n
asemenea s, i numărul lor, adică , se numes, te tot permutări
t1 , t2 , . . . , tm
cu repetit, ie de n luate câte t1 , t2 , . . . , tm .
Observat
, ia 3.5.10. Luând t1 = t2 = · · · = tm = 1 obt, inem n = m s, i
n
= n!, deci permutările (fără repetit, ie) sunt un caz particu-
1, 1, . . . , 1
lar
al permutărilor cu repetit, ie. Pe de altă parte, luând m = 2 obt, inem
n n!
= , deci s, i combinările (fără repetit, ie) sunt un caz particular
t1 , t2 t1 !t2 !
al permutărilor cu repetit, ie.
TEMA 3. METODA BACKTRACKING 126
(1, 1, 2, 3), (1, 1, 3, 2), (1, 2, 1, 3), (1, 2, 3, 1), (1, 3, 1, 2), (1, 3, 2, 1),
(2, 1, 1, 3), (2, 1, 3, 1), (2, 3, 1, 1), (3, 1, 1, 2), (3, 1, 2, 1), (3, 2, 1, 1).
4 4!
Deci avem = = 12 permutări cu repetit, ie.
2, 1, 1 2!1!1!
Algoritmul 3.5.10 (de generare a permutărilor cu repetit, ie prin meto-
da Backtracking, varianta 1). Fie mult, imea standard A = {1, 2, . . . , m},
t1 , t2 , . . . , tm ∈ N s, i n = t1 + t2 + · · · + tm .
Vom utiliza metoda Backtracking. Avem
x = (x1 , x2 , . . . , xn ) ∈ S1 × S2 × · · · × Sn ,
unde
S1 = S2 = · · · = Sn = A.
As, adar, mult, imile Sk , cont, in termeni succesivi ai unei progresii aritmeti-
ce, ı̂n care
ak = 1,
rk = 1, ∀ k = 1, n.
bk = m,
Condit, iile interne:
VALID(p, x, k) : // p = t[x[k]]
q ← 0; // q reprezintă card ({i|i = 1, k − 1, x[i] = x[k]})
if p = 0 then returnează 0;
for i = 1, k − 1 do
if x[i] = x[k] then
q ← q + 1;
if q ≥ p then returnează 0;
returnează 1;
Funct, ia de afis, are este, din nou:
AFISARE(x, n) :
for i = 1, n do
afis, ează x[i];
Algoritmul 3.5.11 (de generare a permutărilor cu repetit, ie prin me-
toda Backtracking, varianta 2). Putem ı̂mbunătăt, i algoritmul anterior
prin utilizarea unui vector (y1, y2 , . . . , ym ) cu semnificat, ia: dacă avem solut, ia
part, ială (x1 , . . . , xk−1 ), atunci
Fort, ând din nou revenirea după determinarea fiecărei permutări cu repetit, ie,
obt, inem următorul algoritm.
PERMUTĂRI CU REPETIT , IE2(n, t, m) :
n ← 0;
for i = 1, m do n ← n + t[i];
for i = 1, m do y[i] ← 0; // init, ial, solut, ia part, ială este
// vectorul vid
k ← 1;
x[1] ← 0;
while k > 0 do
if x[k] < m then
x[k] ← x[k] + 1;
if y[x[k]] < t[x[k]] then // x[k] verifică condit, iile
// de continuare
if k = n then
AFISARE(x, n);
k ← k − 1;
y[x[k]] ← y[x[k]] − 1; // după fort, area revenirii,
// se elimină x[k] din solut, ia part, ială
else
y[x[k]] ← y[x[k]] + 1; // ^ınainte de avansare, se
// adaugă x[k] la solut, ia part, ială
k ← k + 1;
x[k] ← 0;
else
k ← k − 1;
y[x[k]] ← y[x[k]] − 1; // după revenire, se elimină
// x[k] din solut, ia part, ială
• Divide: Problema dată este ı̂mpărt, ită ı̂n două sau mai multe subpro-
bleme de acelas, i tip, dar de dimensiuni mai mici.
P (m1 ), . . . , P (ma )
129
TEMA 4. METODA DIVIDE ET IMPERA 130
după care, combinând solut, iile celor a subprobleme, se obt, ine solut, ia
dorită a ı̂ntregii probleme P (n).
Algoritmul poate fi descris recursiv astfel:
DIVIMP(n, S) : // Rezolvarea problemei P (n)
if n ≤ n0 then
PRELUCREAZA(n, S); // Rezolvarea se face direct,
// rezult^ and solut, ia S a problemei P (n)
else
DESCOMPUNERE(n, a, m); // Se descompune problema,
// adică se determină m1 , . . . , ma
for i = 1, a do
DIVIMP(mi , si ); // Se obt, ine solut, ia si pentru
// subproblema P (mi )
COMBINA(s, a, S); // Se combină solut, iile s1 , . . . , sa ,
and solut, ia S a problemei P (n)
// rezult^
(ap , . . . , am ) s, i
(am+1 , . . . , aq ),
după care, combinând rezultatele celor două prelucrări, se obt, ine pre-
lucrarea dorită a ı̂ntregii secvent, e (ap , . . . , aq ).
TEMA 4. METODA DIVIDE ET IMPERA 131
DIVIMP(1, n, S).
PRELUCREAZA(p, q, S)
• Procedura
COMBINA(S1 , S2 , S)
realizează combinarea rezultatelor S1 , S2 ale prelucrării celor două sub-
secvent, e vecine (p, m) s, i (m + 1, q), obt, inându-se rezultatul S al pre-
lucrării secvent, ei (p, q).
DESCOMPUNERE(p, q, m).
TEMA 4. METODA DIVIDE ET IMPERA 132
• nu este permisă as, ezarea unui disc peste unul cu diametru mai mic.
Modelarea problemei
Vom nota o mutare cu perechea (i, j), ceea ce semnifică faptul că se mută un
disc de pe tija i pe tija j (i, j ∈ {1, 2, 3}).
Dacă n = 1, solut, ia directă este mutarea (1, 2).
Dacă n = 2, o solut, ie este formată din mutările (1, 3), (1, 2), (3, 2).
Dacă n > 2, problema se complică.
Notăm cu H(m, i, j) s, irul mutărilor necesare pentru a muta primele m
discuri de pe tija i pe tija j, folosind pentru manevre cealaltă tijă k := 6−i−j.
(Avem i + j + k = 1 + 2 + 3 = 6.)
Rezultă că, pentru problema noastră, avem de determinat s, irul H(n, 1, 2).
Avem
(i, j), dacă m = 1,
H(m, i, j) =
H(m − 1, i, k), (i, j), H(m − 1, k, j), dacă m ≥ 2.
TEMA 4. METODA DIVIDE ET IMPERA 133
HANOI(n, 1, 2).
1, dacă n = 1,
M(n) =
M(n − 1) + 1 + M(n − 1), dacă n ≥ 2,
1, dacă n = 1,
=
2 · M(n − 1) + 1, dacă n ≥ 2.
obt, inem că s, irul (M(n) + 1)n≥1 este o progresie geometrică având rat, ia 2 s, i
primul termen M(1) + 1 = 2, deci M(n) + 1 = 2n , ∀ n ≥ 1 s, i astfel se obt, ine
că
M(n) = 2n − 1, ∀ n ≥ 1.
Rezultă că timpul de execut, ie al algoritmului este
T (n) = Θ(2n ),
1 + 2(2n−1 − 1) = 2n − 1.
Modelarea problemei
Memorăm suprafat, a pătrată ı̂ntr-o matrice S = (sij )i,j=1,n , fiecare pătrat
unitar fiind deci reprezentat de un element al acestei matrice.
Evident, o acoperire cu piese de forma dată utilizează un număr de
n2 − 1 4k − 1
=
3 3
piese.
n2 − 1
Considerăm că piesele sunt numerotate cu 1, 2, . . . , s, i că as, ezarea
3
piesei numărul i constă ı̂n completarea elementelor corespunzătoare
din ma-
n2 − 1
tricea S cu numărul i al piesei, pentru fiecare valoare i ∈ 1, 2, . . . , .
3
Pentru rezolvarea problemei utilizăm următoarea strategie Divide et Im-
pera:
TEMA 4. METODA DIVIDE ET IMPERA 136
• Una dintre cele patru suprafet, e are deja un pătrat unitar acoperit.
• Acoperim cu o placă trei pătrate unitare din centrul suprafet, ei mari ast-
fel ı̂ncât să acoperim câte un pătrat unitar s, i din celelalte trei suprafet, e.
Un exemplu ı̂n acest sens este redat ı̂n Figura 4.3.1.
Figura 4.3.1:
• Fiecare dintre cele patru suprafet, e este acum ı̂n condit, iile problemei,
deci pentru fiecare suprafat, ă se repetă procedeul de descompunere des-
cris anterior.
Obt, inem următorul algoritm Divide et Impera, descris ı̂n pseudocod, pen-
tru rezolvarea problemei.
Algoritmul 4.3.1.
TEMA 4. METODA DIVIDE ET IMPERA 137
138
TEMA 5. METODA PROGRAMĂRII DINAMICE 139
Deci este de preferat ca relat, iile de recurent, ă să fie rezolvate prin imple-
mentări nerecursive, utilizând strategia bottom-up, cu memorarea temporară
a solut, iilor optime ale subproblemelor.
Prezentăm o schemă generală de lucru:
• Se alege o structură de date ı̂n care se memorează solut, iile optime ale
problemei s, i subproblemelor.
Observat, ia 5.1.1. Presupunem că solut, iile optime ale subproblemelor sunt
memorate ı̂ntr-un tablou
a1 , a2 , . . . , an , n ≥ 1.
lungimea maximă a unui subs, ir crescător este egală cu 4 (nu există subs, iruri
crescătoare de lungime 5), iar un subs, ir crescător de lungime maximă este,
de exemplu,
2, 3, 4, 8.
Modelarea problemei
i = n, n − 1, . . . , 2, 1.
construit astfel:
t1 = min {i | L[i] = k},
i=1,n
SUBSIRMAX1(A, n) :
L[n] ← 1;
for i = n − 1, 1, −1 do
L[i] ← 1;
P [i] ← −1;
for j = i + 1, n do
if (aj ≥ ai ) and (1 + L[j] > L[i]) then
L[i] ← 1 + L[j];
P [i] ← j;
k ← L[1];
t1 ← 1;
for i = 2, n do
if (L[i] > k) then
k ← L[i];
t1 ← i;
for j = 2, k do
tj ← P [tj−1];
for j = 1, k do
afis, ează atj ;
Exemplul 5.2.2. La aplicarea algoritmului anterior pentru s, irul din Exemplul
5.2.1 avem n = 10,
L[10] = 1;
L[9] = 1, P [9] = −1;
L[8] = 2, P [8] = 9;
L[7] = 3, P [7] = 8;
L[6] = 1, P [6] = −1;
L[5] = 3, P [5] = 8;
L[4] = 2, P [4] = 6;
L[3] = 4, P [3] = 5;
L[2] = 1, P [2] = −1;
L[1] = 2, P [1] = 2,
deci lungimea maximă a unui subs, ir crescător este
k=4
iar un subs, ir crescător de lungime maximă este dat de indicii
t1 = 3, t2 = P [t1 ] = 5, t3 = P [t2 ] = 8, t4 = P [t3 ] = 9,
TEMA 5. METODA PROGRAMĂRII DINAMICE 143
P [i] = mult, imea indicilor tuturor elementelor care sunt succesori direct, i ai
lui ai ı̂ntr-un subs, ir crescător de lungime maximă care ı̂ncepe cu ai
construit astfel:
t1 ∈ {i = 1, n | L[i] = k},
tj ∈ P [tj−1], ∀j ∈ {2, . . . , k}.
Pentru generarea tuturor acestor vectori (t1 , t2 , . . . , tk ) se poate utiliza metoda
Backtracking.
TEMA 5. METODA PROGRAMĂRII DINAMICE 144
L[10] = 1;
L[9] = 1, P [9] = ∅;
L[8] = 2, P [8] = {9, 10};
L[7] = 3, P [7] = {8};
L[6] = 1, P [6] = ∅;
L[5] = 3, P [5] = {8};
L[4] = 2, P [4] = {6, 9, 10};
L[3] = 4, P [3] = {5, 7};
L[2] = 1, P [2] = ∅;
L[1] = 2, P [1] = {2, 6},
deci lungimea maximă a unui subs, ir crescător este k = 4 iar orice subs, ir
crescător de lungime maximă este dat de indicii
i = 1, 2, . . . , n − 1, n.
construit astfel:
tk = min {i | L[i] = k},
i=1,n
tj = P [tj+1], ∀j ∈ {k − 1, . . . , 1}.
Obt, inem următorul algoritm de programare dinamică ı̂n varianta ı̂nainte,
descris ı̂n pseudocod, pentru rezolvarea problemei.
Algoritmul 5.2.2.
TEMA 5. METODA PROGRAMĂRII DINAMICE 146
SUBSIRMAX2(A, n) :
L[1] ← 1;
for i = 2, n do
L[i] ← 1;
P [i] ← −1;
for j = 1, i − 1 do
if (aj ≤ ai ) and (1 + L[j] > L[i]) then
L[i] ← 1 + L[j];
P [i] ← j;
L[1] = 1;
L[2] = 2, P [2] = −1;
L[3] = 1, P [3] = −1;
L[4] = 2, P [4] = 3;
L[5] = 2, P [5] = 3;
L[6] = 3, P [6] = 4;
L[7] = 2, P [7] = 3;
L[8] = 3, P [8] = 5;
L[9] = 4, P [9] = 8;
L[10] = 4, P [10] = 8,
k=4
TEMA 5. METODA PROGRAMĂRII DINAMICE 147
iar un subs, ir crescător de lungime maximă este at1 ≤ at2 ≤ · · · ≤ atk dat de
indicii
t4 = 9, t3 = P [t4 ] = 8, t2 = P [t3 ] = 5, t1 = P [t2 ] = 3,
adică subs, irul
2, 4, 4, 9.
Observat, ia 5.2.3. Analog algoritmului de la Metoda 1, s, i algoritmul anterior
are complexitatea Θ(n2 ).
Observat, ia 5.2.4. Printr-un procedeu similar celui descris ı̂n Observat, ia 5.2.2,
s, i algoritmul anterior poate fi adaptat pentru determinarea tuturor subs, iru-
rilor crescătoare de lungime maximă.
A = (aij ) i = 1, m , m, n ∈ N∗ .
j = 1, n
un drum de sumă maximă este format din elementele ı̂ncadrate ı̂n cercuri,
având suma 240.
TEMA 5. METODA PROGRAMĂRII DINAMICE 148
Pentru aceeas, i matrice, un drum de sumă minimă este format din ele-
mentele ı̂ncadrate ı̂n pătrate, având suma 135.
Modelarea problemei
a) Considerăm problema drumului de sumă maximă.
Metoda 1) Utilizăm programarea dinamică, varianta ı̂napoi. Considerăm
subproblemele constând ı̂n determinarea a câte unui drum de sumă maximă
care ı̂ncepe cu elementul aij (s, i se ı̂ncheie cu un element de pe ultima linie),
pentru orice i ∈ {1, 2, . . . , m} s, i orice j ∈ {1, 2, . . . , n}.
Pentru memorarea solut, iilor subproblemelor utilizăm două matrice S =
(S[i, j]) i = 1, m s, i P = (P [i, j]) i = 1, m − 1 având semnificat, ia
j = 1, n j = 1, n
Evident,
S[m, j] = amj , ∀ j ∈ {1, . . . , n}
s, i pentru orice i ∈ {1, . . . , m − 1} avem
Relat, iile de recurent, ă de mai sus exprimă elementul S[i, j] ı̂n funct, ie de
elementele de pe linia următoare S[i + 1, j − 1], S[i + 1, j], S[i + 1, j + 1].
Rezolvarea relat, iei de recurent, ă a elementelor S[i, j] s, i calculul elementelor
P [i, j] conform strategiei bottom-up revine la calculul acestor elemente ı̂n or-
dinea inversă a liniilor, adică
i = m, m − 1, . . . , 2, 1.
construit astfel:
t1 = min {j | S[1, j] = M},
j=1,n
DRUMMAX1(A, m, n) :
for j = 1, n do S[m, j] ← amj ;
for i = m − 1, 1, −1 do
P [i, 1] ← 0;
if S[i + 1, 2] > S[i + 1, 1] then P [i, 1] ← 1;
S[i, 1] ← ai1 + S[i + 1, 1 + P [i, 1]];
for j = 2, n − 1 do
P [i, j] ← −1;
if S[i + 1, j] > S[i + 1, j − 1] then P [i, j] ← 0;
if S[i + 1, j + 1] > S[i + 1, j + P [i, j]] then P [i, j] ← 1;
S[i, j] ← aij + S[i + 1, j + P [i, j]];
P [i, n] ← −1;
if S[i + 1, n] > S[i + 1, n − 1] then P [i, n] ← 0;
S[i, n] ← ain + S[i + 1, n + P [i, n]];
M ← S[1, 1];
t1 ← 1;
for j = 2, n do
if S[1, j] > M then
M ← S[1, j];
t1 ← j;
for i = 2, m do // (*)
ti ← ti−1 + P [i − 1, ti−1 ];
afis, ează M;
for i = 1, m do
afis, ează aiti ;
Exemplul 5.3.2. La aplicarea algoritmului anterior pentru matricea A din
Exemplul 5.3.1 avem
235 235 215 240 225 230
195 195 205 195 205 180
145 150 165 165 135 120
S= ,
125 105 100 115 105 110
80 90 80 75 85 90
40 20 15 20 10 10
0 1 0 −1 0 −1
1 1
0 −1 −1 −1
P = 0 −1 1
0 −1 0 .
1 0 −1 1 1 0
0 −1 −1 0 −1 −1
TEMA 5. METODA PROGRAMĂRII DINAMICE 151
Avem
t1 = min {j | S[1, j] = M} = 4,
j=1,6
t2 = t1 + P [1, t1 ] = 4 + P [1, 4] = 4 − 1 = 3,
t3 = t2 + P [2, t2 ] = 3 + P [2, 3] = 3 + 0 = 3,
t4 = t3 + P [3, t3 ] = 3 + P [3, 3] = 3 + 1 = 4,
t5 = t4 + P [4, t4 ] = 4 + P [4, 4] = 4 + 1 = 5,
t6 = t5 + P [5, t5 ] = 5 + P [5, 5] = 5 − 1 = 4,
deci drumul de sumă maximă produs de algoritm are elementele
a1t1 = a14 = 35, a2t2 = a23 = 40, a3t3 = a33 = 50,
a4t4 = a44 = 30, a5t5 = a55 = 65, a6t6 = a64 = 20.
Observat, ia 5.3.1. Pentru calculul fiecărui element al matricelor S s, i P sunt
necesare câte o atribuire s, i cel mult două comparat, ii, deci algoritmul are
complexitatea Θ(mn).
Observat, ia 5.3.2. Problema poate fi rezolvată s, i fără utilizarea matricei P .
În acest caz, pentru determinarea unui drum de sumă maximă ı̂nlocuim
instruct, iunea (∗) cu următoarea secvent, ă de instruct, iuni:
for i = 1, m − 1 do
if (ti > 1) and (S[i + 1, ti − 1] = S[i, ti ] − aiti ) then
ti+1 ← ti − 1; // cobor^ are de forma ւ
else
if S[i + 1, ti ] = S[i, ti ] − aiti then
ti+1 ← ti ; // cobor^ are de forma ↓
else
ti+1 ← ti + 1; // cobor^ are de forma ց
de sumă
M = max S[1, j],
j=1,n
construit astfel:
t1 ∈ {j = 1, n | S[1, j] = M},
ti ∈ {ti−1 + k | k ∈ P [i − 1, ti−1 ]}, ∀i ∈ {2, . . . , m}.
Pentru generarea tuturor acestor vectori (t1 , t2 , . . . , tm ) se poate utiliza metoda
Backtracking.
De exemplu, pentru matricea A din Exemplul 5.3.1 avem
235 235 215 240 225 230
195 195 205 195 205 180
145 150 165 165 135 120
S= ,
125 105 100 115 105 110
80 90 80 75 85 90
40 20 15 20 10 10
{0, 1} {1} {0} {−1, 1} {0} {−1}
{1} {1} {0, 1} {−1, 0} {−1} {−1}
P = {0} {−1}
{1} {0} {−1} {0} .
{1} {0} {−1} {1} {1} {0}
{0} {−1} {−1, 1} {0} {−1} {−1, 0}
TEMA 5. METODA PROGRAMĂRII DINAMICE 153
t1 ∈ {j = 1, 6 | S[1, j] = M} = {4},
t2 ∈ {4 + k | k ∈ P [1, 4]} = {3, 5},
pentru t2 = 3 : t3 ∈ {3 + k | k ∈ P [2, 3]} = {3, 4},
pentru t2 = 5 : t3 ∈ {5 + k | k ∈ P [2, 5]} = {4},
pentru t3 = 3 : t4 ∈ {3 + k | k ∈ P [3, 3]} = {4},
pentru t3 = 4 : t4 ∈ {4 + k | k ∈ P [3, 4]} = {4},
t5 ∈ {4 + k | k ∈ P [4, 4]} = {5},
t6 ∈ {5 + k | k ∈ P [5, 5]} = {4},
deci drumurile de sumă maximă sunt
(a14 = 35, a23 = 40, a33 = 50, a44 = 30, a55 = 65, a64 = 20),
(a14 = 35, a23 = 40, a34 = 50, a44 = 30, a55 = 65, a64 = 20),
(a14 = 35, a25 = 40, a34 = 50, a44 = 30, a55 = 65, a64 = 20),
deci avem 3 solut, ii (drumuri de sumă maximă).
Metoda 2) Utilizăm programarea dinamică, varianta ı̂nainte. Considerăm
subproblemele constând ı̂n determinarea a câte unui drum de sumă maximă
care se ı̂ncheie cu elementul aij (s, i se ı̂ncepe cu un element de pe prima linie),
pentru orice i ∈ {1, 2, . . . , m} s, i orice j ∈ {1, 2, . . . , n}.
Pentru memorarea solut, iilor subproblemelor utilizăm din nou două ma-
trice S = (S[i, j]) i = 1, m s, i P = (P [i, j]) i = 1, m − 1 având acum semnificat, ia
j = 1, n j = 1, n
Evident,
S[1, j] = a1j , ∀ j ∈ {1, . . . , n}
s, i pentru orice i ∈ {2, . . . , m} avem
Relat, iile de recurent, ă de mai sus exprimă elementul S[i, j] ı̂n funct, ie de
elementele de pe linia anterioară S[i − 1, j − 1], S[i − 1, j], S[i − 1, j + 1].
Rezolvarea relat, iei de recurent, ă a elementelor S[i, j] s, i calculul elementelor
P [i, j] conform strategiei bottom-up revine la calculul acestor elemente ı̂n or-
dinea directă a liniilor, adică
i = 1, 2, . . . , m − 1, m.
construit astfel:
tm = min {j | S[m, j] = M},
j=1,n
Avem
t6 = min {j | S[6, j] = M} = 4,
j=1,6
t5 = t6 − P [5, t6 ] = 4 − P [5, 4] = 4 + 1 = 5,
t4 = t5 − P [4, t5 ] = 5 − P [4, 5] = 5 − 1 = 4,
t3 = t4 − P [3, t4 ] = 4 − P [3, 4] = 4 − 1 = 3,
t2 = t3 − P [2, t3 ] = 3 − P [2, 3] = 3 − 0 = 3,
t1 = t2 − P [1, t2 ] = 3 − P [1, 3] = 3 + 1 = 4,
for i = m, 2, −1 do
if (ti > 1) and (S[i − 1, ti − 1] = S[i, ti ] − aiti ) then
ti−1 ← ti − 1; // cobor^ are de forma ց
else
if S[i − 1, ti ] = S[i, ti ] − aiti then
ti−1 ← ti ; // cobor^ are de forma ↓
else
ti−1 ← ti + 1; // cobor^ are de forma ւ
Evident,
S[m, j] = amj , ∀ j ∈ {1, . . . , n}
TEMA 5. METODA PROGRAMĂRII DINAMICE 158
Relat, iile de recurent, ă de mai sus exprimă elementul S[i, j] ı̂n funct, ie de
elementele de pe linia următoare S[i + 1, j − 1], S[i + 1, j], S[i + 1, j + 1].
Rezolvarea relat, iei de recurent, ă a elementelor S[i, j] s, i calculul elementelor
P [i, j] conform strategiei bottom-up revine la calculul acestor elemente ı̂n or-
dinea inversă a liniilor, adică
i = m, m − 1, . . . , 2, 1.
construit astfel:
t1 = min {j | S[1, j] = M},
j=1,n
TEMA 5. METODA PROGRAMĂRII DINAMICE 159
Avem
t1 = min {j | S[1, j] = M} = 3,
j=1,6
t2 = t1 + P [1, t1 ] = 3 + P [1, 3] = 3 − 1 = 2,
t3 = t2 + P [2, t2 ] = 2 + P [2, 2] = 2 − 1 = 1,
t4 = t3 + P [3, t3 ] = 1 + P [3, 1] = 1 + 1 = 2,
t5 = t4 + P [4, t4 ] = 2 + P [4, 2] = 2 − 1 = 1,
t6 = t5 + P [5, t5 ] = 1 + P [5, 1] = 1 + 1 = 2,
Relat, iile de recurent, ă de mai sus exprimă elementul S[i, j] ı̂n funct, ie de
elementele de pe linia anterioară S[i − 1, j − 1], S[i − 1, j], S[i − 1, j + 1].
Rezolvarea relat, iei de recurent, ă a elementelor S[i, j] s, i calculul elementelor
P [i, j] conform strategiei bottom-up revine la calculul acestor elemente ı̂n or-
dinea directă a liniilor, adică
i = 1, 2, . . . , m − 1, m.
construit astfel:
tm = min {j | S[m, j] = M},
j=1,n
DRUMMIN2(A, m, n) :
for j = 1, n do S[1, j] ← a1j ;
for i = 1, m − 1 do
P [i, 1] ← 0;
if S[i, 2] < S[i, 1] then P [i, 1] ← −1;
S[i + 1, 1] ← ai+1,1 + S[i, 1 − P [i, 1]];
for j = 2, n − 1 do
P [i, j] ← 1;
if S[i, j] < S[i, j − 1] then P [i, j] ← 0;
if S[i, j + 1] < S[i, j − P [i, j]] then P [i, j] ← −1;
S[i + 1, j] ← ai+1,j + S[i, j − P [i, j]];
P [i, n] ← 1;
if S[i, n] < S[i, n − 1] then P [i, n] ← 0;
S[i + 1, n] ← ai+1,n + S[i, n − P [i, n]];
M ← S[m, 1];
tm ← 1;
for j = 2, n do
if S[m, j] < M then
M ← S[m, j];
tm ← j;
for i = m − 1, 1, −1 do // (*)
ti ← ti+1 − P [i, ti+1 ];
afis, ează M;
for i = 1, m do
afis, ează aiti ;
Exemplul 5.3.5. La aplicarea algoritmului anterior pentru matricea A din
Exemplul 5.3.1 avem
40 30 10 35 20 25
75 40 50 40 60 65
60 65 90 90 60 70
S= 95 75 75 90 75 80 ,
115 125 135 130 140 155
155 135 140 150 140 150
−1 −1 0 1 0 1
−1 0 1 0 1 1
P = 0 1 1 −1 0 1 .
−1 0 1 1 0 1
0 1 1 0 1 1
TEMA 5. METODA PROGRAMĂRII DINAMICE 164
Avem
t6 = min {j | S[6, j] = M} = 2,
j=1,6
t5 = t6 − P [5, t6 ] = 2 − P [5, 2] = 2 − 1 = 1,
t4 = t5 − P [4, t5 ] = 1 − P [4, 1] = 1 + 1 = 2,
t3 = t4 − P [3, t4 ] = 2 − P [3, 2] = 2 − 1 = 1,
t2 = t3 − P [2, t3 ] = 1 − P [2, 1] = 1 + 1 = 2,
t1 = t2 − P [1, t2 ] = 2 − P [1, 2] = 2 + 1 = 3,
165
Tema 7
Algoritmi euristici
166