Sunteți pe pagina 1din 52

UNIVERSITATEA TEHNICĂ A MOLDOVEI

ASPECTE ALGORITMICE DIN TEORIA GRAFURILOR


PRIVIND FLUX MAXIM ŞI DRUMURI MINIME (MAXIME)

Îndrumar metodic la disciplinele "Matematici speciale" şi


"Structuri de date şi algoritmi"

Chişinău
2018

0
UNIVERSITATEA TEHNICĂ A MOLDOVEI

FACULTATEA CALCULATOARE, INFORMATICĂ ȘI


MICROELECTRONICĂ
DEPARTAMENTUL INFORMATICĂ ȘI INGINERIA
SISTEMELOR
DEPARTAMENTUL INGINERIA SOFTWARE ȘI
AUTOMATICĂ

ASPECTE ALGORITMICE DIN TEORIA GRAFURILOR


PRIVIND FLUX MAXIM ŞI DRUMURI MINIME (MAXIME)

Îndrumar metodic la disciplinele "Matematici speciale" şi


"Structuri de date şi algoritmi"


Chişinău
Editura „Tehnica-UTM”
2018
1
Prezenta lucrare conține îndrumări metodice și sarcini pentru
lucrările practice și lucrările de laborator destinate studiului
utilizării structurilor de date, cum ar fi tabloul bidimensional,
tabloul unidimensional de pointeri, lista simplu înlănțuită și coada
pentru implementarea algoritmilor de determinare a fluxului maxim
și drumurilor minime (maxime) între două vârfuri ale unui graf
arbitrar. Sunt prezentate exemple în limbajul C pentru
implementarea algoritmilor menţionaţi.
Lucrarea este destinată studenților Facultății Calculatoare,
Informatică şi Microelectronică, învățământ cu frecvență și cu
frecvență redusă, care studiază disciplinele „Structuri de date și
algoritmi” și „Matematici speciale”.

Autori: conf. univ., dr. G. Marusic


conf. univ., dr.N. Falico
conf. univ., dr. M. Kulev
asist. univ., mag. T. Tiholaz

Redactor responsabil: conf. univ., dr. M. Kulev

Recenzent: conf. univ., dr. V. Moraru

 UTM, 2018

2
INTRODUCERE

În lucrare sunt prezentate aspecte algoritmice din teoria


grafurilor privind fluxul maxim în reţele de transport și drumuri
minime (maxime). Din mai mulți algoritmi similari au fost selectați
algoritmii, care sunt mai ușor de implementat în limbajul C. Este de
remarcat faptul că studenții au însușit cursul relevant „Programarea
calculatoarelor”. Cu toate acestea, simplitatea de implementare nu
afectează eficacitatea acestor programe.
Prima parte a prezentei lucrări include implementarea în
limbajul C a algoritmului Ford-Folkerson de determinare a fluxului
maxim. Ideea algoritmului este următoarea: inițial, valoarea fluxului
este setată la 0. Treptat, valoarea fluxului crește iterativ prin
căutarea unui drum în creștere (drumul de la sursa s la nodul t, de-a
lungul căruia poate fi trimis un flux mai mare). Procesul dat se
repetă, până devine posibil de a găsi un drum în creștere [1-5].
Implementarea algoritmului este realizată în forma anologică cu
programele prezentate în lucrarea [6]. Algoritmul nu specifică care
anume drum este căutat sau modalitatea de căutare. Din acest motiv,
algoritmul este garantat să se convertească numai pentru mărimile
întregi ale capacităților arcelor unui graf și chiar pentru aceștia el
poate funcționa prea mult timp. Exemplul [3] demonstrează că
algoritmul Ford-Fulkerson, care folosește o căutare în adâncime,
este extrem de lent în comparație cu implementarea care utilizează
căutarea în lățime. Atunci când se utilizează căutarea în lățime
pentru acest exemplu, algoritmul va avea nevoie doar de doi pași,
spre deosebire de căutarea în adâncime, unde răspunsul va fi obținut
abia după 2000 de iterații [7]. În îndrumar se prezintă
implementarea folosind căutarea în lățime. Se utilizează structura
coadă, care este studiată în cadrul cursului „Structuri și algoritmi de
date”.
A doua parte a lucrării prezintă algoritmul pentru
determinarea drumului minim (maxim) într-un graf orientat. De
fapt, Ford a inventat acest algoritm în 1956 în timp ce studia o altă
problemă matematică, subproblema căruia s-a redus la găsirea celui
3
mai scurt drum într-un graf, iar Ford a propus o schiță de principiu a
algoritmului, care rezolvă această problemă. Bellman, în 1958, a
publicat un articol dedicat în mod specific problemei găsirii celui
mai scurt drum, iar în acest articol el a formulat clar algoritmul în
forma în care ne este cunoscut acum. În îndrumar este prezentată
implementarea în limbajul C a algoritmului pentru aflarea drumului
minim prin metoda Ford. În acest caz programul alocă memoria
dinamică pentru toate matricele. Al doilea program implementează
o abordare unificată a algoritmului Bellman-Ford ca algoritmul
programării dinamice. Implementarea algoritmului Bellman-Calaba
se reduce la implementarea lui Ford, dar pe un graf cu o matrice de
distanțe transpusă. A fost adăugată o condiție pentru detectarea
buclelor cu pondere negativă, pentru care este imposibil să se
găsească drumul minim din graf. Ca și în primul capitol, este
folosită o coadă pentru a găsi toate drumurile minime. În algoritmul
Bellman-Ford implementarea funcției standard de relaxare de-a
lungul muchiei este realizată astfel încât să se găsească căile
minime și maxime fără a schimba matricea de distanțe. Absența
muchiei între noduri este echivalentă cu un anumit număr într-o
matrice, indiferent dacă se cere determinarea drumului minim sau
maxim.
În a treia parte a lucrării se propune spre rezolvare o gamă
largă de probleme. Pentru unele probleme este necesar să se
compare algoritmi diferiți pe aceleași date inițiale.
În cea de-a patra parte, sunt prezentate răspunsurile la
problemele propuse spre rezolvare, iar la unele probleme se prezintă
şi indicații pentru rezolvare.

4
1. FLUXUL MAXIM. ALGORITMUL FORD-
FULKERSON

1.1. Probleme rezolvate


1. Să se determine valoarea fluxului maxim care traversează
reţeaua de ransport R   X ,U  dată în figura 1.1.
4
2 6
6
7
8 5 3
5

6
1 5
9
6 5
9
3
6
3 4 8
5 4
Fig. 1.1
Rezolvare:
Aplicăm algoritmul Ford-Fulkerson. Ideia algoritmului constă
dintr-un procedeu de marcare a vârfurilor, pe baza căruia se
îmbunătăţeşte succesiv valoarea fluxului pînă cînd se obţine un flux
maximal.
I. Definim fluxul iniţial f(u) = 0  uU.
II. Determinăm lanţurile nesăturate de la intrarea reţelei x1 până
la ieşirea reţelei x9 prin următorul procedeu de marcare:
a) marcăm intrarea x1 cu semnul “+”;
b) marcăm cu semnul “  xi ” oricare vârf xk nemarcat cu
proprietatea că arcul  xi , xk   U este nesaturat;
c) marcăm cu semnul “- xk ” oricare vârf xi nemarcat cu
proprietatea că arcul  xi , xk   U are un flux nenul, adică
f  xi , xk   0 .

5
III. Determinăm cantitatea de flux  , cu care mărim sau
micşorăm fluxul pe fiecare arc din drumul (lanţul) ales:
1  min c u   f  u   , u U +, (U + - mulţimea arcelor,
orientate de la intrare spre ieşire).
 2  min  f  u   , u U -, (U - - mulţimea arcelor, orientate de la
ieşire spre intrare).
 1, dacă U 
 
min  1 ,  2  , dacă U 
IV. Dacă   0 , definim un nou flux f1  u  astfel:
 f  u  , dacă u l

f1  u    f  u    , dacă u U 
 f  u    , dacă u U 

l - drumul(lanţul) ales.
V. Repetăm paşii II, III şi IV cu fluxul nou obţinut.
Dacă prin acest procedeu de marcare nu putem marca ieşirea
reţelei, atunci fluxul are o valoare maximă la ieşire, iar mulţimea
arcelor care unesc vârfurile marcate cu vârfurile care nu au putut fi
marcate constituie o tăietură de capacitate minimă (secţiunea
minimală).
În urma marcării vârfurilor obţinem următoarele
lanţuri(drumuri):
l1={1,2,5,6,7,9}  1=min(8,6,3,4,9)=3
l2={1,2,5,7,9}  2=min(8-3,6-3,5,9-3)=3
l3={1,2,4,8,7,9}  3=min(8-6,5,4,5,9-6)=2
l4={1,5,7,9}  4=min(6,5-3,9-8)=1
l5={1,3,6,7,4,8,9}  5=min(9,6,4-3,3,4-2,6)=1
l6={1,5,7,4,8,9}  6=min(6-1,5-4,3-1,4-3,6-1)=1
l7={1,5,2,4,7,8,9}  7=min(6-2,6,5-2,2,2,6-2)=2
Secţiunea minimală se obţine pentru A={7,8,9}(mulţimea
vîrfurilor nemarcate)
   A    6,7  ,  5,7  ,  4,8 - tăietura de capacitate minimă.
c    A   4  5  4  13 - capacitatea tăieturii.
6
Conform teoremei lui Ford-Fulkerson
f max 9  c   A   13 (fig. 1.2).
+1,+1,+1,-5, +5,+3, 4 (3+1)
2 6 (3+3)-2 6
-5 +3 +6,+5,+8,
8 (3+3+2) +5,+6,+5,-4,
7
5 (2+2 3 (3)
5 (3+1+1)

6 (1+1+2 +1 9 (3+3+2+1)
+ 1 5
+2,+2,+1,+1,+1
9
6 (1 5 (2-2
6 (1+1+2 +7,+7,+7,+7,
9 (1 +8,+8,+8
3 (1+1-2
+1 +2
+1
3 4 8 +4,+4,+4,-7,
5 4 (2+1+1)
+2,+7,+7,+2,

Fig. 1.2

2. Folosind algoritmul Ford-Fulkerson să se determine valoarea


fluxului maxim care traversează reţeaua de transport dată în
figura 1.3.
1
3
2 4

2
2
3
a b
1

1 2
3

Fig. 1.3
Rezolvare:
7
I. Vom considera fluxul iniţial f(u) = 0  uU.
II. Determinăm lanţurile nesăturate şi cantitatea de flux  , cu care
mărim sau micşorăm fluxul pe fiecare arc din drumul (lanţul) ales:
l1={a,1,2,b}  1=min(2,4,2)=2
l2={a,3,b}  2=min(1,2)=1
l3={a,2,3,b}  3=min(3,1,2-1)=1
l4={a,2,1,b}  4=min(3-1,2,3)=2
III. Determinăm mulţimea vîrfurilor nemarcate: A={1,2,3,b}
IV. Determinăm tăietura şi capacitatea tăieturii:
   A    a,1 ,  a,2  ,  a,3 c    A    2  3  1  6
f max b  c    A   6 (fig. 1.4)

+a, -2,
3 (2
1
2 (2) 4 (2-2
+1,+a,+a
3 (1+2) 2 +2,+3,+3,+1
2 (2)
+ a b
1 (1)
1 (1)
2 (1+1)
3 +a, +2,

Fig. 1.4

1.2. Programul in limbajul C pentru determinarea valoarei


fluxului maxim într-un graf arbitrar folosind algoritmul
Ford-Fulkerson

#include <memory.h>
#include <stdio.h>
const int MAX_V = 100;

8
int NUM_V; // number of verticies
const int INF = 10000;

int f[MAX_V][MAX_V]; // f[i][j] - flow from i to j


int c[MAX_V][MAX_V]; // c[i][j] - the maximum amount of flow
//that can pass through an edge i to j.

int Flow[MAX_V]; // Flow [i] the amount of flow in BFS


int Link[MAX_V]; // Link[i] the number of previos verticie on the
//path from i -> source
int Queue[MAX_V];
int QP, QC; // QP - Head of queue и QC - the amount of
//elements in queue
// Function finds the path from source to target with non zero
capacity //of flow
// BFS is used with the condition c[i][j] - f[i][j]>0
int FindPath(int source, int target) // source - the first verticie, target -
//the last
{
QP = 0; QC = 1; Queue[0] = source;
int i,CurV,stack[MAX_V],top;
Link[target] = -1;
memset(Flow, 0, sizeof(int)*NUM_V);
Flow[source] = INF;
while (Link[target] == -1 && QP < QC) // While the Queue is
//nonempty and we didnot find target

{
CurV = Queue[QP];
/*
for(i=0;i<50;i++) printf("*");
printf("\n%d\n",CurV+1);
*/
for (i=0; i<NUM_V; i++)
if ((c[CurV][i] - f[CurV][i])>0 && Flow[i] == 0)
9
{
Queue[QC++] = i;
// printf("%d ",i+1);
Link[i] = CurV;
if (c[CurV][i]-f[CurV][i] < Flow[CurV])
Flow[i] = c[CurV][i];
else
Flow[i] = Flow[CurV];
}
// printf("\n");
QP++;
}
// for(i=0;i<NUM_V;i++) printf("%d ",Flow[i]);
if (Link[target] == -1) return 0;
CurV = target;
printf("%d\n",Flow[target]);
top=0;
while (CurV != source)
{
stack[top++]=CurV+1;// put the verticie in stack
f[Link[CurV]][CurV] +=Flow[target]; // the modification of
flow //matrix
CurV = Link[CurV];
}
stack[top]=source+1;
while(top>=0)
printf("%d ",stack[top--] );
printf("\n");
return Flow[target];
}
int main()
{
int source, target;
freopen("input.txt","r",stdin);
scanf("%d", &NUM_V);
10
scanf("%d %d", &source, &target);
int i, j;
for (i=0; i<NUM_V; i++)
for (j=0; j<NUM_V; j++)
scanf("%d",&c[i][j]);
int MaxF = 0, AddF;
do
{
AddF = FindPath(source, target);
MaxF += AddF;
} while (AddF >0);
printf("%d", MaxF);
return 0;
}

Descrierea programului

Datele de intrare sunt citite din fișier


9
1 9
089060000
000560000
000006000
005000040
000003500
000000400
000300009
000000509
000000000

Prima linie conţine numărul total de noduri 9. Pe linia a doua sunt scrise
numerele nodurilor sursă şi destinație, separate de un spațiu. Numerotarea
nodurilor începe de la 1, însă în program numerotarea nodurilor începe de
la 0.

11
Ieșirea programului – s-a găsit trei lanțuri saturate și valoarea fluxului
maxim care poate fi trecut prin aceste lanțuri.
Valoarea fluxului și primul lanț (Debit și primul lanț)
5
1579
Valoarea fluxului și al doilea lanț
4
12489
Valoarea fluxului și al treilea lanț
4
13679
Nu există mai multe lanțuri și, prin urmare, valoarea fluxului maxim este
13 = 5 + 4 + 4.
Partea principală a programului - căutare pentru secvența de muchi, care
poate crește fluxul total de la sursă la ieşire. Acest lucru se întâmplă în
subprogram int FindPath (int sursă, int țintă), care utilizează coada
int Queue [MAX_V];
int QP, QC; // QP – capul cozei și QC – numărul de elemente în coadă.
În acest caz, vârful de pornire inițial este plasat în coadă și indicilor sunt
setate valorile
    QP = 0; QC = 1; Queue[0] = source;
Apoi, în timp ce coada nu este goală, extragem vârful din coadă
CurV = Queue [QP];
Și pentru acest nod se verifică toate muchiile adiacente și în cazul în care
lățimea de bandă pentru muchii mai mare de valoarea fluxului (ce
înseamnă că este posibil de a mări fluxul), și considerăm acest nod pentru
prima dată (căutare în lățime), atunci vom înregistra nodul corespunzător
în coadă. Apoi procesăm acest vârf. Schimbăm fluxul pentru acest vârf în
dependență de condiție
            if (c [CurV] [i] -f [CurV] [i] <Flow [CurV])
               Flow [i] = c [CurV] [i];
            altfel
               Flow [i] = Flow [CurV];
În cazul în care procesul de prelucrare ajunge la nodul de destinație, atunci
vom obține valoarea fluxului până la acest vârf și afișăm valoarea obținută
12
printf ("% d \ n", Flow [taget]);
Apoi, algoritmul modifică matricea fluxului
        f [Link [CurV]] [CurV] + = Flow [taget]; // the modification of
flow //matrix
și căutam următorul lanț. Odată ce este imposibil să ajungi la destinație
atunci
    if(Link [target] == -1) return 0;
subprogramul returnează 0 și ciclul din programul principal se oprește
do
    {
        AddF = FindPath (source, target);
        MaxF + = AddF;
    } while (AddF> 0);
Pentru o mai bună înțelegere a programului, este recomandat de a citi
comentarii și de a urmări algoritmul de căutare al următorului lanț.

13
2. DRUMUL DE VALOARE MINIMĂ (MAXIMĂ)
ALGORITMII FORD ȘI BELLMAN-CALABA

2.1. Probleme rezolvate


1. Să se determine pentru graful din figura 2.1 drumul de valoare
minimă între vârfurile x1 şi x7 conform algoritmului lui Ford.
1 5
X2 X4
4 X6
5 5 3
8
5
X1 6 4
3 X7
2 6
X3 X5

Fig.2.1

Algoritmul lui Ford permite determinarea drumului de valoare


minimă de la un vârf fixat până la toate celelalte vârfuri ale grafului
orientat dat.
I. Vârfului iniţial îi atribuim eticheta H 0  0 .
II. La toate celelalte vârfuri le atribuim eticheta H j   . ( 
reprezintă lungimea unui drum arbitrar de la vârful xi până la
vârful x j ).
III. Calculăm diferenţele H j  H i pentru fiecare arc  xi , x j  a
grafului dat şi le comparăm cu ponderea arcului  xi , x j  :
a) H j  H i  Lij , Lij - ponderea (lungimea) arcului  xi , x j 
b) H j  H i  Lij
c) H j  H i  Lij
Cazul c) permite micşorarea distanţei dintre vârful xi şi x j :
H j  Lij  H i

14
Pasul III îl repetăm atât timp cât există arce pentru care are loc
inegalitatea „c”. Etchitele H i vor defini distanţa de la vârful xi
până la vârful x j .
IV. Stabilim secvenţa de vârfuri care formează drumul minim.
Plecăm de la vârful final x j spre cel iniţial. Predecesorul lui x j va
fi considerat xi , dacă are loc H j  H i  Lij . Dacă există câteva
arce, pentru care are loc această relaţie, alegem la opţiune.
Rezolvare:
I. H 0  0 ;
II. H j   ;
III. Examinăm toate arcele care iese din vârful x1 :
H2-H1>L12 ∞-0>5  H2=H1+L12=0+5=5
H4-H1>L14 ∞-0>5  H4=H1+L14=0+5=5
H6-H1>L16 ∞-0>8  H6=H1+L16=0+8=8
H5-H1>L15 ∞-0>6  H5=H1+L15=0+6=6
H3-H1>L13 ∞-0>3  H3=H1+L13=0+3=3
(fig. 3.8)
Examinăm toate arcele care iese din vârful x2 :
H4-H2<L24 5-5<1  Eticheta la vârful x4 nu se
schimbă.
H5-H2<L25 6-5<4  Eticheta la vârful x5 nu se
schimbă.
Examinăm toate arcele care iese din vârful x3 :
H5-H3>L35 6-3>2  H5=H3+L35=3+2=5
Examinăm toate arcele care iese din vârful x4 :
H5-H4<L45 5-5<3  Eticheta la vârful x5 nu se
schimbă.
H6-H4<L46 8-5<5  Eticheta la vârful x6 nu se
schimbă.
Examinăm toate arcele care iese din vârful x5 :
H6-H5<L56 8-5<4  Eticheta la vârful x6 nu se
schimbă.
15
H7-H5>L57 ∞-5>6  H7=H5+L57=5+6=11
Examinăm toate arcele care iese din vârful x6 :
H7-H6<L67 11-8<5  Eticheta la vârful x7 nu se schimbă.
Rezolvarea problemei poate fi scrisă cu ajutorul unui tabel
(fig.2.2) și figurei 2.3.

1 2 3 4 5 6 7
I 0 ∞ ∞ ∞ ∞ ∞ ∞
II1 5 3 5 6 8 ∞
III2 ∞
IV3 5 ∞
V4 ∞
VI5 11
VII6
0 5 3 5 5 8 11

Fig.2.2

∞5 ∞5
1 5 ∞8
X2 X4
4 X6
5 5 3
0 8
5
X1 6 4
∞ 11
3 X7
2 6
X3 X5
∞3 ∞65

Fig.2.3

lmin 1  7   11

IV. Determinăm drumul minim: H 7  H 5  L57 , 11-5 = 6


H 5  H 3  L35 , 5-3 = 2
H 3  H1  L13 , 3-0 = 3

Drumul corespunzător valorii minime 11: 1 3 5 7


16
2. Folosind algoritmului lui Ford să se determine drumul de valoare
maximă între vârfurile x1 şi x7 ale grafului din figura 2.1.
Rezolvare:
I. H 0  0 ;
II. H j   ;

III. Examinăm toate arcele care iese din vârful x1 :


H2-H1<L12 -∞-0<5  H2=H1+L12=0+5=5
H4-H1<L14 -∞-0<5  H4=H1+L14=0+5=5
H6-H1<L16 -∞-0<8  H6=H1+L16=0+8=8
H5-H1<L15 -∞-0<6  H5=H1+L15=0+6=6
H3-H1<L13 -∞-0<3  H3=H1+L13=0+3=3
(fig. 3.10)

Examinăm toate arcele care iese din vârful x2 :


H4-H2<L24 5-5<1  H4=H2+L24=5+1=6
H5-H2<L25 6-5<4  H5=H2+L25=5+4=9

Examinăm toate arcele care iese din vârful x3 :


H5-H3>L35 9-3>2  Eticheta la vîrful x5 nu se schimbă.

Examinăm toate arcele care iese din vârful x4 :


H5-H4=L45 9-6=3  Eticheta la vârful x5 nu se
schimbă.
H6-H4<L46 8-6<5  H6=H4+L46=6+5=11

Examinăm toate arcele care iese din vârful x5 :


H6-H5<L56 11-9<4  H6=H5+L56=9+4=13
H7-H5<L57 -∞-9<6  H7=H5+L57=9+6=15

Examinăm toate arcele care iese din vârful x6 :


H7-H6<L67 15-13<5  H7=H6+L67=13+5=18
17
1 2 3 4 5 6 7
I 0 -∞ -∞ -∞ -∞ -∞ -∞
II1 5 3 5 6 8 -∞
III2 6 9 -∞
IV3 -∞
V4 11 -∞
VI5 13 15
VII6 18

Fig.2.4

l max 1  7   18
IV. Determinăm drumul maxim: H 7  H 6  L67 , 18-13 = 5
H 6  H 5  L56 , 13-9 = 4
H 5  H 4  L45 , 9-6 = 3
H 5  H 2  L25 , 9-5 = 4
H 4  H 2  L24 , 6-5 = 1
H 2  H 1  L12 , 5-0 = 5

Drumurile corespunzătoare valorii maxime 18:


1 2 5 6 7

1 2 4 5 6 7

3. Pentru graful din figura 2.1 să se determine drumul de


valoare minimă între vârfurile x1 şi x7 folosind algoritmul
Bellman-Calaba.
Rezolvare:
Algoritmul Bellman-Calaba permite determinarea drumului de
valoare minimă din fiecare vârf a grafului până la un vârf fixat,
numit vârf final.
Etapa I. Construim matricea ponderată de adiacenţă a grafului
dat G=(X,U): (fig. 2.5)
18
a) mij = Lij, dacă există arcul (xi, xj) de pondere Lij;
b) mij = ∞, unde ∞ este un număr foarte mare (de tip întreg maximal
pentru calculatorul dat), dacă arcul (xi, xj) este lipsă; (  reprezintă
lungimea unui drum arbitrar de la vârful xi până la vârful x j );
c) mij = 0, dacă i = j.
Etapa a II-a. Elaborăm un vector V0 în felul următor:
a) Vi 0  Lin , dacă există arcul (xi, xn), unde xn este vârful final
pentru care se caută drumul minim, Lin este ponderea acestui arc;
b) Vi 0   , dacă arcul (xi, xn) este lipsă;
c) Vi 0  0 , dacă i =n.
Etapa a III-a. Calculăm iterativ vectorul V în conformitate cu
următorul procedeu:
V(ki)  min Lij  V(kj ) 1  , unde
i  1,2,..., n  1, j  1,2,..., n; i  j
Vnk  0 .
Dacă V k  V k 1 - STOP.
Componenta cu numărul i a vectorului Vi k cu valoarea diferită de
zero ne va da valoarea minimă a drumului dintre vârfurile xi şi xn .
Etapa a IV-a. Determinăm drumul de la vârful xi până la vârful
xn , care corespunde valorii minime:

V k  Lij  V k 1  Lij  V k  V k 1

 
V 11  min L12  V20 , L13  V30 , L14  V40 , L15  V50 , L16  V60 , L17  V70 
 min 5  ,3  ,5  ,6  6,8  5,   0  12
V 1
 2  
 min L21  V10 , L23  V30 , L24  V40 , L25  V50 , L26  V60 , L27  V70 
 min   ,   ,1  ,4  6,   5,   0  10
V 1
 3  
 min L31  V10 , L32  V20 , L34  V40 , L35  V50 , L36  V60 , L37  V70 
 min   ,   ,   ,2  6,   5,   0  8

19

V 14   min L41  V10 , L42  V20 , L43  V30 , L45  V50 , L46  V60 , L47  V70 
 min   ,   ,   ,3  6,5  5,   0  9
V 1
 5  
 min L51  V10 , L52  V20 , L53  V30 , L54  V40 , L56  V60 , L57  V70 
 min   ,   ,   ,   ,4  5,6  0  6
V 1
 6  
 min L61  V10 , L62  V20 , L63  V30 , L64  V40 , L65  V50 , L67  V70 
 min   ,   ,   ,   ,   6,5  0  5

V  min L12  V21 , L13  V31 , L14  V41 , L15  V51 , L16  V61 , L17  V71 
2
 1 
 min 5  10,3  8,5  9,6  6,8  5,   0  11
V 2
 2  
 min L21  V11 , L23  V31 , L24  V41 , L25  V51 , L26  V61 , L27  V71 
 min   12,   8,1  9,4  6,   5,   0  10
V 2
 3  
 min L31  V11 , L32  V21 , L34  V41 , L35  V51 , L36  V61 , L37  V71 
 min   12,   10,   9,2  6,   5,   0  8
V 2
 4  
 min L41  V11 , L42  V21 , L43  V31 , L45  V51 , L46  V61 , L47  V71 

 min   12,   10,   8,3  6,5  5,   0  9


V 2
 5  
 min L51  V11 , L52  V21 , L53  V31 , L54  V41 , L56  V61 , L57  V71 
 min    12,   10,   8,   9,4  5,6  0  6
V 2
 6  
 min L61  V11 , L62  V21 , L63  V31 , L64  V41 , L65  V51 , L67  V71 
 min   12,   10,   8,   9,   6,5  0  5

V  min L12  V22 , L13  V32 , L14  V42 , L15  V52 , L16  V62 , L17  V72 
3
 1 
 min 5  10,3  8,5  9,6  6,8  5,   0  11
V 3
 2  
 min L21  V12 , L23  V32 , L24  V42 , L25  V52 , L26  V62 , L27  V72 
 min   11,   8,1  9,4  6,   5,   0  10
V 3
 3  
 min L31  V12 , L32  V22 , L34  V42 , L35  V52 , L36  V63 , L37  V73 
 min   11,   10,   9,2  6,   5,   0  8
V 3
 4  
 min L41  V12 , L42  V22 , L43  V32 , L45  V52 , L46  V63 , L47  V73 
 min   11,   10,   8,3  6,5  5,   0  9
V 3
 5  
 min L51  V12 , L52  V22 , L53  V32 , L54  V42 , L56  V63 , L57  V73 

20
 min   11,   10,   8,   9,4  5,6  0  6
V 3
 6  
 min L61  V12 , L62  V22 , L63  V32 , L64  V42 , L65  V53 , L67  V73 
 min   11,   10,   8,   9,   6,5  0  5

Observăm că am ajuns la Vi 3  Vi 2 - STOP (fig.2.5)

1 2 3 4 5 6 7
1 0 5 3 5 6 8 
2  0  1 4  
3   0  2  
4    0 3 5 
5     40 6
6      0 5
7       0
V i0     6 5 0

V 1i  12 10 8 9 6 5 0

V i2 11 10 8 9 6 5 0

V i3 11 10 8 9 6 5 0

Fig. 2.5

lmin 1  7   11
Determinăm drumul de valoare minimă:
L13  V1  V3 L35  V3  V5 L57  V5  V7
3 = 11 - 8 2=8–6 6=6–0
Drumul corespunzător valorii minime 11: 1 3 5 7

4. Pentru graful din figura 2.1 să se determine drumul de valoare


maximă între vârfurile x1 şi x7 folosind algoritmul Bellman-Calaba.
Rezolvare:
Etapa I. Construim matricea ponderată de adiacenţă a grafului
dat G=(X,U):
21
a) mij = Lij, dacă există arcul (xi, xj) de pondere Lij;
b) mij = -∞, dacă arcul (xi, xj) este lipsă;
c) mij = 0, dacă i = j.

Etapa a II-a. Elaborăm un vector V0 în felul următor:


a) Vi 0  Lin , dacă există arcul (xi, xn), unde xn este vârful final
pentru care se caută drumul maxim, Lin este ponderea acestui arc;
b) Vi 0   , dacă arcul (xi, xn) este lipsă;
c) Vi 0  0 , dacă i =n.

Etapa a III-a. Calculăm iterativ vectorul V în conformitate cu


următorul procedeu:
V(ki)  max Lij  V( kj )1 , unde
i  1,2,..., n  1, j  1,2,..., n; i  j
Vnk  0 .
Dacă V k  V k 1 - STOP (fig. 2.6)

Componenta cu numărul i a vectorului Vi k cu valoarea diferită de


zero ne va da valoarea maximă a drumului dintre vârfurile xi şi xn .

Etapa a IV-a. Determinăm drumul de la vârful xi până la vârful


xn , care corespunde valorii maxime:
V k  Lij  V k 1  Lij  V k  V k 1 (fig. 2.6)
lmax 1  7   18

Determinăm drumul de valoare maximă:


L12  V1  V2 L24  V2  V4 L25  V2  V5
L45  V4  V5
5 = 18 - 13 1 = 13 – 12 4 = 13 – 9 3 = 12 – 9
L56  V5  V6 L67  V6  V7

22
4=9–5 5=5–0

1 2 3 4 5 6 7
8 -
1 0 5 3 5 6

- - - -
2
 0
 1 4
 
- - - - -
3
  0
 2
 
- - - 5 -
4
   0 3

- - - - 4 6
5
    0
- - - - - 0 5
6
    
- - - - - - 0
7
     
Fig. 2.6 - - - - 0
V i0
    6 5

V 1i  13 10 8 10 9 5 0

V i2 15 13 11 12 9 5 0

V i3 18 13 11 12 9 5 0

V i4 18 13 11 12 9 5 0

Drumurile corespunzătoare valorii maxime 18:


1 2 5 6 7

1 2 4 5 6 7

2.2. Programul în limbajul C pentru determinarea drumului de


valoare minimă într-un graf arbitrar folosind algoritmul lui
Ford

#include <stdio.h>
#include<mem.h>
23
#include<string.h>
#include<stdlib.h>
void printd(int *a,int i,int n ){
printf("%4d ",i);
for(int j=1;j<=n;j++)
printf("%4d ",*(a+j));
printf("\n");
}
int main()
{
FILE *in=fopen("grford.t","r");
int i,j,fst,lst,*H,*H1;
int **L, n, INF=100;
// L adjacency matrix and n number of verticies
// fst - the first and lst -the last verticies
// d1 and d distances between verticies
fscanf(in,"%d%d%d",&n,&fst,&lst);
L=(int **)malloc((n+1)*sizeof(int *));
for(i=0;i<=n;i++)
L[i]=(int *)malloc((n+1)*sizeof(int));
H=(int *)malloc((n+1)*sizeof(int));
H1=(int *)malloc((n+1)*sizeof(int));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
fscanf(in,"%d", &L[i][j] );
for(i=0;i<=n;i++)
H[i]=INF;
// At the beginning , all vertices have a weight of infinity exept
the // first
H[fst]=0;
do{
memmove(H1,H,(n+1)*sizeof(int));
printd(H,0,n);
for(i=1;i<n;i++){
for(j=1;j<=n;j++)
24
if(i!=j)
if(H[i]!=INF && L[i][j]!=INF)
if(H[j]!=INF){
if(H[j]-H[i]>L[i][j])
H[j]=H[i]+L[i]
[j];
}else
H[j]=H[i]+L[i][j];
printd(H,i,n);
}
} while(memcmp(H,H1,(n+1)*sizeof(int))!=0 );
printf("VALUE = %d\n",H[lst]);
char *path,np=0;
path=(char* )calloc(n+1,sizeof(char));
path[np++]=lst;
i=lst;
while(i!=fst){
j=0;
//finding the next verticie in that path
while( ((j<=n)&&(H[i]-H[j])!=L[j][i]) || i==j)
j++;
printf("%d -%d = %d\n ",H[i],H[j],L[j][i]);
i=path[np++]=j;
//increasing the path
}
for(i=0;path[i];i++)
path[i]+='0';
printf("PATH = %s",strrev(path));
free(H);
free(H1);
free(path);
for(i=0;i<=n;i++)
free(L[i]);
free(L);
return 0;
25
}

26
Descrierea programului

Date de intrare sunt citite din fișier


717
0 5 3 5 6 8 100
100 0 100 1 4 100 100
100 100 0 100 2 100 100
100 100 100 0 3 5 100
100 100 100 100 0 4 6
100 100 100 100 100 0 5
100 100 100 100 100 100 0

Prima linie conține numărul de vârfuri ale grafului, numărul


primului și ultimului vârf. Apare matricea de distanțe a grafului din
exemplu. Valoarea infinitului se presupune a fi 100 INF = 100;
Programul alocă dinamic memoria pentru toate matricele și
folosește funcția void printd (int * a, int i, int n) pentru a imprima o
matrice unidimensională.
Programul este elaborat cât mai aproape de algoritmul prezentat mai
sus, până la notarea și imprimarea rezultatului

0 0 100 100 100 100 100 100


1 0 5 3 5 6 8 100
2 0 5 3 5 6 8 100
3 0 5 3 5 5 8 100
4 0 5 3 5 5 8 100
5 0 5 3 5 5 8 11
6 0 5 3 5 5 8 11
0 0 5 3 5 5 8 11
1 0 5 3 5 5 8 11
2 0 5 3 5 5 8 11
3 0 5 3 5 5 8 11
4 0 5 3 5 5 8 11
5 0 5 3 5 5 8 11
6 0 5 3 5 5 8 11
27
Diferența este că în descrierea algoritmului nu este indicată o
execuție suplimentară de calcul pentru a asigura invarianța
vectorului de marcare (distanțe)

do{
memmove(H1,H,(n+1)*sizeof(int));
printd(H,0,n);
……………………………………
…………………………………….
printd(H,i,n);
}
} while(memcmp(H,H1,(n+1)*sizeof(int))!=0 )
Cu toate acestea, rularea dată este necesară pentru a asigura
corectitudinea rezultatului obținut. Căutarea minimă a căii se
realizează prin calcularea vârfului precedent, începând cu ultimul și
până la primul. Sunt prezentate toate rezultatele intermediare
VALUE = 11
11 -5 = 6
5 -3 = 2
3 -0 = 3
PATH = 1357
care coincid cu cele descrise în algoritm.

2.3. Programul în limbajul C pentru determinarea drumului de


valoare minimă (maximă) într-un graf arbitrar foloosind
algoritmul lui Ford sau Bellman-Calaba

Pentru toate diferențele dintre descrierile algoritmilor lui Ford


și Bellman-Calaba, de fapt este același algoritm dinamic pe graf.
Prin urmare, este posibilă o singură realizare a tuturor celor patru
cazuri (Ford, Bellman-Calaba, calea minimă, maximă). În plus,
folosind coada, se găsesc toate căile extreme.

28
#include <stdio.h>
#include<mem.h>
#include<string.h>
#define minmax(x,y,mm) ((x)>(y)==mm )? (x):(y)
// if mm==1 max else min
int MS[100][100],n,INF=100;
// adjacency matrix and n number of verticies
void printd(int *a){
for(int j=0;j<n;j++)
printf("%4d ",*(a+j));
printf("\n");
}
//Relax function on Bellman-Ford Algorithms
void relax(int *a,int *b, int i,int f)
{
for(int j=0;j<n;j++)
if(MS[i][j]!=INF&&a[i]!=INF)
if(b[j]!=INF)
b[j]=minmax(b[j],MS[i][j]+a[i],f);
//both min and max variants are computed
else
b[j]=MS[i][j]+a[i];
}
int main()
{
FILE *in=fopen("gr.t","r");
int i,j,tmp,count,fst,lst,mm,k,d[100],d1[100]={0};
//fst - the first and lst - the last verticies
//mm=0 min mm=1 max
// k is the selector, k=0 Ford, k=1 Bellman-Calaba
fscanf(in,"%d%d%d%d%d",&k,&mm,&n,&fst,&lst);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
fscanf(in,"%d",k ? &MS[j][i]:&MS[i][j] );
//if k==1 (Bellman-Calaba) the adjacency matrix is transpose
29
// and first and last verticies are swapped
if(k){
tmp=fst;fst=lst;lst=tmp;
}
for(i=0;i<n;i++)
d1[i]=INF;
// At the beginning , all vertices have a weight of infinity exept the
first
d1[fst-1]=0;
// the count of verticies is from 0 , not from 1!!!
count=1;
do{
memmove(d,d1,200);
for(i=0;i<n;i++){
relax(d1,d1,i,mm);
if(k==0)
printd(d1);//Ford
}
if(k)
printd(d1);//Bellman-Calaba
} while(memcmp(d,d1,200)!=0&& (count++)<n );
//check for negative-weight cycles (count==n+1)
//the longest possible path without a cycle can be n-1 edges
if(memcmp(d,d1,200)!=0){
printf("NO PATH - CYCLE!!!");
return 0;
}
printf("VALUE = %d\n",d[lst-1]);
int q1=-1,q2=0,np;
//q1 head of the queue and q2 tail
char path[100][100]={0};
//queue of all pathes of max(min) weights
path[0][0]=lst;
//insert in queue the last verticie
while(q1<q2){
30
np=strlen(path[++q1]);
//np = lenght of the path in the head
i=path[q1][np-1];
// the last verticie in that path
while(i!=fst){
j=0;
tmp=np;
//finding the next verticie in that path
while(++j<=n){
while( ((j<=n)&&d1[i-1]!=d1[j-1]+MS[j-1]
[i-1]) || i==j)
j++;
if(d1[i-1]==d1[j-1]+MS[j-1][i-1] && i!=j )
if(tmp==np)
path[q1][np++]=j;
//increasing the path
else{
strcpy(path[++q2],path[q1]);
// push the new path in queue
path[q2][tmp]=j;
}
}
i=path[q1][tmp];
}
}
for(i=0;i<=q2;i++){
for(j=0;path[i][j];j++)
path[i][j]+='0';
printf("%d PATH = %s\n",i+1,k ? path[i]:strrev(path[i]));
// if k==0 (Ford) the path is reversed , because we started from
the //first verticie
}
return 0;
}

31
Descrierea programului
Datele de intrare sunt citite din fișier
00717
0 5 3 5 6 8 100
100 0 100 1 4 100 100
100 100 0 100 2 100 100
100 100 100 0 3 5 100
100 100 100 100 0 4 6
100 100 100 100 100 0 5
100 100 100 100 100 100 0
Pe prima linie introduceți cheile, numărul de noduri ale grafului,
primul și ultimul nod
fscanf(in,"%d%d%d%d%d",&k,&mm,&n,&fst,&lst);
Acest lucru este clar din comentariul din cod
//fst - the first and lst the last verticies
//mm=0 min mm=1 max
// k is the selector, k=0 Ford, k=1 Bellman-Calaba
Apoi urmează matricea de distanțe, astfel, pentru exemplele
analizate,

//0 0 - Ford min


0 5 3 5 6 8 100
0 5 3 5 6 8 100
0 5 3 5 5 8 100
0 5 3 5 5 8 100
0 5 3 5 5 8 11
0 5 3 5 5 8 11
0 5 3 5 5 8 11
0 5 3 5 5 8 11
0 5 3 5 5 8 11
0 5 3 5 5 8 11
0 5 3 5 5 8 11
0 5 3 5 5 8 11
0 5 3 5 5 8 11
0 5 3 5 5 8 11
32
VALUE = 11
1 PATH = 1357
Schimbând primele două numere din intrare, puteți obține alte
rezultate
//1 0 -Bellman-Calaba min

100 100 100 100 6 5 0


12 10 8 9 6 5 0
11 10 8 9 6 5 0
11 10 8 9 6 5 0
VALUE = 11
1 PATH = 1357
Algoritmul lui Ford și drumul maxim
//0 1 -Ford max
0 5 3 5 6 8 100
0 5 3 6 9 8 100
0 5 3 6 9 8 100
0 5 3 6 9 11 100
0 5 3 6 9 13 15
0 5 3 6 9 13 18
0 5 3 6 9 13 18
0 5 3 6 9 13 18
0 5 3 6 9 13 18
0 5 3 6 9 13 18
0 5 3 6 9 13 18
0 5 3 6 9 13 18
0 5 3 6 9 13 18
0 5 3 6 9 13 18
VALUE = 18
1 PATH = 12567
2 PATH = 124567
În mod similar, algoritmul Bellman-Calaba și, de asemenea, drumul
maxim
//1 1 - Bellman-Calaba max
100 100 100 100 6 5 0
33
13 10 8 10 9 5 0
15 13 11 12 9 5 0
18 13 11 12 9 5 0
18 13 11 12 9 5 0
VALUE = 18
1 PATH = 124567
2 PATH = 12567
Toate rezultatele coincid în totalitate cu cele analizate în
exemplul respectiv.

34
3. PROBLEME PROPUSE SPRE REZOLVARE

1. Folosind algoritmul Bellman-Calaba, să se determine drumul


de valoare minimă între vârfurile 1 şi 8 ale grafului dat în figura 3.1.
3
3 5
1 2
2 4
2 7
1 6 1
6
9 2 3 5
8 6 3
7
2 3

Fig.3.1

2. Pentru graful reprezentat în figura 3.2 se cere să se determine


drumul de valoare minimă între vârfurile 0 şi 9, folosind:
a) algoritmul Belman-Calaba;
b) algoritmul Ford.

1 2
7
5 5
1 4 7
8 2
0 3 5 8 3
1
2 5 9
4 3 3 4

2 3 4 6
3
Fig.3.2

3. Folosind algoritmul Bellman-Calaba, să se determine drumul


de valoare minimă între vârfurile 1 şi 8 ale grafului dat în figura 3.3.

35
11
2
8 6
1 5
3 3
10 5 4
4 7
1 3 7 2 1 8
5 8
2 10
7
8 2
12
4
Fig.3.3
4. Folosind algoritmul Ford, să se determine drumul de valoare
minimă între vârfurile 1 şi 7 ale grafului reprezentat în figura 3.4.
4
4 2
1 2
8 6
2 2
1 4 6
3 2 6
3
3 7
3 3 5

Fig.3.4
5. Reţeaua din figura 3.5 reprezintă un sistem de comunicare a datelor
cu privire la informaţiile asupra necesarului de materiale dintr-o
întreprindere industrială. Să se determine ruta optimă care stabileşte
timpul optim de transmitere a informaţiei, dintre vârfurile 0 şi 7.

1 3
5 3
1 6
2 1 1
2
0 2 3 4
7
9 2
3
7
5
2 6 3

Fig.3.5
36
6. O reţea telefonică ce se construieşte între localităţile 0 şi 7
trebuie să treacă prin unele din localităţile 1, 2, ..., 6, localităţi în
care se instalează o reţea telefonică internă, cu posibilităţi de a se
extinde şi pentru alte localităţi. Costurile instalaţiilor între localităţi,
inclusiv instalaţia punctelor de racordare, sunt trecute în graful din
figura 3.6, pe arcele (i,j) corespunzătoare.
Se cere să se determine schema instalaţiei reţelei telefonice
care trece printr-un număr cît mai mare de localităţi, iar costul
instalaţiei să fie minim.
13
1 6
4
1 2 14 2
3 11 6
0 2 5 7
5
5 4 15
8 3 9

3 6 4
Fig.3.6

7. Fie graful din figura 3.7. Să se determine drumul de valoare


minimă între vârfurile 1 şi 8, folosind:
a) algoritmul Ford;
b) algoritmul Bellman-Calaba.

2
2 3
4
2 6
2 3 2
1 1 6
1 8
5 4
8
2 2
6
3 4 2
7
Fig.3.7

37
8. Pentru graful G dat în figura 3.8 să se determine drumul de
valoare minimă între vârfurile 0 şi 5, folosind:
a) algoritmul Ford;
b) algoritmul Bellman-Calaba.

2
1
3
9
3 2 7
6
0
5
8
2
1
2 4
Fig.3.8

9. Să se determine drumul de valoare minimă între vârfurile 1


şi 9 ale grafului dat în figura 3.9, folosind:
a) algoritmul Ford;
b) algoritmul Bellman-Calaba.

6 1
2 5
1 4 2
1
3 5 7 3
1
2 9
2 5
4 5
3 4
3
4 8

Fig.3.9

10. Dintr-o hartă a unui judeţ, întreprinderea judeţeană de


drumuri şi poduri şi-a extras o configuraţie cuprinzînd 9 localităţi:
0, 1,..., 8 (fig. 3.10) şi şoselele intermediare dintre aceste localităţi.

38
În vederea construirii unei şosele asfaltate dintre localităţile 0 şi
8 s-a făcut un studiu (luând în consideraţie distanţa dintre localităţi,
numărul podurilor ce vor trebui să se construiască, cheltuielile de
organizare cu materiale de construcţii etc.), în urma căruia s-a
stabilit un preţ informativ mediu (în aceleaşi unităţi băneşti) pentru
fiecare şosea intermediară, preţ ce este trecut în graful dat pe fiecare
arc (i,j).
Se cere să se întocmească un proiect pentru asfaltarea unei
şosele între localităţile 0 şi 8, astfel încât cheltuielile necesare să fie
minime şi, în plus, dacă este posibil, şoseaua să treacă prin centrul
industrial aflat în localitatea 5, în cazul când ar exista mai multe rute
pentru care costul total este acelaşi, în funcţie de dezvoltarea în
continuare a acestui judeţ, există vreo rută pentru care se manifestă
un interes mai mare?
11
6
1 7 4
3 4 5 7
5 6 2
7 2
4 7
0 1
5 9 3
4 4
5 14
3 8
Fig.3.10

11. Să presupunem că din localitatea 0, este solicitat de urgenţă


un produs de către o secţie a unei întreprinderi din localitatea 6.
Presupunînd că pentru transportul produsului se poate folosi
sistemul de linii ferate din figura 3.11, unde a fost indicat pentru
fiecare porţiune de cale ferată timpul necesar de deplasare de la o
localitate la alta, să se determine ruta care trebuie să se aleagă între
cele două localităţi, astfel încât timpul necesar deplasării între
localităţile menţionate să fie minim.

39
2 5
1 1 4
1 2
0
4 3
4 6
3 4
2 2
5
3
Fig.3.11

12. Fie graful din figura 3.12. Să se determine drumul de


valoare minimă între vârfurile 0 şi 12, folosind:
a) algoritmul Ford;
b) algoritmul Bellman-Calaba.

1 7
11
1 6 10 5
2 6 8
4 2 5 2
0 7
5 2
6 2 9 12
3 2 8
3 2 9
4 3 4
5 10
9 10

Fig.3.12

13. Folosind algoritmul lui Ford, să se determine drumul de


valoare maximă între vârfurile 1 şi 7 ale grafului dat în figura 3.13.

40
2 1
5 4 5
5
8 6
1 6
6 4 3
3 5
4
3 2 6 7
5
Fig.3.13

14. Să se determine drumul de valoare maximă între vârfurile 0


şi 6 ale grafului din figura 3.14, folosind:
a) algoritmul Ford;
b) algoritmul Bellman-Calaba.

5
1
6
2 5
6
1
6 6
0 2 5
5
3 2 3
2
4
3 3

Fig.3.14
15. Pentru graful reprezentat în figura 3.15 se cere să se determine
drumul de valoare maximă între vârfurile 0 şi 8, folosind:
a) algoritmul Ford;
b) algoritmul Bellman-Calaba .

41
5 5 1
1
1 6 2
3
8
1 1
0
1
7
3
4 1
4 2
2 1 6
3
Fig.3.15
16. Graful din figura 3.16 reprezintă o reţea de transport a
materiei prime pentru o uzină de aluminiu ce se găseşte în punctul
7. Beneficiul maxim calculat, obţinut în urma alegerii unei linii
oarecare de transport (în funcţie de numărul staţiilor de încărcare
existente pe fiecare linie, sau de procentul de steril care diferă de la
o staţie la alta etc.), este trecut pe fiecare arc al grafului.
Ştiind că mijloacele de transport folosite pentru transportul
materiei prime sunt garate în punctul 0, se cere să se determine
rutele pentru care beneficiul obţinut este maxim.
13
1 6
4
1 2 14 2
3 11 6
0 2 5 7
5
5 4 15
8 3 9

3 6 4
Fig.3.16

17. Un jucător de tenis, care participă la câştigarea titlului de cel


mai bun jucător de tenis al anului trebuie să participe la un număr
de turnee de tenis de diferite categorii cotate fiecare cu câte un
număr diferit de puncte. Posibilitatea de a participa după un turneu
din localitatea “k” la un alt turneu din localitatea “j” este indicată
42
prin graful din figura 3.17; un turneu cîştigat în localitatea j adaugă
la punctajul general un număr de puncte indicat printr-un număr
ataşat vârfului j. Se cere să se afle numărul şi ordinea turneelor care
trebuie să fie câştigate de jucător, pentru a obţine un punctaj general
maxim; participarea la turneul organizat în localitatea 8 este
obligatorie.
4
1 3
5

5 6
0 2 4 6 8
1 2
4
5
3
1
7
3 4
3 7
Fig. 3.17

18. Folosind algoritmul Ford-Fulkerson să se determine


valoarea fluxului maxim care traversează reţeaua de transport dată
în figura 3.18.
5
1 4
2 1 6
10 7
3
5
0 2 5 7
3
2
8 8
4
3 6
4
Fig.3.18

43
19. În portul 0 se găsesc 35 de vapoare ce trebuie să se deplaseze în
portul 9. Deplasarea celor 35 de vapoare dintr-un port în altul se face în
etape, astfel încât în prima etapă trebuie să ajungă cât mai multe dintre ele
în portul 9; în drumul lor, vapoarele trebuie să mai facă câte o escală în
alte porturi intermediare 2,3,…,8 (fig. 3.19). Condiţiile de primire,
aprovizionare etc. fac să existe o limitare a rutelor folosite; capacităţile
existente sunt trecute pe arcele reţelei.
Să se determine un plan optim de transport, astfel încât, în
această etapă să poată pleca cât mai multe vapoare spre portul 9.
5
1 6
6 3
5 13
12 3
4
3 7 10
2
0
5 9
4
4
20 5 3 12
3 8
10

Fig.3.19
20. Folosind algoritmul Ford-Fulkerson să se determine
valoarea fluxului maxim care traversează reţeaua de transport dată
în figura 3.20.
5
1
4
3
8 1 9
1
5 4
0 2 5
7
6
3 15
2
4 6
3
Fig.3.20
44
21. Folosind algoritmul Ford-Fulkerson să se determine
valoarea fluxului maxim care traversează reţeaua de transport dată
în figura 3.21.

1 4
5 4
7 7
3
0 6 2 6
4
13
8 5
2 5

3
Fig.3.21

22. Între 11 puncte ale unei ferme agricole, există o reţea de


canale reprezentată în figura 3.22, unde pe fiecare arc este trecut
debitul maxim ce poate străbate canalul corespunzător.
Ştiind că apa porneşte din punctul 0 şi în punctul 10 există un
lot care are cea mai mare nevoie de apă, se cere să determine modul
în care trebuie folosită reţeaua de canale, astfel încât, în punctul 10
să ajungă un debit maxim de apă.
10
1 8 7
9 4 10 1 14
14 1
14 8
18 1
0 2 6 8 9
16 10
3 8
20 5 10
7 5 6
3 10 10
9
Fig.3.22

45
4. INDICAŢII ŞI RĂSPUNSURI LA PROBLEMELE
PROPUSE SPRE REZOLVARE

1. Se găsesc drumurile: (1,2,7,8), (1,3,6,7,8), (1,3,8) şi (1,8) a


căror valoare este 9.
2. Valoarea minimă 10, este atinsă pe drumul: (0,1,3,6,7,9).
3. Drumurile corespunzătoare valorii minime 17, sunt:
(1,2,3,4,5,6,8), (1,2,5,6,8), (1,3,4,5,6,8).
4. Se găsesc drumurile: (1,4,5,7), (1,3,5,7), (1,2,3,5,7),
(1,4,6,5,7), a căror valoare este 9.
5. Ruta optimă care stabileşte timpul optim de transmitere a
informaţiei, dintre vârfurile 0 şi 7, este dată de drumul de valoare
minimă între vârfurile 0 şi 7 ale grafului ce reprezintă sistemul de
comunicare a datelor informaţiilor. Drumurile de valoare minimă 8
care dau rutele optime, sunt (0,2,5,3,7) şi (0,2,3,7).
6. Determinarea schemei instalaţiei reţelei telefonice de cost
minim se reduce la determinarea drumului de valoare minimă între
vârfurile 0 şi 7 din graful dat. Drumurile de valoare minimă 17 sunt:
(0,1,2,4,5,6,7), (0,2,4,5,6,7), (0,1,2,4,5,7), (0,2,4,5,7), (0,1,2,4,7),
(0,2,4,7). Dintre toate aceste drumuri de aceeaşi valoare, drumul
(0,1,2,4,5,6,7) determină schema instalaţiei reţelei telefonice care
trece prin numărul cel mai mare de localităţi.
7. Drumurile corespunzătoare valorii minime 9, sunt:
(1,2,4,6,8), (1,2,3,5,6,8).
8. Drumul corespunzător valorii minime 10: (0,1,3,2,4,5).
9. Drumul corespunzător valorii minime 7: (1,5,7,9).
10. Găsirea traseului de cost total minim se reduce la
determinarea drumului de valoare minimă între vârfurile 0 şi 8 din
graful dat. Drumurile corespunzătoare valorii minime 19, sunt:
A = (0,1,5,6,7,8), B = (0,1,6,7,8), C = (0,1,5,7,8).
Din punct de vedere economic, existenţa soluţiei multiple (A şi
C) oferă posibilitatea alegerii, după nevoie, a unuia sau a celuilalt
drum; în cazul de faţă, vom alege drumul A, care trece prin centrul
industrial 5, ca şi drumul C, în plus, la acelaşi cost, şoseaua trece
prin cele mai multe localităţi.
46
11. Se caută ruta corespunzătoare drumului de valoare minimă
în graful care dă sistemul de linii ferate între localităţi.
Corespunzător valorii minime 6, se obţine ruta (0,1,4,6).
12. Drumurile corespunzătoare valorii minime 27: (0, 1, 2, 3,
5, 4, 9, 10, 12), (0,1,2,3,4,9,10,12).
13. Se găsesc drumurile: (1,2,4,5,6,7) şi (1,2,5,6,7) a căror
valoare este 18.
14. Drumul (0,1,2,5,6) sau (0,1,2,4,6) cu valoarea maximă 15.
15. Drumul (0,2,4,5,7,8) are valoarea maximă 12.
16. Determinarea rutelor, pentru care beneficiul obţinut este
maxim, se reduce la determinarea drumului de valoare maximă între
vârfurile 0 şi 7, ale grafului dat. Drumurile de valoare maximă 22
sunt:
(0,1,2,3,4,5,6,7), (0,2,3,4,5,6,7), (0,1,2,3,4,5,7),
(0,2,3,4,5,7), (0,1,2,3,4,7), (0,2,3,4,7).
În funcţie de numărul mijloacelor de transport existente, care
diferă de la o zi la alta, se poate alege una sau mai multe din rutele
indicate; valoarea maximă găsită 22, reprezintă beneficiul maxim.
17. Dacă fiecărui arc, care are extremitatea finală în vârful j, îi
ataşăm valoarea corespunzătoare vârfului, atunci turneele ce vor
trebui câştigate sunt date de succesiunea vârfurilor care determină
drumul de valoare maximă între 0 şi 8.
Drumul de valoare maximă 25 determină un număr de 6 turnee
care vor trebui câştigate; ordinea acestor turnee este dată de
succesiunea vârfurilor din drumul (0,1,2,4,7,6,8); numărul maxim
de puncte ce se pot obţine este 25.
18. A   4,5,6,7 - mulţimea vârfurilor nemarcate
   A   1,4  ,  2,4 ,  2,5 ,  3,6  - tăietura
f max  c    A   14 .
19. Planul optim de transport cerut, este determinat de fluxul
maxim ce traversează reţeaua. Aplicînd algoritmul Ford-Fulkerson
plecând de la fluxul iniţial egal cu zero, se determină un flux
maximal care ne dă planul optim de transport. Valoarea fluxului
maxim este determinată de capacitatea secţiunii minimale:
47
 
   A   1,6  ,  5,6  ,  5,7  ,  4,7  ,  8,9  şi f max  c    A  28 ; de
aici, deducem că într-o primă etapă, putem trimite din portul 0 spre
portul 9, un număr de 28 vapoare.
20. A  1,2,4,5,6,7 - mulţimea vârfurilor nemarcate
   A    0,1 ,  0,2  3,5 ,  3,6  - tăietura

f max  c    A   c 0,1  c 0,2  c 3,5  c 3,6   8  5  2  4  19


21. A  1,2,4,5,6 - mulţimea vârfurilor nemarcate
   A    0,1 ,  0,2 ,  3,4  ,  3,5 - tăietura

f max  c   A   c 0,1  c 0,2  c 3,4  c 3,5  7  6  2  5  20


22. A   7,8,9,10 ,    A   1,7  ,  4,10 ,  6,8 ,  5,10 ,  3,9 
f max  c   A   10  10  1  10  10  41

48
BIBLIOGRAFIE

1. A.V. Aho, J.E. Hopcroft, J.D.Ullman. Data structures and


Algorithms. Addison-Wesley, 1983. – 436 p.
2. Ф.А.Новиков. Дискретная математика для программистов.
Учебник. С.Петербург, Питер, 2001.- 301c.
3. Thomas H. Cormen. Charles E. Leiserson. Ronald L. Rivest.
Introducere în algoritmi. Cluj-Napoca: Editura Computer Libris
Agora, 2000.
4. Окулов С. Программирование в алгоритмах. – М., БИНОМ,
2002. – 341 с.
5. G. Marusic, G. Ceban, R Bulai MATEMATICA DISCRETĂ.
Îndicaţii metodice pentru seminare, UTM, Chişinău, 2008, - 92p.

6. Фалько Н., Кулев М., Марусик Г. ИСПОЛЬЗОВАНИЕ


СТРУКТУР ДАННЫХ В АЛГОРИТМАХ НА ГРАФАХ И
ДЕРЕВЬЯХ: Методические указания и задания для
лабораторных работ, UTM, Chişinău, 2015. – 50 с.
7.https://neerc.ifmo.ru/wiki/index.php?
title=Алгоритм_ФордаФалкерсона,_реализация_с_помощью_по
иска_в_глубину

49
CUPRINS

Introducere……………………………………………………….....3
1. Fluxul maxim. Algoritmul Ford-Fulkerson……………………...5
1.1. Probleme rezolvate………………………………………….5
1.2. Programul în limbajul C pentru determinarea valoarei
fluxului maxim într-un graf arbitrar folosind algoritmul
Ford-Fulkerson……………………………………………..8
2. Drumul de valoare minimă (maximă). Algoritmul lui Ford,
Bellman-Calaba………………………………………………..14
2.1. Probleme rezolvate………………………………………..14
2.2. Programul în limbajul C pentru determinarea drumului de
valoare minimă într-un graf arbitrar folosind algoritmul lui
Ford......................................................................................23
2.3. Programul în limbajul C pentru determinarea drumului de
valoare minimă (maximă) într-un graf arbitrar folosind
algoritmul lui Ford sau Bellman-Calaba..............................27
3. Probleme propuse spre rezolvare……………………………….34
4. Indicaţii şi răspunsuri la problemele propuse spre rezolvare….45
Bibliografie……………………………………………………….48

50
ASPECTE ALGORITMICE DIN TEORIA GRAFURILOR
PRIVIND FLUX MAXIM ŞI DRUMURI MINIME (MAXIME)

Îndrumar metodic la disciplinele "Matematici speciale" şi


"Structuri de date şi algoritmi"

Autori: G. Marusic
N. Falico
M. Kulev
T. Tiholaz

Redactor: ..................................
–––––––––––––––––––––––––––––––––––––––––––––––––––––
Bun de tipar 00.03.18. Formatul hârtiei 60x84 1/16
Hârtie ofset. Tipar RISO Tirajul 00 ex.
Coli de tipar 3,0 Comanda nr.00
–––––––––––––––––––––––––––––––––––––––––––––––––––
2004, UTM, Chişinău, bd. Ştefan cel Mare, 168
Editura”Tehnica-UTM”
2068,Chişinău, str. Studenţilor, 9/9

51

S-ar putea să vă placă și