Documente Academic
Documente Profesional
Documente Cultură
Chişinău
2018
0
UNIVERSITATEA TEHNICĂ A MOLDOVEI
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”.
UTM, 2018
2
INTRODUCERE
4
1. FLUXUL MAXIM. ALGORITMUL FORD-
FULKERSON
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 uU.
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
2
3
a b
1
1 2
3
Fig. 1.3
Rezolvare:
7
I. Vom considera fluxul iniţial f(u) = 0 uU.
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
#include <memory.h>
#include <stdio.h>
const int MAX_V = 100;
8
int NUM_V; // number of verticies
const int INF = 10000;
{
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
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
Fig.2.1
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
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
1 2 4 5 6 7
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
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
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
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
1 2 4 5 6 7
#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
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.
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,
34
3. PROBLEME PROPUSE SPRE REZOLVARE
Fig.3.1
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
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
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
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
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
39
2 5
1 1 4
1 2
0
4 3
4 6
3 4
2 2
5
3
Fig.3.11
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
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
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
5 6
0 2 4 6 8
1 2
4
5
3
1
7
3 4
3 7
Fig. 3.17
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
45
4. INDICAŢII ŞI RĂSPUNSURI LA PROBLEMELE
PROPUSE SPRE REZOLVARE
48
BIBLIOGRAFIE
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)
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