Documente Academic
Documente Profesional
Documente Cultură
Notiuni de baza
Un graf orientat G este format dintr-o pereche ordonata de multimi
G=(X,U). ca si in cazul grafurilor neorientate, X este multimea varfurilor
sau nodurilor grafului.Multimea U este formata din perechi ordonate de
elemente distincte din X, numite arce.Orice arc u U va fi notat prin
u=(x,y) cu x,yX si xy.
Spunem ca varful x este extremitatea initiala a arcului u, iar varful y
este extremitatea finala a arcului u. Spre deosebire de cazul grafurilor
neorientate, notatiile(x,y) si (y,x) vor desemna doua arce diferite.
Daca graful G contine arcul (x,y) vom spune ca varfurile x si y sunt
adiacente in G si amandoua sunt incidente cu arcul (x,y). Deci, un graf
orientat G poate fi imaginat ca o multime de varfuri, dintre care unele sunt
unite doua cate doua prin arce. Un graf orientat poate fi desenat in plan
reprezentand varfurile sale prin puncte si arcele prin sageti care sunt
orientate de la extremitatea initiala catre extremitatea finala a fiecarui arc.
Graful orientat G=(X,U) unde:
X={ 1,2, . ,8} si U={(1,2), (2,3), (3,1), (3,2), (2,4), (4,5), (3,5), (6,8),
(8,7), (7,8),(7,6)} se reprezinta ca in figura:
2
u5
u1
1
u3
u4
u7
u2
3
u6
u1=(1,2),
Gradul exterior al unui varf x, notat prin d+(x), este numarul arcelor
de forma (x,y) cu yX. Gradul exterior al unui varf x, notat prin d-(x),este
numarul arcelor de forma (y,x) cu yX.
Un graf partial al unui graf orientat G=(X,U) se defineste in acelasi
mod ca si in cazul neorientat. El este un graf G1=(X,V) unde VU, deci este
graful G insusi sau se obtine din G prin suprimarea anumitor arce.
Si definitia unui subgraf al unui graf orientat G=(X,U) este
asemanatoare cu cazul neorientat.Prin definiie , un subgraf al lui G este un
graf H=(Y,V), unde YX, iar arcele din V sunt toate arcele din U care au
ambele extremiai in mulimea de varfuri Y.
Deci un subgraf H al unui graf orientat G este graful G insui sau se
obine din G prin suprimarea anumitor varfuri si a tuturor arcelor incidente
cu acestea .
Vom spune ca subgraful H este indus sau generat de multimea de
varfuri Y.
Astfel,subgraful grafului G din figura ,indus de multimea de varfuri
Y1 ={1,2,4,5} are ca multime de arce multimea V 1 ={(1,2), (2,4), (4,5)},iar
subgraful indus de multimea de varfuri Y2 ={6,7,8} are multimea arcelor
V2={(7,6),(6,8),(7,8),(8,7)}.
Un graf orientat este complet daca oricare doua varfuri sunt adiacente.
In timp ce in cazul neorientat un graf complet cu n varfuri este unic
determinat, in cazul orientat exista mai multe grafuri complete cu un numar
dat de varfuri.Ele se deosebesc fie prin orientarea arcelor , fie prin faptul ca
intre doua varfuri oarecare exista un arc sau doua arce de sensuri contrare.
Un lant al unui graf orientat se defineste ca un sir de arce:
L=[u1,u2,..,up]
Cu proprietatea ca oricare arc uI din acest sir are comuna o extremitate cu
ui-1 , iar cealalta extremitate este comuna cu ui+1 pentru orice i=1,...,p-1.
Daca toate arcele lantului L au aceeasi orientare ,care este data de
sensul deplasarii de la x0 catre xr lantul se numeste drum.
Deci un drum intr-un graf orientat G=(X,U) este un sir de varfuri
notat :
D=(x0,x1,...,xr)
cu proprietatea ca (x0,x1), (x1,x2), .... , (xr-1,xr)U, deci sunt arce ale grafului.
Varfurile x0 si xr se numesc extremitatile drumului D. Daca varfurile
x0 ,x1 , ... , xr sunt distincte doua cate doua, drumul D se numeste elementar.
Din aceste definitii rezulta ca orice drum este si lant , daca il privim ca un sir
de arce.
2
daca i=j
+
daca (xi ,xj)U
Intuitiv,aceasta alegere ar insemna ca drumul cel mai scurt de la xi la
el insusi este de lungime 0 iar inexistenta arcului ( xi, xj )este totuna cu
existenta unui arc de lungime infinita ( care evident nu va interveni
niciodata intr-un eventual drum minim de la xi la xj ) .
3
1
2
5
3
1
3
6
1 daca xiS
program Dijkstra;
const nmax=15;
inf=maxint div 2;
var c:array[1..nmax , 1..nmax] of integer;
k,i,j,arc,m,n,x,y,z,xp: intrger;
s,d,prec:array[1..nmax] of integer
g: boolean;
procedure min(var k: integer);
var m,i: integer;
begin
m:=inf*2;
for i:=1 to n do
if (s[i]=0) and (d[i]<m) then
begin m:=d[i];
k:=i;
end
end;
procedure drum(i:integer);
begin
if i<>0 then
begin
drum(prec[i]);
write(i);
end
else writeln
end;
begin
writeln( dati nr de noduri ); readln (n);
for i:=1 to n do
forj:=1 to n do c[i,j]:=inf;
for i:=1 to n do c[i,j]:=0;
end
else begin
writeln(Drum minim de la ,xp,la,i);
drum(i);
writeln
end
end.
CIJ =
daca i=j
lungimea drumului minim de la xi la xj daca exista
drum de la xi la xj
daca nu exista drum de la xi la xj
Determinarea matricii C este asemanatoare algoritmului Roy-Warshall
pentru obtinerea matricii drumurilor
Se porneste de la matricea costurilor C
for k=1 to n
for i=1 to n (ik)
for j=1 to n (jk)
cij : = min (cij , cik + ckj)
endfor
endfor
endfor
Observatie : Acest algoritm poate fi privit ca o succesiune de n
transformari aplicate matricii C , o transformare k fiind astfel :
Tk(A) = B, B =(bij)nn , bij= min(aij ,aik+a) i,j { 1 , ... , n}.
10
procedure initc;
{initializeaza matricea costurilor C}
var i,j,x,y,z: word;
begin
write(` Dati nr de noduri: `);
readln(n);
for i:=1 to n do
begin
for j:=1 to n do
c[i,j] := inf;
c[i,i] :=0;
end;
write(`Dati nr de noduri : `);
readln(m);
for i:=1 to m do
begin
write(`Extremitatile si lungimea arcului `,i,`: `);
readln(x,y,z);
c[x,y]:=z;
end;
end;
procedure initd;
{iniializeaza matricea D}
var i,j:integer;
begin
for i:=1 to n do
for j:=1 to n do
if(c[i,j]<inf)and(i<>j) then d[i,j]=[i]
else d[i,j]=[];
end;
procedure drum(i,j:integer);
{genereaza in vectorul dr un drum minim de la i la j pornind din nodul j}
var k: word ;
begin
if i<>j then
begin
for k:=1 to n do
if k in d[i,j] then
begin
lg:=lg+1;
dr[lg]:=k;
12
drum(i,k);
lg:=lg 1
end;
end
else begin
writeln;
for k:=lg downto 1 do
write(dr[k]:4)
end;
end;
procedure afiare;
var i,j:word;
{afiarea rezultatelor}
begin
for i:= 1 to n do
for j:=1 to n do
begin
writeln:
if c[i,j]=inf then
writeln( nu exista drumuri minime de la ,i, la ,j,)
else
begin
writeln( lungimea drumurilor minime de la ,i, la,j, este
,c[i,j]);
if i<> i then begin
lg:=1;
dr[1]:=j
drum(i,j)
end
end
end
end;
begin
initc;
initd;
for k:=1 to n do
for i:=1 to n do
for j:=1 to n do
if c[i,j]>c[i,k]+c[k,j] then
13
begin
c[i,j]:=c[i,k]+c[k,j]:
d[i,j]:=d[k,j]
end
else
if c[i,j]=c[i,k]+c[k,j] then
d[i,j]:=d[i,j]+d[k,j];
afiare;
end.
-
0
14
for k=1 to n
for i=1 to n (ki)
for j=1 to n (kj)
if mij<mik+mkj
then mij := mik+mkj
dij := dkj
else
if mij := mik+ mkj
then dij:= dij dkj
endif
endif
endfor
endfor
endfor.
In matricea M vom avea in final lungimile drumurilor maxime intre
oricare 2 noduri iar in dij i ,j{1 , ... , n} vom avea multimea nodurilor ce
pot precede pe xj intr-un drum maxim de la xi la xj.
Mai jos este dat programul Pascal de determinare a tuturor drumurilor
maxime intre oricare doua noduri folosind algoritmul prezentat anterior ,
pentru un graf G=(X, U) , X={1 , ... , n} .
program roymax;
const nmax=20;
inf=-(maxint div 2);
type multime = set of 1 .. nmax;
var c: array [1 .. nmax , 1 .. nmax] of integer;
{c initial matricea costurilor}
d: array [1 .. nmax , 1 .. nmax] of multime;
dr: array[1 .. nmax] of 1 .. nmax;
n,m,i,j,k,lg:word;
procedure initc;
{initializeaza matricea costurilor C}
15
var i,j,x,y,z:word;
begin
write(Dati nr de noduri:);
readln(n);
for i:=1 to n do
begin
for j:=1 to n do
c[i,j]:= inf;
c[i,j]:=0
end;
write(Dati nr de ace :);
readln(m);
for i:=1 to m do
begin
write(Extremitatile si lungimea arcului,i, :);
readln(x,y,z);
c[x,y] :=z;
end
end;
procedure initd ; {initializeaza matricea D}
var i,j : integer ;
begin
for i:=1 to n do
for j:=1 to n do
if (c[i,j]> inf) and (i<>j) then d[i,j]:=[i]
else d[i,j]:=[];
end;
prodcedure drum(i,j:integer);
var k:word;
begin
if i<>j then
begin
for k:=1 to n do
if k in d[i,j] then
begin
lg:= lg+1;
dr[lg]:=k;
drum(i,k),
lg:=lg-1
16
end;
end
else begin
writeln;
for k:=lg downto 1 do
write(dr[k]:4)
end;
end;
procedure afisare;
var i,j:word;
begin
for i:=1 to n do
for j:=1 to n do
begin
writeln;
if c[i,j]=inf then
writeln( nu exista drum intre ,i, si ,j)
else
begin
writeln(Lungimea drumurilor maxime de la,i,la,j, este
,c[i,j]);
if i<>j then begin
lg:=1;
dr[1]:=j;
drum(i,j)
end
end
end
end;
begin
initc;
initd;
for k:=1 to n do
for i:=1 to n do
for j:=1 to n do
if (c[i,k]<>inf) and (c[k,j]<>inf) then
if (c[i,j]<c[i,k]+c[k,j] ) then
begin
c[i,j]:=c[i,k]+c[k,j];
17
d[i,j]:=d[k,j];
end
else
if c[i,j]=c[i,k]+c[k,j] then d[i,j]:=d[i,j]+d[k,j];
afisare;
end.
18
19
20