Documente Academic
Documente Profesional
Documente Cultură
1
- reţele de calculatoare, clasificarea reţelelor, protocoale de reţea (noţiuni generale)
………………………………………………………………………..178
- reţeaua Internet – descriere generală, adresarea în
Internet………………………………………………………………..180
- (*) serviciile reţelei Internet (transferarea fişierelor prin ftp, poşta electronică, www,
telnet) …………………………………………………………………182
- (*) căutarea informaţiei pe Internet – motoare de
căutare…………………………………………………………………188
Recenzie,
Cartea este destinată concursurilor de titularizare si grade didactice din
invatamânt,management educational cu sectiunea IT dar si elevilor sau
studenţilor din perspectiva examenului de bacalaureat sau olimpiadelor
scolare,respectând in totalitate programa şcolara in acest sens.Salutăm aparitia
celui de al doilea volum ,care prin completitudinea expunerii matematice si
informatice este un suficient material pentru concursurile scolare.Cartea a fost
perfect conceputa cu multa trudă in prelucrarea materialului de oameni cu
experienta cum ar fi prof.Bogdan P.Constantin,Col.Nat.”Tudor
Vladimirescu”,Tg-Jiu,prof. Ion Săceanu,director adj.Colegiu Tehnic Matasari.
05.01.2007
Prof.univ.dr Octavian Dogaru,Universitatea din Timisoara
Referenti ştiintifici:
Prof.univ.dr Ion Vladimirescu Rector ,Universitatea din Craiova
Prof.univ.dr Octavian Dogaru,Universitatea din Timisoara
Prof.univ.dr Udrişte Constantin ,Universitatea PolitehnicaBucuresti
Conf.univ.dr Constantin Lupşoiu ,Universitatea din Craiova
Prof.Drd.Dan Dorin Taşcău,Director Colegiul National “Tudor
Vladimirescu”,TG-JIu
Prof.Tăculescu Violeta, Colegiul National “Tudor Vladimirescu”,TG-JIu
2
Alături de Greedy,programarea dinamica este o tehnica ce conduce, de cele mai
multe ori, la un timp de calcul polinomial.Mai mult, ea furnizează in totdeauna soluţia
optima .Din nefericire, programarea dinamica nu se poate aplica tuturor problemelor, ci
numai care îndeplinesc anumite condiţii.
Se considera o problema in care rezultatul se obţine ca urmare a unui sir de decizii D1,
D2,......Dn. In urma deciziei D1 sistemul evoluează din starea S0 in starea S1,in urma
deciziei D2 sistemul evoluează din starea S1 in starea S2,....,in urma deciziei Dn
sistemul evoluează din starea Sn-1 in starea Sn.
Daca D1, D2,....Dn este un sir de decizii care conduce sistemul in mod optim din S0 in
Sn,atunci trebuie îndeplinita una din condiţiile următoare (principiul de optimalitate):
1)Dk...Dn este un sir de decizii ce conduce optim sistemul din starea Sk-1 in starea
Sn,Ak,1<=k<=n;
2)D1....Dk este un sir de decizii ce conduce optim sistemul din starea S0 in starea
Dk,Ak,1<=K<=n;
3)Dk+1...Dn,D1...Dk sunt şiruri de decizii care conduc optim sistemul starea Sk in starea
Sn, respectiv din starea D0 in starea Sk,Ak,1<=k<=n.
=>Daca principiul de optimalitate se verifica in forma 1,spunem ca se aplica programarea
dinamica metoda înainte.
=>Daca principul de oplimalitate se verifica in forma 2, spunem ca se aplica programarea
dinamica înapoi.
=>Daca principiul de optimalitate se verifica in forma 3, spunem ca se aplica programarea
dinamica metoda mixta.
Programarea dinamica se poate aplica problemelor la care optimul general implica optimul
parţial.
Faptul ca optimul general determina optimul parţial, nu înseamnă ca optimul parţial determina
optimul general.
cu toate acestea, faptul ca optimul general impune optimul parţial ne este de mare
ajutor:căutam optimul general,intre optimele parţiale, pe care le reţinem la fiecare pas.
Oricum,căutarea se reduce considerabil.
Problema triunghiului. Se considera un triunghi de numere naturale format din n linii.
Prima linie conţine un număr,a doua numere,........ultima n numere naturale. Cu ajutorul
acestui triunghi se pot forma sume de numere naturale in felul următor:
-se porneşte cu numărul din linia unu;
-succesorul unui număr se afla pe linia următoare plasat sub el(acees coloana) sau pe
diagonala la dreapta(coloana creste cu 1).
Care este cea mai mare suma care se poate forma astfel si care sunt numerele care o
alcătuiesc:
Exemplu:n=4;
2
3 5
6 3 4
5 6 1 4
Se pot forma mai multe sume:
S1=2+3+6+5=16;
S2=2+5+4+1=12;
Sk=2+3+6+6=17 (care sete[i suma maxim').
Sa observam ca se pot forma 2 la puterea n-1 sume de acest fel.A le lua in considerare pe
toate pentru a găsi valoarea maxima nu este eficient.
Pentru etapa i se tratează linia i a triunghiului. Fie un sir de n numere care respecta condiţiile
problemei si care formează suma maxima. In acest sir,consideram numărul care a fost preluat
de pe linia i. Numerele intre i+1 si n,formează o suma maxima in raport cu sumele care se pot
forma începând cu numărul preluat de pe linia i,contrar,se contrazice ipoteza. In aceasta
situaţie se poate aplica programarea dinamica,metoda înainte.
3
Vom forma un triunghi,de la baza către vârf,cu sumele maxime care se pot forma cu fiecare
numar.Daca am citit triunghiul de numere intr-o matrice T si calculam sumele intr-o matrice C
vom avea relaţiile următoare:
C[n][1]:=T[n][1];
C[n][2]:=T[n][2];
C[n][n]:=T[n][n];
Pentru linia i (i<n), cele i sume maxime care se obţin astfel:
C[i][j]=max{T[i][j]+C[i+1][j],T[i][j]+C[i+1][j+1]},i apartine mulţimii {1,2,....,n-1) iar j aparţine
mulţimii {1,.....,i}.
Sa rezolvam problema propusa ca exemplu:
Linia 4 a matricei C va fi linia n a matricei T:5 6 1 4;
Linia 3 se calculează astfel:
C[3][1]=max{6+5,6+6}=12;
C[3][2]=max{3+6,3+1}=9;
C[3][3]=max{4+1,4+4}=8;
Linia 2:
C[2][1]=max{3+12,3+9}=15;
C[2][3]=max{5+9,5+8}=14;
Linia 1
C[1][1]=max{2+15,2+14}=17.
Aceasta este si cea mai mare suma care se poate forma.
Pentru a tipări numerele luate in calcul se foloseşte o matrice numita DRUM in care pentru
fiecare i aparţinând mulţimii mai sus menţionate si j la fel aparţinând mulţimii menţionate mai
sus se retine coloana in care se găseşte succesorul lui T[i][j].
{Fie un triunghi care are pe prima linie un număr pe a doua doua ....
Sa se calculeze cea mai mare dintre sumele ce apare drumurile ce pleacă
din vârf si ajung la baza}
const dimmax=100;
type numar=0..9;
var c:array[1..dimmax,1..dimmax] of numar;
t,cc:array[1..dimmax,1..dimmax] of numar;
d,n,i,j:integer;
begin
writeln('cite linii avem in triunghi ');readln(n);
for i:=1 to n do
for j:=1 to i do
begin
writeln('t[',i,',',j,' ]=');
readln(t[i,j]);
end;
for i:=1 to n do
begin
cc[n,j]:=j;
c[n,j]:=t[n,j];
end;
for i:=n-1 downto 1 do
for j:=1 to i do
if c[i+1,j]+t[i,j]>c[i+1,j+1]+t[i,j]
then
begin
cc[i,j]:=j;
c[i,j]:=c[i+1,j]+t[i,j];
end
else
begin
cc[i,j]:=j+1;
c[i,j]:=c[i+1,j+1]+t[i,j] ;
4
end;
writeln('suma este ',c[1,1]);
d:=cc[1,1];
writeln(1);
for i:=1 to n-1 do
begin
writeln(cc[i,d]);
d:=cc[i,d];
end;
readln;
end.
{Sa se calculeze cit e lungimea unui subsir crescator al unui sir initial
in cazul in care este maxima}
var v:array[0..20] of integer;
n,i:integer;
function lungime(k:integer):integer;
var max,i:integer;
begin
if k=n then lungime:=1 else
begin
max:=0;
for i:=K+1 to n do
if (max<lungime(i)) and (v[i]>=v[k]) then
max:=lungime(i);
Lungime:=max+1;
end;
end;
5
begin
write('cite elemente are sirul ');readln(n);
v[0]:=0;
for i:=1 to n do
begin
writeln('v[',i,']=');
readln(v[i]);
end;
writeln(' lungimea maxima este ',lungime(0)-1);
readln;
end.
6
-inmultind matricele Ak+1 x.....x Aj se obţine o matrice cu un nr. de linii egal cu acela al
matricei Ak+1 (DIM(k+1)) si cu un nr. de coloane egal cu acela al matricei Aj (DIM(j+1));
-prin înmulţirea celor doua matrice se obţine matricea rezultat al înmulţirii Ai x....x Aj, iar pt.
aceasta înmulţire de matrice se efectuează DIM(i) x DIM(k+1) x DIM(j+1) înmulţiri;
~Relaţia sintetizează faptul ca pt. a obţine nr. de înmulţiri optim pt. produsul Ai x....x Aj se
înmulţesc doua matrice, una obţinuta ca produs optim intre Ai x....x Ak si cealalalta obţinuta ca
produs optim intre Ak+1 x....x Aj, in ipoteza in care cunoaştem nr. de înmulţiri necesar
efectuării acestor doua produse oricare ar fi k, cuprins intre limitele date.
~Aceasta observaţie este o consecinţa directa a programării dinamice si anume ca produsul
efectuat optim intre matricele prezentate se reduce in ultima instanţa la a efectua un produs
intre 2 matrice cu condiţia ca acestea sa fie calculate optim(produsul lor sa aiba un număr
minim de înmulţiri).
Se pune problema cum putem efectua acest calcul utilizând relaţiile prezentate. Pentru
exemplificare vom utiliza exemplul dat la începutul acestui capitol. Datorita relaţiei 1, diagonala
pricipala a maricei A( cu 4 lini si 4 coloane) va fi alcătuita numai din elemente având valoarea
0. s
Iniţial se pot calcula numai elemente A(i,i+1),adică A(1,2),A(2,3),A(3,4)-elemente situate pe o
paralela la digonala principala a matricei A.Este cazul sa observam ca porţiunea din matrice
situata sub diagonala principala este neutilizata.In concluzie,avem
A(1,2)=100,A(2,3)=10,A(3,4)=100.Matricea A va arata astfel:
0 100 x x
x 0 10 x
A= x x 0 100
x x x 0
In continuare calculam:
A(1,3)=min{A(1,k)+A(k+1,3)+DIM(1)*DIM(k+1)*DIM(4)}=min{0+10+10*1*1,100+0+10*10*1}=20
A(2,4)=min{A(2,k)+A(k+1,4)+DIM(2)*DIM(k+1)*DIM(5)}=min{0+100+1*10*10,10+0+1*1*10}=20
A(1,4)=min{A(1,k)
+A(k+1,4)+DIM(1)*DIM(K+1)*DIM(5)}=min{0+20+10*1*10,100+100+10*10,20+0+10*1*10}=12
0;
.
0 100 20 120
x 0 10 20
A= x x 0 100
x x x 0
In concluzie,pt. exemplul nostru, se fac minim 120 de înmulţiri,rezultat luat din matricea A si
anume A(1,4).
var k:integer;
{Prin programare dinamica sa se determine numarul begin
minim de inmultiri care sa se faca if i<j then begin
cind se dau dimensiunile matricelor k:=m[j,i];
ex:n=4 if i<>k then begin
10 1 10 1 10} write('(');
paranteze(i,k);
program inm_optima; write(')');
const nmax=20; end
type vector=array[1..nmax] of word; else paranteze(i,k);
tabl=array[1..nmax,1..nmax] of word; write('x');
var p:vector; if k+1<>j then begin
m:tabl;n,i,j,k,imin:integer;min,v:word; write('(');
procedure paranteze(i,j:integer); paranteze(k+1,j);
7
write(')') begin
end v:=m[i,k]+m[k+1,j]+p[i]*p[k+1]*p[j+1];
else paranteze(k+1,j); if min>v then begin
end min:=v;
else write('A',i) imin:=k
end; end;
begin end;
write('Nr. de matrici:'); m[i,j]:=min;
readln(n); m[j,i]:=imin;
writeln('Dimensiuni matricelor:'); end;
for i:=1 to n+1 do read(p[i]); writeln('Numarul minim de inmultiri este:',m[1,n]);
for i:=n downto 1 do writeln('Aceasta se obtine pentru urmatoarea ordine
for j:=i+1 to n do a inmultirilor');
begin paranteze(1,n);
min:=m[i,i]+m[i+1,j]+p[i]*p[i+1]*p[j+1]; readln;
imin:=i; end.
for k:=i+1 to j-1 do
( )
a11……………..0
( )
. . . 0……………0
N=D= , L= a12 .
. . . . .
. . .
0……….....ann an1……..ann-1.0
)
0 a12…………a1n
(
. . .
R= . . .
. an-1n
0………………0
P=N-A=-(L+R)=>A=N-P
Ax=b => Nx(K+1)=Px (K) +b , dorind sa aploximam solutia sistemului printr-un
termen al lui xk.
OBS :
( ) -( )
A=L+D+R a11……………..0 a11……………..a1n
P=N-A= . . . . . .
. . .
. . . . . .
. . . an1……….....ann
0……….....ann
-(aij) , j<>i
8
=
aii=0
X (k+1) =N -1 *P*x (k) +N -1 *b, G, ma intereseaza norma lui si pun conditiile |g ij|<1 rezulta
n
∑aij >1 <= >∑|aii/aij|<1 = >||G||=max ∑|gij|=max ∑|aij/aii|<1
=>|aij|/
j=1 j=1 1≤i≤n ; j=1 j=1
j<>i j<>i j<>i
p→∞
Cum||G||<1=>||G||p 0
||x (m+1) -x (m) ||=||G(x (m) -x (m-1) ||=…=||G (m) || || (x (1) -x(0) )||
si deci cum
||x (k+p) -x (k) ||=|x (k+p) -x (k+p-1) +x (k+p-1) -x (k+p-2) +...-x (k) ||≤
≤||x (k+p) -x (k+p-1) ||+||x (k+p-1) -x (k+p-2) ||+...+)||+||x (k+p-1) -x (k+p-2) ||+...+||x (k+1) -
-x ( k) || ≤||G|| k+p-1 *||x (1) -x^ (0) ||+...||G|| k *||x (-1) -x (0) ||=
=(||G|| k+p-1 +...||G|| k )*||x (1) -x (0) ||=||G|| k *(1-||G|| p /(1-||G||)*||x (1) -x (0) ||
deci , cand p→∞ ||x (k+p) -x (k) || ≤ ||G|| (k) * (1-||G|| (p) )/1-||G||) * ||x (1) -x (0) || rezulta
||x-x (k) ||<||G|| k * 1 / (1-||G||)*||x (1 ) -x (0) ||
PROGRAM JACOBI ;
Const max=10 ;
Type vector=array[1..10] of real;
Var x,b:vector; a:array[1..10,1..10]of real;
n,i:integer;
function rezolva (nit:integer :boolean;
var y:vector;c,j,k:integer; v:real; g:boolean;
function ZERO:Boolean;
var L,m:integer ; t:real;
begin
zero:=false;
L:=j;
While (l<n) and (a[I,j]=0 do L:=L+1
If (a[L,j]<>0 then zero:=true;
end;
begin
g:=true;i:=0;
repeat
for j:=1 to n do
if zero and g then
begin
y[j]:=x[j];v:=0;
for k:=1 to n do
if j<>k thenn v:=v +a[i,k]*y[k];
x[j]:=(=b[j]-v)/a[I,j]);
end
else g:=false;
v:=0;
i:=i+1;
9
for k:=1 to n do
v:=v + sqr(x[k]-y[k]);
until (sqrt(v),1.e-6) or (i>nit) or not g;
end;
rezolva:=g and (i<= nit);
end;
begin
citesc pe n, a[i,j], b[i]
for i:=1 to n do x[i]:=1;
if NOT rezolva (200) then writeln (‘incompatibil’)
else
begin writeln(‘solutia sistemului este’)
write(‘x=c’);
for i:=1 to n-1 do write (x[i]);
end;
end.
ETAPA1
Triangulizarea se face la randul ei intr-un numar finit de etape optinand de sirul martice
( 1) (2) (n)
A =A ; A ,...,A unde
( )
(k) (k) (k) (k) (k)
a11 a12…………….a1 k-1 a 1 k………………….a 1n
(k) (k) (k) (k)
0 a22…… ……....a 2 k-1 a 2 k…………………..a 2 n
………………………………………………………………………….
A= (k) (k) (k)
( k)
0 0………….ak-1k-1 ak-1k………………….ak-1n
akk≠0 (k) (k)
0 0……………..0 akk …………………….akn
…………………………………………………………………………
(k) (k)
0 0……………..0 ank…………………….ann
( )
1 0………0 0…………0
0 1………0 0…………0
Fie M= ……………………….………..
0 0………-mk+1 k 1…………0
………………………………..
0 0………-mn k 0…………1
(k) (k)
Mik=aik/akk , k+1≤i≤n
(k+1) (k)
A =Mk * A
10
(K+1) (k)
aij = aij ,1≤j≤n ,i≤j≤n =>primele k linii raman necunoscute in matrice
0 ,i≤j≤k , j+1≤i≤n=>primele j coloane de sub diagonala principala sub zero
(k) (k) (k) (k) (k) (k) (k) (k) (k) (k) (k)
aij -mik * akj = aij-aik / akk* akj=(aij * akk- akk * aik)/akk , i≥k+1
j≤n
j>i≥k+1
elementele situate in liniile
si coloanele k+1,k+2,k+3
….n se schimba dupa regula
dreptunghiului
(k) (k)
k……akk………akj………….
(k) (k)
i…….aik………aij…………..
( )
1 -1 2
2 1 1 (1) (1) (1) (1)
A= 1 2 -1 ,A=A , a 11=1 , m2 1=(a2 1)/a11=2/1=2
(1)
m31=a31=1/1=1
c1
( ) ( )
r11 r12 r13…….r1n .
0 r22 r23………..r2n .
R= ………………………… ,,, ,termenii liberi c = .
0 0 0………….rnn .
.
cn
( )
Y1
Sistemul devine Ry=c ,y= .
.
.
OBS : yn
R se obtine din prelucrarea matricei extrase (A,b) unde coloana n+1 care este ocupata de b sei
prelucreaza la fel ca celelalte componente.
Vectorul de solutii finale ale sistemului adica y se obtine dupa formele :
-yn=c / rnn
n
-yi=(ci - ∑ r ik * y k)/r ii, i=n-1,n-2,...,1.
k=i+1
Program sistem ;
Type matrice=array[1..10,1..10] of real ;
Var a:matrice;
b,x:vector;
i,iv,j,k,l:integer;
temp:real;
11
t:boolean;
BEGIN
Citesc pe n,aij,bi
For j:1 to n-1 do begin
iv:=j;
t:=true;
while (iv<=n) and t do
if a[iv,j]=0 then iv:=iv+1
else t:=false;
if t then begin
writeln(‘determinatul sistemului nul’);
end;
if (j<>iv) then begin
for k:=j to ndo begin
temp:=a[j,k];
a[[j,k]:=a[iv,k];
a[iv,k]:=Temp;
end;
temp:=b[j];
b[j]:=b[iv];
b[iv]:=temp;
end;
for l:=j+1 to n do begin
for k:=j+1 to n do
a[l,k]:=a[l,k]-a[j,k]*a[l,j]/a[j,j];
b[l]:=b[l]-b[j]*a[l,j]/z[j,j];
end;
end;
if a[n,n]=0 then begin
writeln)’determinantul principal nul’);
exit;
end;
x[n]:=b[n]/a[n,n];
for i:=n-1 downto 1do begin
temp:=b[i];
for j:=i+1 to n do temp:=temp-a[I,j]*x[j];
x[i]:=temp/a[i,i];
nd;
for i:=1 to n do
writeln(x[i]);
readln;
end.
Fie N-numarul variatiilor de semn din subsirul obtinut prin eliminarea elementelor nule
12
N-numarul variatiilor de semn din subsirul obtinut prin inlocuirea elementelor nule dupa
algoritmul :
Ck-1≠0, Ck=Ck+1=...=Ck+L-1=0,Ck+L≠0
Inlocuit cu
l+i
C* k+i=(-1) sgn(Ck+l),i€[0,L-1];
Teorema Budan Founci,a<b€R,care nu sunt radacini ale lui P .
,Numarul radacinilor reale ale lui P din intervalul (a,b) este N(a)- N(b) sau interior acestuia cu un numar
par .
DEFINITIE
Se numeste polinom de interpolare al functiei f pe nodurile x1,...xn, un polinom P cu
proprietatile :gr(p)≤n-1,p(xi)=yi,1≤i≤n unde f :[a,b]→R, f(xi)=yi ,xi€[a,b],1≤i≤n.
n-1
1 x1......x1
D= .................. =∏(xi-xj)≠0,1≤j≤i≤n are solutii unice
n-1
1 xn.......xn n-1
n-1 n-1
a0+a1 xk+…an-1 * xk =f(xk) a0+a1 xk+…+an-1 xk +an f(xn)=0
n-1 n-1
a0+a1 x +…+an-1 * x =P(x) a0+a1 x+…+an-1 x +an-1 P(x)=0
system liniar omogen ,an≠0 are n+1 ecuatii si n+1 necunoscute =>determinantul e nul.
n- 1 n-1 n-1
1 x1…..x1 f(x1) 1 x1.....x1 0 1 x 1.....x1 f(x1)
n-1 ................................ ...............................
1 x2…...x2 f(x2) n-1 n-1
……………….. =0 1 xn......xn 0 + 1 xn.....xn f(xn) =0
n-1 n-1 n-1
1 xn……xn f(xn) 1 x......x P(x) 1 x .......x 0
n-1
1 x……x P(x)
n-1 n-1
1 x1......x1 1 x1......x1 f(x1)
P(x)* ..................... + .................... =0 => p(x)=D2/D1.
n-1 n-1
1 xn.......xn 1 xn.......xn f(xn)
n-1
1 x.......x 0
D1
D2
Interpolare Langrange
13
N n
ω(x)= ∏(x-xi)
j=1
program lagrange;
type sir=array[1..100] of real;
var fx,vp,bk:real;
x,y:sir;
n,I,j,m:integer;
begin
readln(n);
n:=n+1;
readln(fx);
for i:=1 to n do
begin
readnl(x[i],y[i]);end;
for i:=1 to n do
begin
bk:=1;
for j:=1 to n do
if i<>j then
bk:=bk *(fx-x[i])/(x[j]-x[i]);
vp:=vp+b[k]*y[i];
end;
write(vp);
end.
Interpolare Newton
Stiu
F<x1,…xn>=(f<X1,…,X m-1>-< f<X2,…,X m>)/(X1-Xm)
P(x)=f(X1)+f(x1,x2) * (x-x1)+…
Program newton;
Var x,y:array[1..100] of integer;
S:real;
Xx,I,j,m:integer;
Begin
Readln(m);
For i:=1 to m do
Read(x[i],y[i]);
For j:=1 to m-1 do
For i:=m downto j+1 do
Y[i]:=(y[i-1]-y[i])/(x[i-j]-x[i]);
For j:=0 to m do
Begin
S:=y[m];
14
For i:=y[i]+(j-x[i]) *s;
Write(s);
End.
METODA BISECTIEI
(INJUMATATIRII),COARDEI,TANGENTEI
METODA INJUMATATIRII
15
am=an-1 bm=bn-1 cm=cn-1
siruri convergente
an -->a bn -->b cn -->c
METODA COARDEI
siruri convergente
an -->a bn -->b cn -->c
METODA TANGENTEI(NEWTON)
16
f(x)=0,f ( z-r,z+r)R,exista a>0,b>0 si |f’(x)|>=a, |f’(x)|>=a,x
apartine de I ,f de doua ori derivabila
Tangenta in (xn ,f(xn ) ) este xn+1 = xn + f(xn )/f’(xn )
Pentru ca:
y-f( xn ) =f’( () عx- xn )
cum y=0 xn -x= f(xn )/f’(xn ) x = xn+1 + f(xn )/f’(xn )
{Folosind parametrii de tip functie si procedura sa se rezolve o ecuatie
prin metoda injumatatirii,tangentei si coardei pe un interval dat}
{$f+}
type functie=function(x:real):real;
procedura=procedure(var a,b,x,y:real;f:functie);
var car:char; a,b:real;
function f(x:real):real;
begin
f:=sin(x)-x;end;
procedure injumat(var a,b,x,y:real;f:functie);
begin
x:=(a+b)/2;y:=f(x);end;
procedure coarda(var a,b,x,y:real;f:functie);
begin
x:=a-(b-a)/(f(b)-f(a))*f(a);y:=f(x);end;
procedure tangenta(var a,b,x,y:real;f:functie);
function derivata(f:functie;x0:real):real;
const h=1.e-6;
begin
derivata:=(f(x0+h)-f(x0))/h;end;
begin
x:=x-f(x)/derivata(f,x);y:=f(x);
end;
procedure radacina(f:functie;p:procedura);
const eps=1.e-10;
var epsa,b,x,y:real;i:integer;
begin
write('inceputul intervalui a=');readln(a);
write('sfirsitul intervalui b=');readln(b);
i:=0;
repeat
p(a,b,x,y,f);i:=i+1;
if (f(a)<0)=(y<0) then a:=x else b:=x;
until (abs(a-b)<eps) or (y=0) or (i>200);
if i>200 then write('solutia nu afost gasita in 200 de pasi')
else
writeln('solutia ',x:12:7);
end;
17
begin
writeln('alegeti metoda de rezolvare a ecuatiei ');
write('a=metoda injumatairii intervalului ');
write('b=metoda coardei ');
write('c=metoda tangentei ');
writeln;
write('optiunea');readln(car);
case car of
'a':radacina(f,injumat);
'b':radacina(f,coarda);
'c':radacina(f,tangenta);
else
writeln('varianta eronata ');
end;
readln;
end.
18
semn:=-semn;
integr:=semn+k*integr;
end;
writeln('recurent integrala este ',integr:20:11);
readln;
end.
{Sa se calculeze prin formula trapezelor o integrala dintr-o functie}
{$f+}
type ff=function(x:real):real;
var a,b,int:real;n:integer;
function f1(x:real):real;
begin
f1:=sin(ln(x))/x;
end;
procedure tr(a,b:real;f:ff;n:integer;var s:real);
var h:real;i:integer;
begin
h:=(b-a)/n;
s:=(f(a)+f(b))/2;
for i:=1 to n-1 do
s:=s+f(a+i*h);
s:=s*h;
end;
begin
write('a=');readln(a); write('b=');readln(b);write('n=');readln(n);
tr(a,b,f1,n,int);
writeln('integrala este ',int:8:2);
readln;
end.
19
s1,s2:real;
begin
s1:=0;
s2:=0;
for i:=1 to n div 2 do
begin
s1:=s1+ss(m,(2*i-1)*h);
s2:=s2+ss(m ,2*i*h);end;
sim:=h/3*(ss(m,0)-ss(m,pi/2)+4*s1+2*s2);
end;
var m:integer;
begin
write(' m=');
readln(m);
writeln(' integrala este ',sim(m):20:11);
readln;
end.
7.Alocare dinamica
7.1 Tipuri specifice alocării dinamice a memoriei
Memoria interna poate fi privita ca o succesiune de octeti.Numarul de ordine al unui octet se
numeşte adresa lui. Adresa unei variabile nu trebuie confundata cu valoarea pe care aceasta o
memorează.
Definiţie: Adresa primului octet al variabilei se numeşte adresa variabilei.
Adresele variabilelor se memorează cu ajutorul variabilelor de tip pointer.
Noţiunea de variabila dinamica
Am invatat inca din clasa a IX-a ca o variabila este o entitate caracterizata prin trei
atribute:tip, valoare si adresa .Primele doua
atribute au fost foarte des întâlnite pana acum. Atributul adresa va face obiectul noţiunilor in acest
capitol.
Pentru început ,consideram un exemplu foarte simplu , o variabila x de tipul integer.Declaratia ei
va este cunoscuta:
var x: integer;
Variabila x de mai sus se numeşte variabila statica. O variabila statica se caracterizează prin
faptul ca in momentul declarări ,
compilatorul ii un anumit spaţiu de memorie. Mărimea spaţiului rezervat unei variabile depinde de tipul
acesteia . De exemplu ,pentru
o variabila de tipul integer se aloca 2 octeţi, pentru una de tipul real 6 octeţi .
Variabila x se numeşte “pointer către un întreg” sau”referinţa către un întreg”.Fireşte ca tipul de
date al variabilei x nu va mai
fi integer ci ,un tip de date nou , numit “tipul pointer către un întreg” sau “tipul referinţa către un
întreg “, notat integer .
Declaraţia necesara este: var x:^integer:Pe scurt vom spune ca x este un pointer către un
intreg.Caracterul “ ^ ” se numeşte operatorul
De adresare “săgeata”.
Tipurile de date “pointer către ….” sunt anonime .Un tip pointer poate fi insa denumit ,ca
orice tip anonim, cu cuvântul cheie type.
Exemplu :
Pentru a declare trei pointeri către numere reale ,putem scrie: var x,y,z:^real;
20
momentul utilizării variabilei .Pentru aceasta folosim procedura new, care are doua forme:
new (<pointer>)
<pointer>:=new(<tip>);
unde: - <pointer>→numele (identificatorului) pointerului ;
- <tip>→ tipul pointerului;
Pentru eliberarea memoriei alocate unei variabile dinamice ,apelam procedura dispose , cu
sintaxa:
dispose(<pointer>);
Exemplu:
Memoria alocata anterior pentru variabila dinamica x^ alocata anterior, poate fi eliberata cu
dispose(x);
Pointerul NIL
In general ,un pointer conţine adresa unei variabile dinamice ,mai exact adresa zonei de
memorie unde este depozitata valoarea
variabilei dinamice. Este insa posibil ca in timpul execuţiei unui program ,un pointer sa primească
drept valoare adresa unei locaţii
de memorie “goala” ,in care nu se găseşte nici o valoare. In acest caz vom spune ca poianterul este “in
vânt” si ca valoarea sa este NIL.
Acest NIL reprezintă de fapt o constanta redefinita a limbajului cu sens de “nimic” (nul) ,si
poate fi atribuit numai variabilelor
de un tip pointer.
Atribuiri de pointeri
Un pointer poate fi transmis ca parametru unei proceduri sau funcţii, dar pentru aceasta este
obligatoriu sa denumim tipul anonim al
pointerului respectiv (ştim ca in antetul unui subprogram nu putem folosi tipuri anonime).
Exemplu :
Ne propunem sa declaram o procedura P care sa primească drept parametri doi pointeri x si y
către întreg. Aşadar x si y vor fi de
tipul ^ integer.
Este incorect sa scriem antetul procedurii astfel :
procedure P(x,y:^ integer);
Trebuie sa denumim tipul ^integer dandu-I de exemplu numele pint ;
type pint =^integer;
Acum putem scrie antetul procedurii in felul următor :
procedure P(x,y :pint);
21
Begin
a1:=a2;
End.
Adresa pentru tipul pointer
Var x:integer;
A:^integer;
Begin
X:=10;
A=@x;
Write(a^);
End.
Alocarea spatiului pentru variabila poiter p si elberarea lui
Procedure new(var p:pointer);
Procedure dispose (var p :pointer);
Ex:
Var adr1:^integer;
New(adr1);adr^:=7;
Writeln(adr1);dispose(adr1);
End;
7.2 Structuri de date implementate dinamic
Stiva funcţionează pe principiul LIFO (Last In First Out) – “ultimul intrat, primul ieşit”.
Pentru a înţelege modul de lucru cu stiva, ne imaginăm un număr n de farfurii identice, aşezate una peste
alta (o “stivă” de farfurii). Adăugarea sau scoaterea unei farfurii se face, cu uşurinţă, numai în vârful stivei. Oricât
ar părea de simplu principiul stivei, el are consecinţe uriaşe în programare.
Stivele se pot aloca secvenţial (ca vectori). Fie ST[i] un vector. ST[1], ST[2], … , ST[n] pot reţine numai litere sau
numai cifre. O variabilă k indică în permanenţă vârful stivei, adică ultimul element introdus.
22
Observaţii:
În mod practic, la scoaterea unei variabile din stivă, valoarea variabilei ce indică vârful stivei scade cu 1, iar atunci
când scriem ceva în stivă, o eventuală valoare reziduală se pierde.
Pe un anumit nivel se reţine, de regulă, o singură informaţie (literă sau cifră), însă este posibil, aşa cum va rezulta
din exemplele prezentate în lucrare, să avem mai multe informaţii, caz în care avem stive duble, triple, etc.
În cazul stivei, alocarea secvenţială nu prezintă mari dezavantaje, ca în cazul mai general, al listelor, pentru că nu
se fac operaţii de inserare sau ştergere în interiorul stivei. Singurul dezavantaj, în comparaţie cu alocarea dinamică
înlănţuită este dat de faptul că numărul de noduri care pot fi memorate la un moment dat este mai mic – depinde de
gradul de ocupare al segmentului de date.
În literatura de specialitate veţi întâlni termenul PUSH pentru operaţia de adăugare în stivă a unei înregistrări şi
POP, pentru extragere.
Exemple:
Vom începe prin a studia modul de calcul al funcţiei pentru x=15 şi x=8.
f(15)=14;
f(8)=f(f(10))=f(f(f(12)))=f(f(11))=f(f(f(13)))=f(f(12))=f(11)=f(f(13))= f(12)=11.
Algoritmul va folosi o stivă ST şi o variabilă k, ce indică în permanenţă vârful stivei. Algoritmul se
bazează pe următoarele considerente:
■ la o nouă autoapelare a funcţiei f, se urcă în stivă (k se incrementează cu 1) şi se pune noua valoare.
■ în situaţia în care pentru valoarea aflată pe nivelul k se poate calcula funcţia, se coboară în stivă, punându-se pe
acest nivel noua valoare.
12 13
10 10 11 11
8 8
8 8 8
12 13
11 12
8 11
f=11
23
□ Programul următor calculează funcţia Manna-Pnueli, utilizând stiva alocată dinamic. Lucrul
cu stiva se face prin utilizarea funcţiilor PUSH (PUNE) şi POP (SCOATE).
24
const nmax=5; DINAMIC
type stiva=array[1..nmax] of {Sa se simuleze formula lui manna pnueli cu
byte; stive pentru a se pune
var a: stiva; in evidenta operatiile in stiva f(x)=x-1
dim,n,i:byte; dacax>=12 alfel f(x)=f(f(x+2))
x,y:byte; ex:n=8}
function program stiva;
vida(x:stiva;dim:byte):boolean; type adresa=^nod;
begin nod=record
if dim >0 then vida:=false else info:integer;
vida:=true; adr_inap:adresa;
end; end;
var v:adresa;
function n,man:integer;
plina(x:stiva;dim:byte):boolean procedure push(var v:adresa;n:integer);
; var c:adresa;
begin begin
if dim <nmax then plina:=false if v=nil then
else plina:=true; begin
end; new(v);
procedure adaug(var x:stiva;var v^.info:=n;
dim:byte;y:byte);
v^.adr_inap:=nil;
begin
end
inc(dim);
else
x[dim]:=y;
begin
end;
new(c);
c^.info:=n;
function elimin(var x:stiva;var
c^.adr_inap:=v;
dim:byte):byte;
begin v:=c;
elimin:=x[dim] ; end;
dec(dim); end;
end; procedure pop(var v:adresa);
var c:adresa;
begin begin
write('x=');readln(x); if v=nil then writeln('stiva este vida')
adaug(a,dim,x); else
while not vida(a,dim) do begin
begin c:=v;
y:=elimin(a,dim); v:=v^.adr_inap;
for i:=1 to dim do dispose(c)
writeln(a[i]);writeln; end;
if y>=12 then end;
{writeln('valoarea functiei se procedure tipar(v:adresa);
poate calcula direct') } var c:adresa;
if not vida(a,dim) then begin
a[dim]:=y-1 c:=v;
else while c<> nil do
else begin
begin writeln(c^.info);c:=c^.adr_inap;
adaug(a,dim,y); end;
for i:=1 to dim do end;
writeln(a[i]); writeln; begin
adaug(a,dim,y+2); write('n=');
for i:=1 to dim do readln(n);
writeln(a[i]); push(v,n);
end; while v<>nil do
end; if v^.info <12 then
write('manna pnueli(',x,')=',y- begin
1); push(v,v^.info+2);
end. tipar(v); readln;
25
end procedure s(var p:ref);
else var c:ref;
begin begin
man:=v^.info; if p=nil then
pop(v); writeln(' goala ')
tipar(v); else
readln; begin
writeln(' scot din stiva pe');
if v<>nil then writeln(p^.nr);
v^.info:=man-1; c:=p;
end; p:=p^.urm;
writeln('f=',man-1) ; dispose(c);
readln; end;
end. end;
DINAMIC IN GENERAL procedure s1(var p:ref);
{Sa se creeze o stiva. var q:ref;
Scrieti doua proceduri diferite begin
care elimina elemente in stiva} q:=p;
type ref=^inr; p:=q^.urm;
inr=record dispose(q);
nr:integer; end;
urm:ref;
end; begin
var p:ref; write('dati un numar n>=3 ');
i,n:integer; readln(n);
procedure b(var p:ref); for i:=1 to n do
var c:ref; b(p);
begin writeln('-----------elimin
new(c); elementul din virful stivei');
writeln(' pe cine pui in stiva s1(p);
');readln(c^.nr); for i:=1 to n do
c^.urm:=p; s(p);
p:=c;
end; readln;
end.
□ Funcţia lui Ackermann. Se dă funcţia următoare, definită pe produsul cartezian N x N.. Se citesc m
şi n. Să se calculeze Ack(m, n).
n+1, m=0
Ack(m,n)= Ack(m-1, 1), n=0
Ack(m-1, Ack(m, n-1)), altfel
Pentru calculul acestei funcţii, folosim o stivă dublă, ST. Iniţial, valorile m şi n se reţin la nivelul 1. Pe
nivelul k al stivei se reţin valorile curente m şi n. În funcţie de valorile acestora se procedează astfel:
■ pentru m şi n diferite de 0, este necesar un nou calcul de funcţie, caz în care se urcă în stivă şi pe noul
nivel se pun argumente m şi n-1.
■ pentru cazul n=0, se rămâne pe acelaşi nivel în stivă, punând în locul lui m valoarea m-1, iar în locul
lui n valoarea 1.
26
■ în situaţia în care m=0, funcţia se poate calcula; se coboară în stivă şi se înlocuieşte valoarea lui m cu
m-1, valoarea lui n cu valoarea calculată anterior.
10 01
20 11 11 11
21 21 21 21 21
10
01 11 11
11
02 02 13 12 12
12
21 12 03
12 13 13
13 13 13 04
ack(2,1)=5.
Coada funcţionează pe principiul FIFO (First In First Out) – “primul intrat, primul ieşit”.
Este cu totul nerecomandabilă alocarea secvenţială a cozii, deoarece în această situaţie, are loc
un fenomen de migraţie a datelor către ultimele componente ale vectorului (cele de indice mare).
27
Să presupunem că simulăm o coadă cu ajutorul unui vector cu zece componente, care reţin
numere întregi. Introducem în coadă, pe rând, numerele 1, 2, 3, 4.
1 2 3 4
2 3 4 5
3 4 5 6
Alocarea dinamică înlănţuită a cozii. O variabilă v va reţine adresa elementului care urmează a
fi scos (servit). O alta, numită sf, va reţine adresa elementului introdus în coadă. Figura următoare
prezintă o coadă în care primul element care urmează a fi scos are adresa în v, iar ultimul introdus are
adresa sf.
v sf
7 3 5 2
Etapa 1)
28
stergerea unui element
29
IF (P=NIL) THEN BEGIN end;
begin
q^.leg:=p; o; {L;
p:=q; writeln;}
u:=p; Li;
end readln;
else end.
begin CU LISTE DUBLU INLANTUITE
q^.leg:=nil;u^.leg:=q;u:=q; { Sa se creeze o structura de coada}
end; type ref=^inr;
end; inr=record
while (not eof(f)) do begin nr:integer;
new(q);q^.info:=a;q^.leg:=nil; as,ad:ref;
u^.leg:=q;u:=q; end;
read(f,a); var p,u:ref;i,n:integer;
end; procedure b(var u:ref);
var c:ref;
while (not eof(g)) do begin
begin new(c);
new(q);q^.info:=b;q^.leg:=nil;u^.leg:=q; writeln(' pe cine pui in coada ');readln(c^.nr);
u:=q; c^.ad:=nil;
read(g,b); c^.as:=nil;
end; if u<>nil then u^.ad:=c else
close(f);close(g); p:=c;
end; u:=c;
procedure L; end;
var c:po; procedure s(var p:ref);
begin var c:ref;
c:=p; begin
while(c<>nil) do if p=nil then writeln(' e goala ') else
begin begin
write(c^.info, ' '); writeln(' pe cine scot ');
c:=c^.leg; writeln(p^.nr);
end; c:=p;p:=p^.ad;
end; p^.as:=nil;
procedure li; dispose(c);
var H:text; end;
var c:integer; end;
begin
assign(h,'ff.pas');rewrite(h); begin
d:=p;c:=0; writeln(' cite elemente dai n>=3');readln(n);
while d<>nil do for i:=1 to n do
begin b(u);
writeln(d^.info);writeln(h,d^.info); for i:=1 to n do
inc(c);d:=d^.leg; s(p);
end;
writeln(' am atitea inregistrari',c); readln;
end.
close(h);
O listă liniară este o colecţie de n≥0 noduri, X₁, X₂, … , Xn aflate într-o relaţie de ordine. Astfel,
X₁ este primul nod al listei, X₂ este al doilea nod al listei … Xn este ultimul nod. Operaţiile
permise sunt:
□ Accesul la oricare nod al listei în scopul citirii sau modificării informaţiei conţinute de acesta.
30
□ Adăugarea unui nod, indiferent de poziţia pe care o ocupă în listă.
Există două metode de alocare a unei liste liniare: alocarea secvenţială şi alocarea înlănţuită.
Nodurile listei ocupă poziţii succesive în memorie. Acest tip de alocare l-am întâlnit des, de
câte ori am utilizat vectori.
Exemplu: un vector are n componente de tip real. Se cere să se sorteze vectorul crescător. Algoritmul
are ca dată de intrare o listă liniară, cu n noduri de tip real. Ieşirea este tot o listă liniară, cu aceleaşi
noduri, dar în altă ordine. Să presupunem că utilizăm sortarea prin interschimbare. O interschimbare a
nodurilor i şi j se reduce la următoarele operaţii, premise în listă:
■ v[i] v[i+1]; - accesez nodul i+1 în vederea citirii (operaţie permisă) şi accesez nodul i în vederea
modificării informaţiei reţinute (operaţie permisă).
■ v[i+1] = man; - accesez nodul i+1 în vederea modificării informaţiei reţinute de el.
În concluzie, sortarea se realizează prin utilizarea operaţiilor permise asupra unei liste liniare.
Avantajul alocării secvenţiale este dat de faptul că programatorul are acces direct la oricare din
nodurile listei, la fel ca la componentele unui vector.
Dezavantajul alocării secvenţiale este dat de faptul că operaţiile de adăugare, eliminare sau schimbare
de poziţie a unui nod necesită un efort mare de calcul, ca în exemplul următor, în care se elimină un
nod:
31
in₁ adr₂
adr₁ adr₂ adrn
■ in₁, in₂, in₃, … , inn reprezintă informaţiile conţinute de noduri, de altă natură decât cele de adresă;
După cum observăm, fiecare nod, cu excepţia ultimului, reţine adresa nodului următor.
2. Alocarea dublu înlănţuită. Alocarea simplu înlănţuită permite parcurgerea listei într-un singur sens
(de la stânga la dreapta). În cazul în care se doreşte ca lista să poată fi parcursă în ambele sensuri
se utilizează alocarea dublu înlănţuită. Aici fiecare nod reţine adresele predecesorului şi
succesorului său, aşa cum se vede în figura următoare:
1. Accesul la un nod al listei se face prin parcurgerea nodurilor care în preced. Aceasta necesită un
efort de calcul.
2. Informaţiile de adresă, prezente în cadrul fiecărui nod, ocupă memorie.
Avantajele alocării înlănţuite sunt date de faptul că operaţiile de adăugare sau eliminare a unui nod se
fac rapid. Exemplele sunt date pentru lista liniară simplu înlănţuită, dar bine înţelese, ne permit să
deducem singuri modul de efectuare a operaţiilor respective pentru liste dublu înlănţuite.
Fie lista:
3 adr₂
7 adr₃ 9 nil
7 adr₃ 32
9 nil
3 adr₂
adr₁ adr₂ adrn
adrt
□ Se completează informaţiile pentru nodul creat – câmpul de adresă trebuie să conţină adresa nodului
care trebuie să-i urmeze în listă:
3 adr₂
7 adr₃
9 nil
5 adr₂
adrt
□ Se modifică adresa nodului care precede nodul nou creat. Adresa trebuie să fie a nodului nou creat:
adrt
5 adr₂
33
3 adrt
adr₁ adrt adr₂ adrn
b) Ştergerea unui nod. Pentru a exemplifica operaţiile efectuate în acest caz vom folosi a de mai sus,
la care ştergem al doilea nod (cel cu informaţia 5). Iată etapele:
□ Informaţia de adresă a nodului care îl precede trebuie să reţină adresa nodului următor:
Observaţii:
În cazul alocării înlănţuite, adresele de memorare ale nodurilor consecutive nu sunt neapărat
consecutive. Pentru a realiza acest lucru este suficient să analizaţi cazul ştergerii unui nod (sau acela al
adăugării unui nod).
Prin alocarea memoriei pentru un nod înţelegem rezervarea spaţiului necesar memorării informaţiilor
conţinute de acesta. Evident, se poate aloca memorie doar dacă există memorie disponibilă, adică nu
este ocupată de alte variabile.
Pentru eliberarea memoriei ocupate de un nod înţelegem că spaţiul ocupat de acesta devine disponibil
– este pus la dispoziţia programatorului, pentru ca, eventual, acesta să fie din nou alocat.
Este important să folosim termenii corect. De exemplu, nu putem folosi în loc de “alocarea
memoriei” termenul “crearea memoriei”, tot aşa cum nu este corect să folosim în loc de “eliberarea
memoriei” termenul “ştergere a memoriei”.
Noţiunile care privesc alocarea şi eliberarea memoriei sunt prezentate în paragraful următor.
34
Liste liniare alocate simplu inlantuit
Definitia listelor
Def.:O lista liniara este o colectie de n>=0 noduri, X1,X2,…,Xn, aflate intr-o relatie de
ordine.Astfel, X1 este primul nod al listei, X2 este al doilea nod al listei,…, Xn este ultimul
nod.Operatiile permise sunt:
Accesul la oricare nod al listei in scopul citirii sau modificarii informatiei continute de acesta.
Adaugarea unui nod, indiferent de pozitia pe care o ocupa in lista.
Stergerea unui nod,indiferent de pozitia pe care o ocupa in lista.
Schimbarea pozitiei unui nod in cadrul listei.
35
stergerea unui element
36
CREAREA SI AFISAREA LISTELOR SIMPLU INLANTUITE
type ref=^inr; u:=c;
inr=record end;
nr:integer;
urm:ref; end;
end;
var qq,p,c,u:ref; a:array[1..15] of ref; procedure afisare(p:ref);
nn,n,i:integer; var c:ref;
procedure init(var p:ref); begin
begin c:=p;
writeln(' cite inregistrari vreti sa introduceti while (c <>nil) do
');readln(n); begin
new(c); writeln('introduceti inregistrarea prima writeln(c^.nr:6);
'); c:=c^.urm;
readln(c^.nr); end;
c^.urm:=nil; end;
p:=c;u:=c; begin
for i:=2 to n do init(p);
begin afisare(p);
writeln('introduceti inregistrarea ',i); readln;
new(c);readln(c^.nr);c^.urm:=nil;u^.urm:=c; end.
37
begin while potadauga do
new(c); begin
writeln('pe cine inserati inaite de pa i(dati un while (c<>nil) and(c^.nr<>cecaut) do
numar ',i);readln(c^.nr); c:=c^.urm;
c^.urm:=p;
p:=c; end; if (c=nil) then potadauga:=false
end; else
procedure adaugunlasfirsit; begin
begin new(pecinepun);
new(c); writeln(' pe cine vrei sa pui ');
writeln('dati numarul care-l puneti dupa ua readln(pecinepun^.nr);
inregistrare '); pecinepun^.urm:=c^.urm;
readln(c^.nr); c^.urm:=pecinepun ;
c^.urm:=nil; c:=c^.urm;
u^.urm:=c; end;
u:=c; end;end;
end; procedure pununadupamaimulte;
procedure adaugunlasfirsitmaimulte; var cecaut:integer; pecinepun :ref;
var multe:integer; begin
begin
writeln('cite inregistrari vreti sa mai puneti dupa writeln('introduceti dupa a cit -a inregistrare
ua ');readln(multe); vreti sa faceti adaugarea ');readln(cecaut);
for i:=1 to multe do c:=p;
begin for i:=1 to cecaut-1 do
new(c); c:=c^.urm;
writeln('dati numarul care-l puneti dupa ua begin
inregistrare ',i); new(pecinepun);
readln(c^.nr); writeln(' pe cine vrei sa pui ');
c^.urm:=nil; readln(pecinepun^.nr);
u^.urm:=c; pecinepun^.urm:=c^.urm;
u:=c; c^.urm:=pecinepun ;
end;end; c:=c^.urm;
end;
procedure pununadupacecaut; end;
var cecaut:integer; pecinepun :ref; procedure pununainaintedemaimulte;
begin var cecaut:integer; pecinepun :ref;
writeln('introduceti valoarea inainte de care begin
vreti sa faceti adaugarea ');readln(cecaut);
c:=p; writeln('introduceti inainte de a cit -a
while(c<>nil) and (c^.nr<>cecaut) do inregistrare vreti sa faceti inseararea
c:=c^.urm; ');readln(cecaut);
if (c=nil) then writeln(' nu este ce cauti in lista ') c:=p;
else for i:=1 to cecaut-2 do
begin c:=c^.urm;
new(pecinepun); begin
writeln(' pe cine vrei sa pui '); new(pecinepun);
readln(pecinepun^.nr); writeln(' pe cine vrei sa pui ');
pecinepun^.urm:=c^.urm; readln(pecinepun^.nr);
c^.urm:=pecinepun ; pecinepun^.urm:=c^.urm;
end; c^.urm:=pecinepun ;
end; c:=c^.urm;
end;
procedure punmaimulteinaintedececaut; end;
var cecaut:integer; pecinepun :ref; procedure stergpa;
potadauga:boolean; var desters:ref;
begin begin
potadauga :=true; desters :=p;
writeln('introduceti valoarea inainte de care p:=p^.urm;
vreti sa faceti adaugarea ');readln(cecaut); dispose( desters);
c:=p; end;
38
procedure stergua; begin
var oretinpepenua,desters:ref; writeln('cite vreti sa stergeti incepind de la pa
begin ');readln(multe);
c:=p; for i:=1 to multe do
while (c<>u) do begin
desters :=p;
begin p:=p^.urm;
oretinpepenua :=c; dispose( desters);
c:=c^.urm; end;
end; end;
desters :=c;
oretinpepenua^.urm :=nil; procedure stergdupacecaut;
u:=oretinpepenua ; var osterg:ref;cecaut:integer;
dispose( desters); begin
end;
c:=p;
procedure stergdupaunacareocaut; writeln(' dupa ce valoare vrei sa stergi');
var oretinpepenua,desters:ref;cecaut:integer; readln(cecaut);
begin while (c<>nil) and (c^.nr<>cecaut) do
writeln('dupa a cit-a intergistrare vreti sa c:=c^.urm;
stergeti ');readln(cecaut); if c=nil then writeln(' nu este in lista ')
c:=p; else
for i:=1 to cecaut do begin
osterg:=c^.urm;
begin c^.urm:=c^.urm^.urm;
oretinpepenua :=c; {dispose(osterg); }
c:=c^.urm; end;
end; end;
desters :=c;
oretinpepenua^.urm :=c^.urm; procedure stergcecaut;
var oretin,osterg:ref;cecaut:integer;
dispose( desters); begin
end;
c:=p;
writeln(' ce valoare vrei sa stergi');
readln(cecaut);
procedure sterguele; while (c<>nil) and (c^.nr<>cecaut) do
var oretinpepenua,desters:ref;multe:integer; begin
begin oretin:=c;
writeln('cite vreti sa stergeti incepind de la c:=c^.urm;end;
sfirsit spre inceput ');readln(multe); if c=nil then writeln(' nu este in lista ')
for i:=1 to multe do else
begin begin
c:=p; osterg:=c;
while (c<>u) do oretin^.urm:=c^.urm;
dispose(osterg);
begin end;
oretinpepenua :=c; end;
c:=c^.urm;
end; procedure stergcecautdeciteoriapare;
desters :=c; var
oretinpepenua^.urm :=nil; oretin,osterg:ref;cecaut:integer;potsterge:boole
u:=oretinpepenua ; an;
dispose( desters); begin
end; writeln(' ce valoare vrei sa stergi');
end; readln(cecaut);
potsterge:=true;
39
c:=c^.urm;
c:=p; writeln(' cu cine o modifici');
readln(c^.nr);
while (c<>nil) and (c^.nr<>cecaut) do end;
begin
oretin:=c;
c:=c^.urm;end; begin
if c=nil then potsterge :=false init;
else afisare;
begin inserareinaintedepa;
osterg:=c; afisare;
oretin^.urm:=c^.urm; inserareinaintedepamaimulte;
dispose(osterg); afisare;
end; adaugunlasfirsit;
end;end; afisare;
procedure afisare; adaugunlasfirsitmaimulte;
begin afisare;
c:=p;
while (c <>nil) do pununadupamaimulte;
begin afisare;
writeln(c^.nr:6); pununainaintedemaimulte;
c:=c^.urm; afisare; writeln('o sterg pe pa ');
end; stergpa ;afisare;
end; stergdelapamaimulte; afisare;
procedure modificpa; stergua;
begin writeln('o sterg pe ua ');
c:=p; afisare;
writeln('cu cine modifici pe pa');readln(c^.nr); sterguele;afisare;
stergdupaunacareocaut;
end; afisare;
procedure modificua; pununadupacecaut;afisare;
begin stergdupacecaut;
c:=u; afisare;
writeln('cu cine modifici pe ua');readln(c^.nr); stergcecaut;
afisare;
end; stergcecautdeciteoriapare; afisare;
procedure modificcepozitiecaut; modificpa;
var cecaut:integer; afisare;
begin modificua; afisare;
c:=p; modificcepozitiecaut; afisare;
writeln(' a cit-a inregistrare vrei sa o modifici'); readln;
readln(cecaut); end.
for i:=1 to cecaut-1 do
40
1) creare;
2) adaugare la dreapta;
3) adaugare la stanga;
4) adaugare in interiorul listei;
5) stergere din interiorul listei;
6) stergere la stanga listei;
7) stergere la dreapta listei;
8) listare de la stanga la dreapta;
9) listare de la dreapta la stanga.
1) Creare
2) Adaugare la dreapta
Functia add citeste informatia numerica, aloca spatiu pentru inregistrare, completeaza adresele,
modifica adresa la dreapta a inregistrarii din s cu adresa noii inregistrari si ii atribuie
lui s valoarea noii inregistrari.
3) Adaugare la stanga
Functia includ parcurge lista pentru a gasi inregistrarea cu informatia m, in dreapta careia urmeaza sa
introducem noua inregistrare, citeste informatia, aloca spatiu, completeaza informatia, completeaza
adresa stanga a noii inregistrari cu valoarea adresei inregistrarii de informatie m, si completeaza adresa
dreapta a noii inregistrari cu valoarea adresei dreapta a inregistrarii cu informatia utila m.
Functia Sterg parcurge lista pentru a gasi informatia care va fi stearsa, atribuie inregistrarii precedente
campul de adresa dreapta al inregistrarii care va fi stearsa, iar inregistrarii care urmeaza celei care va fi
stearsa i se atribuie campul de adresa stanga al inregistrarii pe care o stergem, dupa care se elibereaza
spatiul de memorie rezervat inregistrarii care se sterge.
Functia listare porneste din stanga listei si tipareste informatia numerica a fiecarei inregistrari, atata
timp cat nu s-a ajuns la capatul listei.
OPERATII CU LISTE DUBLU INLANTUITE
{Cu liste dublu inlantuite sa se simuleze procedure creare;
crearea ,listarea in ambele sensuri si stergerea begin
ultimului,primului element ,inserarea dupa un writeln('n=');readln(n);
anumit numar de inregistrari new(c);
sau stergerea elementui care are un anumit writeln(' primul element ');readln(c^.nr);
numar de inregistrare} c^.ad:=nil;
type ref=^inr; c^.as:=nil;
inr=record p:=c;
as:ref; u:=c;
nr:integer; for i:=2 to n do
ad:ref; begin
end; new(c);
var p,c,u:ref; writeln(' dati integistrarea ',i);
n,i:integer; readln(c^.nr);
41
c^.ad:=nil; procedure stergA_p1_componenta;
c^.as:=u; var p1:integer;q:ref;
u^.ad:=c; begin
u:=c; c:=p;
end; writeln(' dati componenta care o stergeti din
end; lista ');readln(p1);
procedure adauginaintedeprima; writeln('------------------');
begin for i:=1 to p1-1 do
new(c); c:=c^.ad;
writeln('pe cine adaug inainte de prima '); q:=c;
readln(c^.nr); c^.as^.ad:=c^.ad;
c^.ad:=p; c^.ad^.as:=c^.as;
p^.as:=c; dispose(q)
c^.as:=nil; end;
p:=c; procedure ins1;
end; var i:integer;d,q:ref;
procedure adugadupaultima; begin
begin writeln(' in fata cui inserati ');readln(i);
new(c); writeln('------------------');
writeln(' pe cine adugi dupa ultima '); d:=p;
readln(c^.nr); writeln('------------------'); while(i<>d^.nr) and (d<>nil) do
c^.ad:=nil; d:=d^.ad;
c^.as:=u; if d= nil then writeln(' nu ')
u^.ad:=c; else
u:=c; begin
end; new(q);
procedure adaugadupaa_p1_acomponenta; writeln('informatia care o inserati ');
var p1:integer;q:ref; readln(q^.nr);
begin q^.ad:=d;
c:=p; q^.as:=d^.as;
writeln(' dupa a cita componenta d^.as^.ad:=q;
adaugi(inserezi '); d^.as:=q;
readln(p1); writeln('------------------'); end;
for i:=1 to p1-1 do end;
c:=c^.ad;
new(q); procedure listare;
writeln(' dati componenta care o inserati '); var c:ref;
readln(q^.nr); writeln('------------------'); begin
q^.ad:=c^.ad; c:=p;
c^.ad^.as:=q; while(c<>nil) do
q^.as:=c; begin
c^.ad:=q; writeln(c^.nr,' ');
end; c:=c^.ad;
procedure stegultima; end;
var q:ref; end;
begin
q:=u; procedure listare1;
u:=u^.as; var c:ref;
u^.ad:=nil; begin
dispose(q); c:=u;
end; while(c<>nil) do
begin
procedure stegprima; writeln(c^.nr,' ');
var q:ref; c:=c^.as;
begin end;
q:=p; end;
p:=p^.ad;
p^.as:=nil; begin
dispose(q); creare;
end; writeln('------------------');
42
listare; writeln('sterg pe ultima adugadupaultima; listare;
------------------'); writeln('------------------');
stegultima; adaugadupaa_p1_acomponenta; listare;
writeln('o listez de la sfirsit spre writeln(' sterg prima ------------------');
inceput------------------'); stegprima;listare; writeln('------------------');
listare1; stergA_p1_componenta; listare;
adauginaintedeprima; writeln('------------------');
writeln('------------------'); ins1; listare;
listare; writeln('------------------'); readln;
end.
Arbori binari
Definitie
Un arbore cu propietatea ca fiecare nod cu exceptia frunzelor , are cel mult doi descendenti
(succesori ) se numeste arbore binar.
Intr-un arbore binar ,cei doi succesori ai unui nod (daca exista), se numeste succesor stang
respectiv arbore drept.
Definitie
Un arbore cu proprietatea ca fiecare nod ,cu exceptia frunzelor , are exact doi descendenti
(succesori) se numeste arbore binar complet .
Etapa 1)
43
nod radacina e 58,nod terminal(frunza) e 7
44
etepa 2)parcurgerea in inordine
45
46
{ Creati un arbore cu chei var x:integer;nou:arbore;
intregi.Parcurgeti in begin
write('Info:');read(x);
postordine,inordine,preordine if x<>0 then
arborele creat.} begin
new(nou);
{ Rezolvare : 1 nou^.info:=x;
2 write('Stanga lui ',x,':');
0 nou^.st:=radacina;
0 write('Dreapta lui ',x,':');
3 nou^.dr:=radacina;
0 radacina:=nou
0 end
} else radacina:=nil;
end;
program ParcurgereArb; procedure preordine(p:arbore);
type arbore=^nod; begin
nod=record if p<>nil then
info:integer; begin
st,dr:arbore write(p^.info:4);
end; preordine(p^.st);
var rad:arbore; preordine(p^.dr);
function radacina:arbore; end
47
end; postordine(p^.st);
procedure inordine(p:arbore); postordine(p^.dr);
begin write(p^.info:4);
if p<>nil then end
begin end;
inordine(p^.st); begin
write(p^.info:4); rad:=radacina;
inordine(p^.dr); preordine(rad);
end writeln;
end; inordine(rad);
procedure postordine(p:arbore); writeln;
begin postordine(rad);
if p<>nil then end.
begin
7.2.5 Arbore binar de cautare
Definitie. Se numeste arbore de cautare un arbore binar ale carui noduri au o cheie de
identificare,iar pentru fiecare nod avem proprietatiile urmatoare:
orice cheie asociata unui nod al subbarborelui stang este mai mica decat cheia asociata
nodului;
orice cheie asociata unui nod al subarborelui drept este mai mare decat cheia asociata
nodului.
1. INSERAREA
Crearea arborilor de cautare se face aplicand de un nr de ori operatia de inserare. Regula de inserare
este urmatoarea:
Se compara cheia asociata unui nod cu cheia inregistrarii care se insereaza. Avem trei posibilitati:
2. CAUTAREA
3. LISTAREA
48
Informatia se poate lista utilizand oricare din metodele cunoscute pentru parcurgerea arborilor. Daca
dorim listarea informatiilor in ordinea strict crescatoare a cheilor,se utilizeaza metoda stang-varf-dreapta
(inordine), intrucat pentru orice nod avem urmatoarele:
cheile nodurilor din subarborele stang sunt mai mici decat cheia asociata
nodului;
cheile nodurilor din subarborele drept sunt mai mari decat cheia asociata
nodului.
4. STERGEREA
Dupa stergerea unui nod care are o anumita cheie, arborele ramas trebuie sa fie de cautare.
a) nodul care urmeaza sa fie sters este nod terminal – in acest caz se face stergerea
avand grija ca la parintele lui sa inlocuim adresa catre el cu nil;
b) nodul care urmeaza a fi sters subordoneaza un singur subarbor – cel drept – caz in
care parintelui se va inlocui adresa catre el cu adresa subarborelui drept,iar nodul
respectiv se sterge;
c) nodul care urmeaza a fi sters subordoneaza un singur subarbore – cel stang – caz in
care parintelui i se va inlocui adresa catre el cu adresa subarborelui stang, iar nodul
respectiv se sterge;
d) nodul care urmeaza a fi sters( dupa cum vom vedea, acesta se va sterge numai logic)
subordoneaza doi subarbori, caz in care se fac operatiile:
se indentifica cel mai din dreapta nod al subarborelui stang coorespunzator nodului care
urmeaza a fi sters (acesta va fi sters in mod efectiv, nu inainte de a muta informatiile sale la
nodul care se sterge logic);
cheia acestuia si alte informatii utile continute de el se muta la nodul care urmeaza a fi sters
subarborele stang al nodului care se va sterge fizic se leaga:
in stanga nodului care se sterge logic (daca nodul indentificat ca cel mai din dreapta din
subarborele stang este descendent direct al nodului care se sterge logic)
in dreapta tatalui nodului care se sterge fizic( in caz contrar);
Exemple de stergere:
1. Arborelui din stanga i se sterge nodul 8. acesta nu subordoneaza nici un alt arbore.
2. Arborelui din stanga i se sterge nodul 9. acesta subordoneaza un singur subarbore, cel
drept.
49
3. Arborelui din stanga i se sterge nodul 3. Cel mai din dreapta nod al subarborelui stang este 1.
se obtine:
4. Arborelui din stanga i se sterge nodul 7. cel mai din dreapta nod al subarborelui stang este 6.
tatal nodului care se sterge fizic este 3. in dreapta sa se leaga subarborele 5 4 . se obtine:
Vezi procedura STERG. In situatia in care nodul care urmeaza a fi sters subordoneaza doi arbori,se
apeleaza procedura CMMD.
50
prelucrarii primele tri cazuri nu necesita comentarii. In cazul 4 se indentifica nodul cel
mai din dreaptadin arborele stang. Cheia acestuia trece in locul cheii nodului care se
sterge. Aceasta este mai mica decat cheia initiala,este in acelasi timp cea mai mare
din subarborele stang,deci este cea mai mare cheie mai mica decat cheia care se
sterge. Iata motivul pentru care aceasta trece in locul cheii sterse logic.
Transmiterea parametrului c se face prin referinta. Adresa de alocare va fi trimisa
automat parintelui,caadresa de subarbore stang sau drept (duopa caz).
Altgoritmul are complexitatea in cazul cel mai defavorabil 0(n 2). In cazul in care, de
exemplu cheile inserate sunt in ordine crescatoare, arborele va degenera intr-o lista
liniara –orice nod are numai un descendent drept,iar
inserarea unui nod inseamna parcurgerea tuturor nodurilor deja inserate in pasul
anterior.
Teoria regasirii informatiei este deosebit de importanta pentru viata practica. Aceasta conduce la o
cautare rapida (putine comparatii).
Etapa 1)
inserez noduri
51
stergerea unui nod care nu are fii de exemplu nodul cu cheia 90
52
stergerea unui nod care are un fiu stang
stergerea unui nod care are mai multe niveluri sub el de exemplu o sa stergem de mai jos elemental cu cheia 27
53
stergerea unui nod cu 2 descendenti de exemplu de mai jos pe valoarea cheii 43
54
cautarea unui element de exemplu caut pe valoarea cheii 29
55
inord(r^.dr);
end;
end;
begin
write('n='); readln(n);
new(rad);
write('dati sirul:');
writeln(' primul nod ');
read(rad^.v);
rad^.st:=nil; rad^.dr:=nil;
for i:=2 to n do
begin
writeln(' nodul al ',i,'lea');
read(x);
adauga(rad,x);
end;
writeln('inord:');
inord(rad);
readln;
end.
56
else inserare(v,k)
if c^.nr<k then end;
sterg(c^.ad,k) 'l':parcurg(v);
else 'c':begin
sterg(c^.as,k) write ('k=');readln(k);
else caut(v,man,k);
writeln('numar absent -tentativa if (man<>nil) then writeln(k)
esuata') else writeln('nu exista acest nod');
end; end;
begin 's':begin
v:=nil; write('se sterge numarul');readln(k);
repeat sterg(v,k);
write('optiunea'); end;
readln(opt); end;
case opt of until opt='t'
'i':begin end.
write('k=');readln(k);
Forma poloneza –aplicatii-la coada
Se da o expresie aritmetica ce foloseste operatorii `=`,`-`,`*`,`/` precum si `(`, `)`. Fiecare operand
este o litera. Se cere sa se converteasca aceasta expresie intr-o expresie in forma
poloneza(postfixata).
Exemple:
EXPRESIE ARITMETICA EXPREIE IN FORMA POLONEZA
A+b Ab+
A*(b+c) Abc+*
A*(b+c)-e/(a+d)+h Abc+*ead+/-h+
Forma poloneza este o forma de scriere a expresiilor aritmetice in care parantezele
nu mai sunt puse (din acest motiv o expresie scrisa in forma poloneza se mai
numeste expresie scrisa fara paranteze), dar aceasta nu duce la calculul eronat al
exp.
Exemplu: expresiei (a+b)*c-d/e i se asociaza arborele binar din figura de mai jos. Parcurgerea acestui
arbore in postordine va da chiar forma poloneza:ab+c*de/-. Utilizand cele spise pentru rezolvarea
problemei, vom proceda in felul urmator:
57
construim arborele binar asociat expresiei
aritmetice;
il parcurgem in postrdine pentru a obtine forma
poloneza.
Pentru constructia arborelui vom acorda prioriati operatorilor si operanzilor(mai putin parantezelor),dupa
cum urmeaza:
Utilizand efp si pfp cu ajutorul functieiarb se construieste arborele atasat expresiei aritmetice. Un nod al
acestui arbore are ca informatie utila un operator sau un operand.
58
A:char Parc(c^.as);
Function arb (li,ls:integer;var efp:sir:var Parc(c^.ad);
pfp:vector);ref; Write(c^.op)
Var c:ref End
I,j,min:integer; End;
Begin
Min:=pfp[ls]; Begin
I:=ls; J:=0;read( a); n:=1;
For j:=ls downto li do Whilea<>`.` do
If pfp[j]<min Begin
Then E[n]:=a;n:=n+1;read( a);
Begin End;
min:=pfp[j]; N:=n-1;
I:=j; For i:=1 to n do
End; Case e[i] of
New( c);arb:=c; arb^.op:=efp[i]; `)`:j:=j-10;
If li=ls `(`:j:=j+10;
Then `+`,`-`:p[i]:=j+1;
Begin `*`,`/`:p[i]:j+10
Arb^.as:=nil;arb^.ad:=nil; else p[i]:=1000
End end;
Else j:=1;
Begin for i:=1 to n do
Arb^.as:=arb(li,i-1,efp,pfp); if(e[i]<>`)`) and(e[i]<>`(`)
Arb^.ad:=arb(i+1,ls,efp,pfp) then begin
End efp[j]:=e[i];
End; pfp[j]:=p[i];
j:=j+1
Procedure parc (c:ref); end;
Begin c:=arb(1,j-1,efp,pfp);
Ifc<>nil parc( c );
Then writeln;
Begin end.
Aplicatie. Dandu-se o expresie in forma poloneza postfixata,sa se scrie un program care sa genereze
programul de calcul al expresiei utilizand numai instructiuni de atribuire cu un singur operator. Se vor
introduce variabelele auxiliare x0,x1,…,xn.
X0=b+c
X1=a*x0
X2=a+d
X3=e/x2
X4=x1-x3
X5=x4+h.
59
- in cazul in care caracterul citit este operator,se scot din stiva
continuturile ultimelor doua niveluri si se face tiparirea sub forma:-
xj=variabila penultima in stiva,operator,variabila ultima in stiva, iar
variabila tiparita se retine i stiva.
Procedeul se repeta ata timp cat nu au fost citite toate caracterele. Pe exemplul considerat, rularea
decurge astfel:
D
A
E E,a,d se incarca in stiva;
X1
X2
E Se tipareste x2=a+d;
X1
Program fp_pc;
Type stiva=array[1..100,1..2] of char;
Var st:stiva;
Fp:string[100];
I,j,k:integer;
60
C:string[1];
Begin
Write( ` forma poloneza este=`);
Readln( fp);
K:=0;j:=0;
For i:=1 to lenght(fp) do
Case fp[i] of
`a`..`z`:begin
k:=k+1;
st[k,2]:=fp[i];
st[k,1]:=` `
end;
`+`,`-`,`*`,`/`,:
begin
writeln(`x`,j,`=`,st[k-1,1],st[k-1,2],fp[i],st[k,1],st[k,2]);
k:=k+1;
st[k,1]:=`x`;str(j:1,c);st[k,2]:=c[1];
j:=j+1
end
end{case}
end.
procedeul indicat este utilizt pentru compilarea expresiilor. Se cunoaste faptul ca procesorul are
instructiuni care permit o singura operatie si doi operanzi. O expresie trbuie adusa sub forma
prezenta,pentru obtinerea codului masina. Altgoritmii utilizati sunt de acest tip (evident,acestia sunt si
optimizanti).
8.Teoria grafurilor
8.1 Definitie.Metode de reprezentare
Notiunea de graf neorientat , adiacente , incidenta, grad
Se numeste graf neorientat , o pereghe ordonata de multimi (X,U)unde:
-X este multimea finita si nevida de elemente numite varfuri sau noduri;
-U este o multime de perechi neordonate de cate doua elemete din X, numite muchii sau arce .
Pentru o muchie uk=(a,b), vom spune ca :
-varfurile a si b sunt adiacente si se numesc extremitatile muchiei u k;
-muchia uk si varfurile a sunt incidente in graf .La fel , muchia u k si varful b ;
-muchia (a,b) este totuna cu (b,a)
Gradul unui varf x , notat d(x) , reprezinta numarul muchiilor care trec prin nodul x
Un varf care are gradul 0 , se numeste varf izolat
Un varf care are gradul 1 , se numeste varf terminal .
Aplicatie
Construirea matricei de adiacenta prin “citirea muchiilor “de la tastatura :
Procedure citire_graf;
Var I,j,k,x,y:integer;
Begin
Readln(n);
Readln(M);
For I:=1 to n do
For j:=1 to n do
A[I,j]:=0;
For k:=1 to m do
Begin
Write(‘dati muchia”);
Repeat
Readln(x,y);
Until (x>=1)and (x<=n)and(y>=1) and (y<=n) ;
A[x,y]:=1;
A[y,x]:=1;
End;
Listele vecinilor
61
Pt fiecare nod I formam lista vecinilor lui I .Asta cuprinde toate nodurile care sunt extremitati ale
muchiilor care trec prin nodul I .
Fiecare muchie a grafului poate fi privita ca o inregistrare cu doua componente :cele doua varfuri care
constituie extremitatile muchiei .Notam aceste extremitati cu nod 1 si nod 2 , putem defini tipul de date
TMUCHIE, astfel :
Type tmuchie =record
Nod1 ,nod2:integer;
End;
Reprezentarea grafurilor neorientate
Consideram un graf neorientat g=(X,U) cu m muchii si n varfuri numerotate 1,2,3,4,….,n.
Matricea de adiacenta
Este o matrice a cu n linii si n coloane , in care elementele a[I,j]se definesc astfel :
a[i,j]= 1 , daca exista muchia iI,j] cu i<>j
0 in caz contrar
62
Se numeşte p-graf, un graf orientat în care numărul arcelor identice este mai mic sau egal cu o valoare
dată p.
În cele ce urmează vom analiza numai 1-grafuri fără bucle.
Graful unui vârf. Mulţimile Γ şi ω
Gradul exterior al unui vârf x, notat d*(x), reprezintă numărul arcelor care ies din nodul x, adică numărul
arcelor de forma (x,z) ε U.
Analog, se defineşte gradul interior al unui vârf x, notat d-(x), ca fiind numărul arcelor care intră în nodul
x (de forma (y,x) ε U).
Exemplu:
În graful reprezentat în figura 1, pentru nodul x=2, avem:
d*(2) =3 → există trei arce care ies din nodul 2, şi anume : u2=(2,1), u4=(2,3) şi u5 = (2,4).
d-(2) =1 → în nodul 2 intră un singur arc, în speţă arcul u3=(3,2).
Se mai definesc următoarele mulţimi:
x y X x, y U
→ mulţimea nodurilor ce constituie extremităţi finale ale arcelor care
pleacă din nodul x. Pe scurt, mulţimea succesorilor lui x;
x y X y, x U
→ mulţimea nodurilor ce constituie extremităţi iniţiale ale arcelor care
pleacă din nodul x. Pe scurt, mulţimea predecesorilor lui x;
Exemplu:
În graful din figura 1, pentru nodul x=2, avem:
- Γ+(2) = {1,3,4} → urmare a faptului că muchiile care pleacă din nodul 2 sunt (2,1), (2,3) şi (2,4), putem
spune că mulţimea succesorilor nodului 2 este {1,3,4}.
- Γ-(2) = {3} → în nodul 2 intră doar muchia (3,2), deci mulţimea predecesorilor lui 2 conţine doar nodul
3. ω+(x) = {u = (x,y)| u ε U} → mulţimea arcelor care ies din nodul x;
ω-(x) = {u = (y,x)| u ε U} → mulţimea arcelor care intră în nodul x;
Exemplu:
În graful din figura 1, pentru nodul 2, avem:
ω+(x) = {(2,1), (2,3), (2,4)}, ω-(x) = {(3,2)}
Graf parţial şi subgraf
Fie graful G = (X,U). Un graf parţial al lui G, este un graf G 1= (X,V), cu V U . Altfel spus, un graf
parţial G1 al lui G, este chiar G, sau se obţine din G păstrând toate vârfurile şi suprimând nişte muchii.
Fie graful G = (X,U). Un graf parţial al lui G, este un graf G 1= (Y,T), unde V X şi T U , iar T va
conţine numai muchiile care au ambele extremităţi în Y. Altfel spus, un graf parţial G 1 al lui G, se obţine
din G eliminând nişte vârfuri şi păstrând doar acele muchii care au ambele extremităţi în mulţimea
vârfurilor rămase.
Exemplu:
Se consideră graful G = (X,U) din figura 2, în care X = {1,2,3,4,5,6} şi U={u1, u2, u3, u4, u5, u6, u7}.
- Construim graful parţial G1 = (X,V), unde X = {1,2,3,4,5,6} şi V = { u2, u3, u4, u6, u7} (figura 3)
din graful G au fost eliminate arcele u1 şi u5.
- Construim subgraful G2 = (Y,T), unde Y = {3,4,5,6} şi T = {u4, u5, u6, u7} (figura 4) din graful G
au fost eliminate nodurile 1 şi 2 precum şi arcele u1, u2 şi u3 care au o extremitate în afara
mulţimii nodurilor rămase.
Reprezentarea grafurilor orientate
Considerăm un graf orientat G= (X,U) cu m arce şi n noduri.
Cele mai cunoscute forme de reprezentare sunt: matricea de adiacenţă, matricea vârfuri – arce,
matricea drumurilor şi listele vecinilor.
Matricea de adiacenţă
u2 u2
1 2 1 2
u1
u3 u3
u4 u5 u4 u4
3 3 3 u5
4 4 4
5 5 5
u7 u6 u7 u7
u6 u6
6 6 6
Figura 2 Figura
63 3 Figura 4
Are aceeaşi semnificaţie ca în cazul grafurilor neorientate: fiecare element a[i,j], cu i,j ε {1,2,...,n}, este: 1
dacă există arcul (i,j), respectiv 0 în caz contrar.
Datorită orientării, aşa cum am mai spus, arcul (i,j) nu este totuna cu arcul (j,i). Prin urmare, a[i,j] ≠ a[j,i].
Aşadar matricea de adiacenţă nu mai este simetrică faţă de diagonala principală, aşa cum se întâmpla
în cazul grafurilor neorientate.
Exemplu:
Pentru graful G=(X,U) din figura 5, matricea de adiacenţă este:
coloana 1 2 3 4
0 0 0 0 1
1 0 1 1 2
A=
0 0 0 1 3
0 1 0 0 4
2
3
1
4
Figura 5
Procedure afişare_matrice;
{afişează matricea de adiacenţă a}
var i,j: integer;
begin
for i:=1 to n do
begin
for j:=1 to n do
64
write(a[i,j],' ');
writeln();
end;
end;
Aplicaţie:
Citirea matricei de adiacenţă dintr-un fişier text
Aceasta este absolut similară cu cea prezentată la grafuri neorientate, unde a fost explicată pe larg. De
fapt, este vorba despre algoritmul de citire a unei matrice oarecare dintr-un fişier text. Plecăm de la
presupunerea că fişierul conţine pe primul rând valoarea lui n, apoi pe fiecare din următoarele n rânduri
elementele unei linii a matricei separate de spaţii.
Procedure cit_matr_fis;
{citeşte numărul de noduri si matricea de adiacenta a din fişierul text cu descriptorul f}
var i,j: integer; nume_fis: string;
begin
write('Daţi numele fişierului '); readln(nume_fis);
assign(f,nume_fis); reset(f);
readln(f,n);
for i:=1 to n do
begin
for j:=1 to n do read(f,a[i,j]);
readln(f);
end;
close(f);
end;
Aplicaţie:
Construirea matricei de adiacenţă prin citirea “arcelor” de la tastatură
Se citesc de la tastatură m perechi de numere întregi de forma (x,y) reprezentând extremităţile celor m
arce ale grafului, şi se construieşte matricea de adiacenţă a, cu n linii şi n coloane.
Mai întâi citim m şi n (numărul de arce respectiv numărul de noduri), şi iniţializăm toată matricea de
adiacenţă cu 0, în două cicluri for. Apoi, într-un alt ciclu for, cu k de la i la m, citim cele m perechi de
întregi (x,y).
- Citirea fiecărei perechi (x,z) se face cu validare: repetă citirea lui x şi y până când ambele
valori sunt în intervalul [1,n].
repeat
readln(x,y);
until (x>=1) and x(<=n) and (y>=1) and (y<=n) and (x<>y);
- Pentru fiecare (x,y), marcăm în matricea de adiacenţă existenţa arcului (x,y), prin atribuirea
a[x,y]:=1. Spre deosebire de grafurile neorientate, nu se mai face şi atribuirea a[y,x]:=1,
deoarece arcul (x,y) nu e identic cu arcul (y,x).
Algoritmul prezentat a fost inclus în procedura citire_graf.
Procedure citire_graf;
var i, j, k, x, y: integer;
begin
write('Nr. Arce:'); readln(m);
write('Nr. Vârfuri'); readln(n);
{iniţializează cu 0 toata matricea de adiacenta}
for i:=1 to n do
for j:=1 to n do
a[i,j]:=0;
{citeşte m perechi (x,y) reprezentând arcele grafului}
for k:=1 to m do
begin
write('Muchia ',k,': ');
repeat
readln(x,y);
until (x>=1) and x(<=n) and (y>=1) and (y<=n) and (x<>y);
{pentru fiecare pereche, marchează arcul in matricea de adiacenta}
a[x,y]:=1;
65
end;
end;
Aplicaţie:
Determinarea gradului exterior şi a gradului interior ale unui nod oarecare x
Scriem o funcţie {d_plus(x:integer):integer;} care returnează, gradul exterior al nodului x (notat d*(x)).
Gradul exterior al unui nod x este numărul arcelor care ies din nodul x, adică numărul arcelor de forma
(x,j), cu j ε {1, 2, ... , n}. Luăm ca exemplu graful cu n=4 noduri de mai jos, împreună cu matricea sa de
adiacenţă:
1 2 3 4
0 0 0 0 1
A= 1 0 1 1 2
0 0 0 1 3
0 1 0 0 4
2
3
1
4
Analizăm gradul exterior al nodului 2. Arcele care ies din nodul 2 sunt: (2,1), (2,3), (2,4) (nu şi (4,2)).
Urmare a existenţei acestor arce, în matricea de adiacenţă vom avea a[2,1] = a[2,3] = a[2,4] = 1. Unde
se găsesc în matricea de adiacenţă toate valorile de 1 corespunzătoare arcelor ce ies din nodul 2? Pe
linia 2! Pe caz general, valorile de 1 de pe linia x în matricea de adiacenţă, reprezintă arcele care ies din
nodul x. Deci gradul exterior al nodului x, adică numărul arcelor care ies din nodul x este egal cu
numărul valorilor de 1 de pe linia x a matricei.
Aşadar algoritmul implementat în funcţia d_plus este foarte simplu:
Iniţializăm cu 0 o variabilă nr. în care numărăm valorile de 1 de pe linia x a matricei. Într-un ciclu,
parcurgem coloanele j=1, 2, ..., n ale liniei x. Pentru fiecare valoare a lui j, testăm elementul a[x,j] de pe
linia x şi coloana j. Dacă aceasta are valoarea 1, atunci incrementăm nr. În final funcţia va returna ultima
valoare a variabilei nr.
Function d_plus(x:integer):integer;
{returnează gradul exterior d* pentru un nod x; acesta este numărul valorilor de 1 de pe linia x a matricei
de adiacenta}
var nr.,j: integer;
begin
nr.:=0;
for j:=1 to n do
if a[x,j] = 1 then nr:=nr + 1;
d_plus:=nr;
end;
Observaţie:
Destul de asemănător este şi algoritmul pentru determinarea gradului interior al nodului x (d- (x) ).
Acesta reprezintă numărul arcelor care intră în nodul x, adică numărul arcelor de forma (i,x), cu i ε {1,
2, ..., n}. Să vedem unde se regăsesc în matricea de adiacenţă arcele care intră în nodul x, luând ca
exemplu x=4 pentru graful anterior. Arcele care intră în nodul 4 sunt (3,4) şi (2,4). Rezultă că în matrice
avem a[3,4] = a[2,4] = 1. Am “reperat” astfel valorile de 1 de pe coloana 4 a matricei de adiacenţă. În
66
acest moment putem concluziona că gradul interior al unui nod oarecare x reprezintă numărul valorilor
de 1 de pe coloana x a matricei. Se poate scrie o funcţie asemănătoare cu cea de mai sus, care să
returneze câte valori de 1 se găsesc pe coloana x.
function d_minus(x: integer): integer;
{returnează gradul interior d- pentru un nod x; acesta este numărul valorilor de 1 de pe coloana x a
matricei de adiacenta}
var nr, i: integer;
begin
nr:=0;
for i:=1 to n do
if a[i,x]=1 then nr:=nr+1;
d_minus:=nr;
end;
-1 -1 -1 0 0
0 1 0 1 -1
0 0 1 -1 1
u1 u3
u2
1
u4
3 4
u5
Figura 6
67
- L-(x) → lista vecinilor predecesori; conţine nodurile ce sunt extremităţi iniţiale ale arcelor care
intră în nodul x.
Exemplu:
În graful din figura 6 de mai sus, pentru nodul x=4 avem:
- arcele care ies din nodul 4 sunt (4,2) şi (4,3). În consecinţă, lista vecinilor succesori L*(4)
conţine nodurile 2 şi 3;
- în nodul 4 intră un singur arc, şi anume (3,4), motiv pentru care lista vecinilor predecesori L-(4)
conţine doar nodul 3.
Prezentăm în continuare aceste liste ale vecinilor pentru graful din figura 6.
Matricea drumurilor
Această matrice va fi reprezentată în cadrul capitolului “Drumuri şi circuite în grafuri orientate”.
Reprezentarea grafului ca un vector de muchii
Fiecare arc al grafului poate fi privit ca o înregistrare cu două componente, în speţă cele două noduri
care constituie extremităţile arcului:
- nod_in -> nodul din care iese arcul (“nodul de început” al arcului);
- nod_sf -> nodul în care intră arcul (“nodul de sfârşit” al arcului);
Putem defini tipul de date ARC, astfel:
type ARC=record
nod_in, nod_sf: integer;
end;
Graful în ansamblul său, este o mulţime de arce, adică o mulţime de elemente de tipul ARC. În
consecinţă, definim graful ca un “vector de arce”, adică un vector de elemente de tipul ARC:
var v: array [1..25] of ARC;
Numărul real de elemente este numărul de arce m. Astfel, elementele efectiv folosite ale vectorului vor fi
v[1], v[2],..., v[m]. Fiecare element {1, 2, ..., m}) este de tipul ARC şi reprezintă unv[i] (cu i arc al
grafului, având două componente:
v[i].nod_in şi v[i].nod_sf -> nodurile extremităţi ale arcului.
68
Un nod x se numeşte izolat dacă prin el nu trece nici un arc. Altfel spus, nu iese nici un arc din el şi nu
intră nici un arc în el, adică dp[x]=dm[x]=0. În continuare, vom număra nodurile izolate în variabila nr, pe
care o iniţializăm cu 0. Parcurgem “în paralel” cei doi vectori ai gradelor dp şi dm, într-un ciclu cu i=1, 2,
3, ..., n. La fiecare pas, testăm dacă nodul i este izolat, adică dacă dp[i]=0 şi dm[i]=0; în caz afirmativ
afişăm respectivul nod i şi incrementăm numărul nr al nodurilor izolate.
nr:=0;
for i:=1 to n do
if(dp[i]=0) and (dp[i]=0) then
begin
write(i,' ');
nr:=nr+1;
end;
După încheierea acestei parcurgeri, dacă numărul vârfurilor izolate este diferit de 0 atunci îl afişăm, iar
în caz contrar tipărim un mesaj din care să rezulte că graful nu are noduri izolate.
Program XI_7;
type vect =array[1..20] of integer;
var n,m:integer;
a:array[1..20,1..20] of integer;
dp,dm:vect;
procedure noduri_izolate;
var i,j,k,x,y,nr:integer;
begin
write('Nr.arce : '); readln(m);
write('Nr.noduri: '); readln(n);
{iniţializează cu 0 vectorii gradelor dp şi dm}
for i:=1 to n do
begin
dp[i]:=0; dm[i]:=0;
end;
{citeşte m perechi (x,y) reprezentând arcele grafului}
for k:=1 to m do
begin
write('Arcul ',k,': ');
repeat
readln(x,y);
until (x>=1) and (x<=n) and (y>=1) and (y<=n) and (x<>y);
{pentru fiecare arc (x,y), incrementează gradul exterior al lui x şi gradul interior al lui y}
dp[x]:=dp[x]+1; dm[y]:=dm[y]+1;
end;
writeln; nr:=0; {nr=numărul nodurilor izolate}
for i:=1 to n do
{dacă ambele grade ale lui i sunt 0,am găsit un vârf izolat, pe care-l afişăm şi incrementăm nr}
if (dp[i]=0) and (dm[i]=0) then
begin
write(i,' '); nr:=nr+1;
end;
writeln;
if nr<>0 then writeln('Graful are ',nr, ' noduri izolate')
else writeln ('Graful nu are noduri izolate');
end;
begin
noduri_izolate;
end.
Celebritate.
Se dă un grup format din n persoane, care se cunosc sau nu între ele. De la tastatură se introduc m
perechi de numere întregi (x,y) cu semnificaţia ”persoana x cunoaşte pe persoana y”. relaţia de
cunoştinţă nu este neapărat reciprocă. Numim celebritate, o persoană care este cunoscută de către
69
toate celelalte persoane din grup, dar ea nu cunoaşte pe nici un alt membru al grupului. Să se
determine dacă din grup există o astfel de celebritate.
Interpretarea datelor.
Problema poate fi modelată într-un graf orientat, în care nodurile sunt persoanele 1,2,3...n, iar arcele
sunt relaţiile de cunoştinţă între aceste persoane. O relaţie de cunoştinţă este de forma (x,y) cu
semnificaţia “persoana x o cunoaşte pe persoana y”. De exemplu, dacă grupul are n=4 persoane, iar
cele m=5 “relaţii de cunoştinţă” sunt (1,3), (2,3), (4,3), (1,2), (1,4), atunci graful şi matricea sa de
adiacenţă arată astfel:
3
0 1 1 1
0 0 1 0
A
0 0 0 0
0 0 1 0 4
1
Să analizăm persoana reprezentată prin nodul 3:
- există relaţiile de cunoştinţă (1,3), (2,3) şi
(4,3), adică persoana 3 este cunoscută de
către 1,2 şi 4. Mai exact, persoana 3 2 este
cunoscută de către toate celelalte
persoane din grup;
- nu există nici o relaţie de cunoştinţă de forma (3,p). Cu alte cuvinte, persoana 3 nu cunoaşte
pe nimeni.
În concluzie, persoana 3 este ceea ce numim celebritate. În graf, existenţa celebrităţii se interpretează
astfel:
- în nodul 3 intră arce “ieşite” din toate celelalte noduri;
- din nodul 3 nu iese nici un arc.
Rezolvare
În procedura citire_graf se citesc de la tastatură m perechi de numere întregi de forma (x,y)
reprezentând extremităţile celor m arce ale grafului, şi se constituie matricea de adiacenţă a, cu n linii *
n coloane.
Algoritmul de căutare a celebrităţii cuprins în procedura celebritate.
Pentru început, vom căuta o persoană pe care o vom numi în continuare candidat la celebritate.
Memorăm acest candidat în variabila candid. Presupunem că iniţial candidatul este persoana 1
(candid:=1). “Cercetăm” celelalte persoane, într-un ciclu cu i de la 2 la n. Pentru fiecare persoană i,
trebuie să facem o testare. În cazul în care candidatul “actual” candid o cunoaşte i (a[candid,i] este 1)
candid nu mai poate fi celebritate (celebritate nu trebuie să cunoască nici o altă persoană din grup !). În
această situaţie, noul candidat la celebritate devine i (candid:=1).
La finele parcurgerii de mai sus, în variabila candid vom avea aşadar un candidat la celebritate. Mai
rămâne să vedem dacă acest candidat este cunoscut de către celelalte persoane. În exemplul de mai
sus, urmare a faptului că persoana 3 este celebritate, avem relaţiile (1,3), (2,3) şi (4,3), adică
a[1,3]=a[2,3]=a[4,3]=0. În consecinţă, pe coloana 3 avem n-1 valori de 1. Pe caz general, trebuie să
numărăm valorile de 1 de pe coloana candid în matricea de adiacenţă, în adiacenţă, iar dacă găsim n-1
valori, atunci persoana candid este într-adevăr celebritate.
Program XI_8;
var n, m: integer; a: array[1..20, 1..20] of integer;
procedure citire_graf;
var i, j, k, x, y: integer;
begin
write('Nr. arce: '); readln(m);
write('Nr. noduri: '); readln(n);
{iniţializează cu 0 toata matricea de adiacenta}
for i:=1 to n do
for j:=1 to m do
a[i,j]:=0;
{citeşte m perechi (x,y) reprezentând arcele grafului}
for k:=1 to m do
begin
70
write('Arcul ',k,': ');
repeat
readln(x,y);
until (x>=1) and (x<=n) and (y>=1) and (y<=n) and (x<>y);
{pentru fiecare pereche marchează arcul in matricea de adiacenta}
a[x,y]:=1;
end;
end;
procedure celebritate;
var i, j, candid, nr : integer;
begin
candid:=1; {candid va reprezenta candidatul la celebritate, care iniţial este persoana 1}
for i:=2 to n do
{daca candidatul îl cunoaşte pe i, el nu mai poate fi celebritate noul candidat devine i}
if a[candid, i]=1 then candid:=i;
nr:=0; {numaram in nr cate persoane îl cunosc pe candidatul candid}
for i:=1 to n do
if a[i, candid]=1 then nr:=nr+1;
{verificam daca intr-adevăr candid este celebritate}
if nr=n-1 then writeln('Persoana ', candid,' este celebritate')
else writeln('Nu exista celebritate in grup');
end;
begin
citire_graf; celebritate;
end.
Drumuri si circuite in grafuri orientate
Se numeşte lanţ intr-un graf orientat, o mulţime de arce L={u 1,u2,...,uk}, cu proprietatea ca oricare doua
arce vecine in mulţime au o extremitate comuna.
Un lanţ este de fapt un traseu care uneşte prin arce doua noduri numite extremităţile lanţului, fără a tine
cont de orientarea arcelor componente.
Se numeşte drum în graful G, un şir de noduri D={z 1, z2, z3, …, zk}, unde z1, z2, z3, …, zk aparţin lui x, cu
proprietatea că oricare două noduri consecutive sunt adiacente, adică există arcele [z 1, z2], [z2, z3], …,
[zk-1,zk] aparţin lui U.
Practic, un drum poate fi privit ca un traseu în care toate arcele au aceeaşi orientare, dată de sensul de
deplasare de la z1 la zk.
Dacă nodurile z1, z2, z3, …, zk sunt distincte două câte două, drumul se numeşte elementar. În caz
contrar, drumul este ne-elementar.
Asemenea uni lanţ într-un graf neorientat, un drum într-un graf orientat este de fapt un traseu pe care l-
am parcurge între două noduri deplasându-ne de-a lungul unor arce şi trecând prin nişte noduri
intermediare. Deosebirea unui drum faţă de un lanţ constă în faptul că de-a lungul unui arc ne putem
deplasa numai în sensul dat de orientarea arcului.
Se numeşte circuit într-un graf, un lanţ L={z 1, z2, z3, …, zk} cu proprietatea că z1=zk şi arcele [z1, z2], [z2,
z3], …, [zk-1,zk] sunt distincte două câte două.
Dacă într-un circuit, toate nodurile cu excepţia primului şi ultimului sunt distincte două câte două, atunci
circuitul se numeşte elementar. În caz contrar, el este ne-elementar.
71
u2
1 2
u1
u3
u4 u5
3
4
5
u7 u6
6
Figura 8
Matricea drumurilor.
Este o matrice d cu n linii şi n coloane, în care fiecare element d[i,j] este :
- 1, dacă există drum de la nodul i la nodul j în graf;
- 0, în caz contrar.
Algoritmul Roy-Warshall de determinare a matricei drumurilor
Matricea drumurilor se obţine aplicând matricei de adiacenţă transformări succesive. Vom spune că
există drum de la nodul i la nodul j, dacă găsim un nod k (diferit de i, j) cu proprietatea că există drum de
la i la k şi drum de la j la k. Astfel:
un element a[i, j] care este 0, devine 1, dacă există un nod k astfel încât a[i, k]=1 şi a[k, j]=1.
Pentru a găsi arcele nodului k, trebuie parcurse pe rând în varianta k toate nodurile 1, 2, …, n.
for k:=1 to n do
for i:=to n do {i≠k}
for j:=1 to n do {j≠k}
if (a[i, j]=0) and (i<>k) and (j<>k) then
a[i, j]:=a[i,k]*a[k, j];
Atribuirea a[i, j]:=a[i,k]*a[k, j] este o scriere elegantă a regulii de mai sus:
în cazul în care unul din elementele a[i,k], a[k, j] este 0, a[i, j] va rămâne 0;
dacă a[i, k]=1 şi a [k, j]=1, atunci a[i, j] devine 1.
Un CD valoros
Într-un grup sunt n elevi, băieţi şi fete, pe care-i numerotăm 1, 2, … , n. Fiecare elev cunoaşte o parte
dintre ceilalţi elevi. Relaţia de cunoştinţă nu este neapărat reciprocă (dacă x îl cunoaşte pe y, asta nu
înseamnă că şi y trebuie să îl cunoască pe x). Unul dintre elevi are un CD foarte valoros, cu multe
jocuri demonstrative, pe care toţi membri grupului vor să-l aibă fie şi pentru scurt timp, pentru a şi-l
copia pe calculatorul propriu. CD—ul circulă printre membrii grupului în felul următor: fiecare elev după
ce l-a primit de la altcineva îl dă mai departe, dar numai unui elev pe care îl cunoaşte, pentru că nu
doreşte să ajungă în mâna unor persoane în care nu poate avea încredere. Determinaţi o modalitate
(dacă există) prin care CD-ul să circule exact o singură dată pe la fiecare elev, transmiterea lui făcându-
se numai către o cunoştinţă, iar în final CD-ul să ajungă din nou la proprietarul său.
Interpretarea datelor
Relaţiile de cunoştinţă din cadrul grupului pot fi reţinute într-o matrice a cu n linii şi n coloane, în fiecare
element a[i, j] este: 1 dacă elevul i îl cunoaşte pe elevul j, respectiv 0 în caz contrar. Cu datele
problemei putem construi un graf în care nodurile sunt elevii 1, 2, 3,…, n, iar arcele sunt relaţiile de
cunoştinţă din grup. Astfel, va exista arc de la nodul x la nodul y dacă elevul x în cunoaşte pe elevul y.
Întrucât în enunţ se precizează că relaţiile de cunoştinţă nu sunt neapărat reciproce („x cunoaşte pe y”
nu implică „y cunoaşte pe x”), rezultă că avem de-a face cu un graf orientat. Matricea a definită mai
înainte este tocmai matricea de adiacenţă a grafului.
„Traseul” pe care îl parcurge CD-ul pleacă dintr-un nod (proprietarul său), trecând prin fiecare nod (pe la
fiecare elev) o singură dată. Transmiterea se face numai către o cunoştinţă. Astfel, de la elevul x va
ajunge la elevul y numai dacă există arc (cunoştinţă) de la x la y. În final, traseul se încheie în nodul de
unde a plecat (CD-ul se întoarce la proprietarul iniţial). Un traseu care respectă condiţiile de mai sus nu
este altceva decât un circuit elementar care trece prin toate nodurile grafului: drum deoarece poate
72
trece de la un nod la altul numai printr-un arc, elementar deoarece nu trece de două ori prin acelaşi nod,
şi în sfârşit circuit pentru că revine în nodul de plecare.
Rezolvare
Folosim metoda backtracking. Fiecare astfel de circuit elementar care trece prin toate nodurile grafului,
va fi o soluţie memorată în vectorul stivă st. Aşadar elementele vectorului st sunt noduri ale grafului.
O soluţie (st[1], st[2], …, st[p] ) este finală dacă
- conţine n nivele, adică p=n (au fost „puşi pe stivă” toţi cei n elevi, adică toate cele n noduri)
- st[n]=x (pentru a fi ciclu trebui să revină în nodul de plecare, adică „elevul de pe ultimul nivel”, st[n],
trebuie să fie proprietarul memorat iniţial în x).
Procedura {citire_matrice;} citeşte matricea de adiacenţă (relaţiile de cunoştinţă). În două cicluri for,
cu i, j=1, 2, …, n, se citesc toate elementele a[i, j]. Această procedură a fost prezentată ca aplicaţie în
lecţia „Reprezentarea grafurilor orientate”
Procedura {iniţializări;} realizează iniţializarea stivei şi a proprietarului CD-ului.
- într-un ciclu for, se iniţializează cu 0 întreg vectorul-stivă;
- se citeşte numărul de ordine al proprietarului CD-ului în variabila x (nodul de plecare).
Procedura {tipar(p:integer):} afişează o configuraţie (st[1], st[2], …, st[p]) a vectorului-stivă.
Funcţia {valid(p:integer):boolean;} verifică pentru fiecare nivel p dacă st[p]I a generat o soluţie
(st[1], st[2], …, st[p]) validă.
Testarea se face prin intermediul unei variabile booleene ok, iniţializează cu TRUE. În primul rând, din
nodul st[p-1] se poate ajunge în
nodul st[p] numai printr-un arc (orice drum/circuit trece prin arce). Aşadar nodul st[p] este valid numai
dacă există arc de la st[p-1] la st[p], adică a[st[p-1], st[p]]=1 (această condiţie provine din faptul că
fiecare elev va transmite CD-ul numai prin cunoştinţă, ia relaţia de cunoştinţă este marcată în graf printr-
un arc). În caz contrar ok devine FALSE.
ok:=TRUE;
if a [ st[p], st[p-1]]=0 then
ok:=FALSE;
Dacă ok a rămas TRUE, urmează testarea celei de-a doua condiţii. Am spus că soluţia este finală dacă
p=n, iar pe ultimul nivel trebuie să se găsească nodul x. Dar pe ultimul nivel anterior lui n nu putem
avea nodul x (CD-ul revine la proprietar, dar numai după ce a trecut pe la ceilalţi elevi, pe la fiecare o
singură dată).
if ok then
if (p<n) and (st[p]=x)
then
ok:=FALSE
Dacă ok a rămas în continuare TRUE, mai avem şi o a treia condiţie. Nodul st[p] să nu se mai
găsească pe stivă (urmare a faptului că CD-ul trebuie să treacă pe la fiecare elev o singură dată).
Parcurgem într-un ciclu nivelele i=1, 2, …, p-1 anterioare lui p. Dacă găsim un st[i] egal cu st[p],
înseamnă că st[p] se mai găsesc pe un nivel anterior, deci ok devine şi în cazul acesta FALSE.
if ok then
for i:=1 to p-1 do
if st[p]= st[i] then
ok:=FALSE
Procedura recursivă {bktr(p:integer);} “tratează” un nivel oarecare p al stivei.
prin variabila val vor trece pe rând, într-un ciclu, toate valorile care teoretic ar putea fi puse pe
nivelul p. Pentru fiecare dintre aceste valori:
dacă respectiva valoare a generat o soluţie validă (dacă funcţia valid(p) a returnat
TRUE), atunci:
- dacă soluţia respectivă e şi finală o tipărim (apelând procedura tipar (p)); în
caz contrar trecem la nivelul următor (pentru a completa soluţia cu un nou
nivel), prin auto-apelul bktr(p+1).
În programul principal, apelăm procedurile iniţializări şi citire_matrice, apoi declanşăm lanţul recursiv
prin apelul bktr(1) (plecăm de la nivelul 1 al stivei).
Program XI_10;
var n,x:integer;
st:array[1..20] of integer;
a:array[1..20,1..20] of integer;
procedure citire_matrice;
73
{citeste matricea de adiacenta a de la tastatura}
var I,j:integer;
begin
write (‘numarul de noduri: ’); readln(n);
for i:=1 to n do
for j:=1 to n do
begin
write (‘[‘, i, ’,’, j, ‘]=’); readln(a[i, j]);
end;
end;
procedure initializari;
{initializeaza stiva si citeste datele problemei}
var i:integer;
begin
write (‘Cine este proprietarul: ’); readln(x);
for i:=1 to 25 do st[i]:=0;
end;
74
begin;
initializai; citire_matrice; bktr(1); {plecam de la nivelul 1 pe stiva}
end.
Definitie :
Numim graf orientat ,o pereche ordonata de multimi G=(X,U), unde :
- x este o multime finita si nevida numita miltimea nodurilor (varfurilor);
- U este o multime formata din perechi ordonate de elemente ale lui X,numita multimea
arcelor (muchiilor).
Definitie
Se numeste p-graf ,un graf orientat in care numarul arcelor identice este mai mic sau egal cu o valoare
data p.
Pentru evidentierea costurilor tuturor arcelor unui graf cu n noduri se poate defini o matrice a, cu
n linii * n coloane.Exista doua forme ale acestei matrici:
Forma a): Fiecare element a[i,j] poate fi:
c , daca exista un arc de cost c>0 intre nodurile i si j;
0, daca i=j;
+∞ ,daca nu exista arc intre nodurile i si j .
Forma b): Este absolut similara,cu singura deosebire ca in loc de +∞ avem -∞.
Forma a) se foloseste pentru determinarea drumurilor de cost minim intre doua noduri , iar forma b)
este utilizata in aflarea drumurilor de cost maxim.
Daca dorim sa citim matrice costurilor ,evident ca nu putem introduce de la tastatura “+”! In loc de +
vom da un numar intreg foarte mare.
75
Definitie
Gradul exterior al unui varf x, notat d+(x), reprezinta numarul arcelor care ies din nodul x,adica
numarul arcelor de forma (x,y)
apartine de U.
Analog , se defineste gradul interior al unui varf x, notat d¯(x), ca fiind numarul arcelor care intra
in nodul x (de forma (x,y) apartine U)
Reprezentarea grafurilor orientate
Matricea de adiacenta
Are aceeasi semnificatie ca in cazul grafurilor neorientate :fiecare element a[I,j] ,cu I,j apartine de
{1, 2,….,n} ,este: 1 daca exista arcul (I,j), respectiv 0 in caz contrar.
Datorita orientarii, asa cum am mai spus , arcul (I,j) nu este totuna cu arcul (j,I).Prin urmare ,
a[I,j]≠a[j,I].Asadar matricea de
adiacenta nu mai este simetrica fata de diagonala principala , asa cum se intampla in cazul grafurilor
neorientate .
Matricea varfuri-arce
Listele vecinilor
2 6
1 +8
76
3
5
7
4
Fig.1
7
4
Fig.2
Cu alte cuvinte, un graf parţial al unui graf se obţine păstrând aceeaşi mulţime de vârfuri şi
eliminând o parte din muchii.
Definiţie. Un subgraf al unui graf G=(X,U) este un graf H=(Y,V) astfel încât Y X iar V conţine
toate muchiile din U care au ambele extremităţi în Y. Vom spune că subgraful H este indus sau generat
de mulţimea de vârfuri Y.
Ex. Mai jos avem un subgraf al grafului din Fig.1 obţinut prin eliminarea nodului 3
2 6
+8
1
5
7
4
Definiţie. Gradul unui vârf x este numărul muchiilor incidente cu x.
Gradul vârfului x se notează cu d(x).
Ex. în Fig.1 d(1)=3, d(4)=2, d(8)=0, d(6)=1
Un vârf care are gradul 0 se numeşte vârf izolat.
Un vârf care are gradul 1 se numeşte vârf terminal.
Propoziţia 1. Dacă un graf G=(X,U) are m muchii şi n vârfuri iar X={x 1,x2,..,xn}, atunci
d(x1)+d(x2)+...+d(xn)=2m.
Corolar. În orice graf G există un număr par de vârfuri de grad impar.
Definiţie. Se numeşte graf complet cu n vârfuri un graf care are proprietatea că orice două
noduri diferite sunt adiacente.
Propoziţia 2. Un graf complet Kn are n(n-1)/2 muchii.
Definiţie. Un graf G=(X,U) se numeşte bipartit dacă există două mulţimi nevide A, B astfel
încât X=A U B, A B = şi orice muchie u a lui G are o extremitate în A iar cealaltă în B.
Definiţie. Un graf bipartit se numeşte complet dacă pentru orice x din A şi orice y din B, există
în G muchia [x,y].
77
-daca x0=xp,drumul=circuit
-daca toate varfurile circuitului, cu exceptia primului si ultimului sunt distincte,
circuitul=elementar;
-un circuit elementar care trece prin toate nodurile grafului se numeste circuit
hamiltonian.
Definitie.Daca multimea g are proprietatea de simetrie, graful se numeste neorientat.
Definitie.Un graf partial al unui graf neorientat dat G=(X,G) este un graf G1=(X,g1 unde G1 inclus
sau=cu G.
Definitie.Un subgraf al unui graf neorientat G=(X,g) este un graf H=(Y<G1), unde Y inclus in X, iar
muchiile din G1 sunt toate muchiile din G care au ambele extremitati in multimea Y.
Definitie.Lant.Pentru graful neorientat , un lant este o succesiune de varfuri cu proprietatea ca oricare
doua varfuri sunt adiacente.
Se numeste graf complet cu n varfuri , notat Kn , un graf G=(X,U) cu proprietatea ca oricare doua
varfuri sunt adiacente adica :
() x,y є x → ca exista muchia [x,y] apartine de U
Teorema:
Un graf complet cu n varfuri , are n(n-1)/2 muchii.
Definitia :
Se numeste graf bipatrat ,un graf G=(X,U) cu propietate ca exista doua multimi A si B incluse in X,
astfel incat :
-A ∩ B=Ø ,A U B=X,
-toate muchiile grafului au o extremitate in A si cealalta in B .
Definitie :
Se numeste graf bipatrat complet, un graf bipatrat cu propietatea ca pentru orice varf x din A si orice
varf y din B,exista muchia (x,y) (unde A si B sunt cele doua submultimi care partitioneaza miltimea
varfurilor X).
Definitie :
Se numeste lant in graful G ,o succesiune de varfuri (z1, z2,z3 ,….zk),unde x1,x2,…,xk apartine de X ,
cu propietatea ca oricare doua varfuri consecutive sunt adiacente ,adica exista muchiile [z1, z2],[z2 ,z3],
….,[zk-1,zk] apartine de U.
Varfurile z1 si zk se numesc extremitatile lantului ,iar numarul de muchii care intra in componenta sa
reprezinta lungimea lantului .
Definitie :
Se numeste ciclu intr-un graf ,un lant L=(z1,z2,….zk) cu propietatea ca z1=zk si muchiile [z1,z2 ],
[z2,z3], ….,[zk-1,zk] sunt disticte doua cate doua.
Daca intr-un ciclu , toate varfurile cu exceptia primului si a ultimului sunt disticte doua cate
doua ,atunci
ciclul se numeste elementar .In contrar, el este neelementar.
Problema rezolvata
Lant intr-un graf
Sa se verifice daca o secventa de varfuri data reprezinta un lant elementar si neelementar intr-un graf
neorientat. Numarul de varfuri si matricea de adiacenta se citesc de la tastatura, iar secventa testata se
gaseste in fisierul “lant .txt”(varfurile sunt scrise in fisier pe un singur rand separate prin spatii).
program X1-5;
uses crt;
var a:array[1..20,1..20] of integer ;
n,I,j,k:integer;
78
z:array[1..20] of integer;
procedure citire matrice;
{citeste numarul de muchi si muchiile de forma (x,y),si construieste matricea de adiacenta}
var I,j,x,y:integer
begin
{citeste numarul de varfuri n}
write (‘numarul de varfuri :’) ;
readln (n) ;
{initializeaza cu 0 diagonala principala}
for I:=1 to n do a[I,i]:=0;
{citeste portiunea din matrice situata deasupra diagonalei principala}
for I:=1 to n-1 do
for j:=I+1 to n do
begin
writeln (‘exista muchie intre’ ,I,’ si ‘,j, ‘ ? [1/0] ‘);
{citeste elementul a[I,j] cu validare (el trebuie sa fie 0 sau 1)}
repeat
readln (a[I,j]);
until (a[I,j]=0 ) or (a[I,j]=1);
a[j,i] :=a[I,j];
end;
end;
procedure secventa ;
var f:text; ok:boolean;
begin
assign(f, ‘lant./txt’); reset(f);
{citeste secventa de varfuri din fisier in vectorul z=(z[1],z[2],…,z[k])
k:=0;
while not seekeoln (f) do
begin
k:=k+1; read(f,z[k]);
end;
close (f);
{afiseaza vectorul z ce contine secventa}
for I:=1 to k do write(z[I], ‘ ‘);
writeln ;
{verifica daca doua varfuri consecutive in secventa sunt adiacente (daca secventa e lant)}
ok:=TRUE;
for I:=1to k-1 do
if a[z[I],z[I+1]]=0 then ok:=FALSE;
if ok then write (‘lant’)
else writeln (‘secventa nu este in lant ‘);
if ok then
begin
{in cazul in care e lant ,testeaza daca varfurile sunt disticte intre ele(adica lant elementar ) }
for I:=1 to k-1 do
for j:=I+1 to k do
if z[I]=z[j] then ok:=FALSE;
if ok then writeln (‘elementar’)
else writeln (‘ne-elementar ‘);
end;
end;
begin
citire_matrice; secventa ;
end.
79
1.Parcurgerea in latime(BF-breadth first)
-parcurgerea in latime se face incepand de la un nod I, pe care il consideram parcurs;
-parcurgem apoi toti descendentii sai – multimea nodurilor j pentru care exista
[I,j]apartin de g;
-parcurgem apoi toti descendentii nodurilor parcurse la pasul anterior.
Parcurgerea BF se efectueaza prin utilizarea structurii numita coada, avand grija ca un
nod sa fie vizitat o singura data. Coada va fi alocata prin utilizarea unui vector.
PARCURGEREA GRAFURILOR
{Parcuregerea in latime nerecursiv si recursivla =>1 2 3 4 6 5 }
grafuri uses crt;
ex: var a:array[1..20,1..20] of integer;
n=6 co,vi:array[1..20] of integer;
8 muchii si anume (1,2),(1,3)(1,4),(2,4),(2,3),(3,4), i,n,el,j,p,u,pl,m,x,y:integer;
(3,6),(4,5)
80
procedure pp(i:integer); for i:=1 to u do
var j:integer; write(co[i],' ');
begin readln;
for j:=1 to n do end.
if (a[co[i],j]=1) and( vi[j]=0) then begin
u:=u+1; {Parcuregerea in adincime la grafuri neorientate
co[u]:=j; ex:n=5
vi[j]:=1; m=4
end; si anume (1 2),(1 5), ( 2 3),(2 4)
if i<=u then pp(i+1); nodul de pelecare este 1 =>
end; 12345
begin }
clrscr; uses crt;
writeln(' n=');readln(n); var a:array[1..20,1..20] of integer;
writeln(' nuamrul de muchii ');readln(m); vi:array[1..20] of integer;
for i:=1 to m do i,n,el,j,p,u,pl,m,x,y:integer;
begin
writeln('dati muchia ',i); procedure pp(pl:integer);
writeln( 'primul nod al muchiei ');readln(x); var j:integer;
writeln(' nodul de sfirsit al muchiei ');readln(y); begin
a[x,y]:=1;a[y,x]:=1; write(pl,' ');vi[pl]:=1;
end; for j:=1 to n do
for i:=1 to n do if (a[pl,j]=1) and (vi[j]=0) then pp(j);
vi[i]:=0; end;
writeln(' care este nodul de plecare ');readln(pl);
vi[pl]:=1;
co[1]:=pl; begin
p:=1; clrscr;
u:=1; writeln(' n=');readln(n);
while p<=u do writeln(' numarul de muchii ');readln(m);
begin for i:=1 to m do
el:=co[p]; begin
for j:=1 to n do writeln('dati muchia ',i);
if (a[el,j]=1) and (vi[j]=0) then begin writeln( 'primul nod al muchiei ');readln(x);
u:=u+1; writeln(' nodul de sfirsit al muchiei ');readln(y);
co[u]:=j; a[x,y]:=1;a[y,x]:=1;
vi[j]:=1; end;
end; for i:=1 to n do
p:=p+1; vi[i]:=0;
end; writeln(' care este nodul de plecare ');readln(pl);
for i:=1 to u do pp(pl);
write(co[i],' '); readln;
pp(1); end.
writeln(' parcurgere recursiva in latime ');
81
8
7
3 4 6
Un graf G este conex , daca oricare ar fi doua varfuri ale sale ,exista un lant care le leaga.
Definitie:
Se numeste componenta conexa a grafului G=(X,U),un subgraf G1=(X1,U1) a lui
G ,conex , cu propietatea ca nu exista nici un lant care sa lege un nod din X1 cu un nod din X-
X1(pentru orice nod , nu exista un lant intre acel nod si nodurile care nu fac parte din subgraf).
Program componenteconexe; {pentru fiecare pereche,
var m,n ,pi,ps,prim, p, actualizeaza cu 1 elementele
nc:integer; a[x,y] si a[y,x] care
a:array[1..20,1..20] of identifica muchia (x,y)}
integer; for k:=1 to mdo
d,c,viz:array[1..20] of begin
integer; writeln(‘Dati muchia cu
procedure citire_graf; numarul de ordine’,k,’:’);
{citeste numarul de muchii si repeat
muchiile de forma (x,y), si readln(x,y);
construieste matricea de until(x>=1) and (x<=n)
adiacenta} and (y>=n) and (y<=n);
var I,j,k,x,y:integer; a[x,y]:=1; a[y,x]:=1;
begin d[x]:=d[x]+1; d[y]:=d[y]
{citeste numarul de varfuri n +1;
si numarul de muchii m} end;
write (‘Numarul de varfuri :’); end;
readln(n);
write (‘Numarul de function nevizitat :integer;
muchii:’); readln(m); {parcurge tabloul viz:
{initializeaza cu 0 intreg returneaza primul nod
vectorul gradelor d} nevizitat,sau –1 daca nu mai
for i:=1 to n do d[i]:=0; sunt noduri nevizitate}
{initializeaza cu 0 toata var prim_nev,j:integer:
matricea de adiacenta} begin
for i:=1 to n do prim_nev:=-1;
for j:=1 to n do j:=1;
a[i,j]=0; while (j<=n) and
{citeste m perechi de numere (prim_nev= -1) do
intregi de forma (x,y)} begin
82
if viz[j]=0 then if (a[z,k]=1) and (viz[k]=0)
prim_nev:=j; then
j:=j+1; begin
end; pi:=pi+1; c[pi]:=k;
nevizitat:=prim_nev; viz[k]:=1;
end; end;
ps:=ps+1;
function conex:boolean; end;
{verifica daca varful este for k:=1 to pi do write(c[k]:3);
conex,returnand TRUE sau FALSE} if nevizitat=-1 then conex:=TRUE
var k,pi,ps,z:imteger; else conex:=
begin FALSE;
{face o parcurgere a grafului cu
algoritmul BF, plecanddin nodul de end;
start prim} begin
for k:=1 to 20 do c[k]:=0; writeln(‘Afisam componentele
for p;=1 to 20 do viz[p]:=0; conexe:’);
write (‘Dati varful de plecare’); citire_graf; writeln;
readln(prim); if conex:=TRUE then
pi:=1; ps:=1; writeln (‘Graful este conex’)
c[1]:=prim; viz[prim]:=1;
while ps<pi do else
begin writeln(‘Graful NU este conex’);
z:=c[ps]; end.
for k:=1 to n do
Graf tare conex .Componente tare conexe
Definitie:
Un graf orientat G=(X,U) este tare conex, daca pentru oricare doua noduri x si y apartin
de X, exista un drum de la x la y precum si un drum de la y la x.
Definitie
Fiind dat un graf orientat G=(X,U), se numeste componenta tare conexa a lui G ,un
subgraf G1=(X1,U1),tare conex, si maximal in raport cu aceasta propietate (adica pentru orice
nod x apartine de X-X1, subgraful indus de X1 U{x} nu mai este tare conex).
APLICATIE
Algoritmul de descompunere a unui graf in componente tare conexe .
Componenta tare conexa din care face parte nodul i, este multimea :
S[i] ∩ P[i] U{i}
83
procedure afisare_matrice; procedure
{afiseaza matricea de det_tare_conexe;
adiacenta } {descompune graful in
var i,j:integer; componente tare conexe}
begin var i,k:integer;
writeln (‘Graful are ‘ ,n, begin
‘ varfuri’); L:=[ ]; {initializeaza
writeln( ‘Matricea de multimea L a nodurilor
adiacenta este ‘); care au fost incluse in
for i:=1 to n do vreo componenta}
begin nc:=0; {initializeaza
for j:=1 to n do numarul componentelor
write(a[i,j]:2) ; tare conexe}
writeln; for i:=1 to n do
end; {parcurge nodurile de la i
end; 1 la n}
if not (i in L) then
procedure {daca nodul i nu a fost
formarea_matrice_drumur deja inclus in vreo
i; componenta}
{formeaza matricea begin
drumurilor (memorata tot {inaugureaza o
in a), cu algoritmul Roy- noua componenta ,deci
Warshall} creste numarul
var i,j,k:integer; componentelor}
begin nc:=nc+1;
for k:=1 to n do det_S(i);
for i:=1 to n do {determina S[i]}
for j:=1 to n do det_P(i);
if a[i,j]=0 then {determina P[i]}
a[i,j]:=a[i,k]*a[k,j]; C[i]:=(S[i]*P[i] ) +
end; [i]; {calculeaza
componenta tare conexa
procedure det_S C[i]}
(i:integer); {determina {adauga C[i] la
multimea S[i]} multimea nodurilor care
var k:integer; fac deja parte dintr-o
begin componenta}
S[i]:=[ ]; L:=L+C[i];
for k:=1 to n do {tipareste
if a[i,k]=1 then componenta conexa C[i]}
S[i]:=S[i]+[k] ; writeln
end; (‘Componenta conexa ]
‘,nc, ‘este ‘ );
procedure det_P for k:=1 to n do
(i:integer); {determina if k in C[i] then
multimea P[i]} write(k:3);
var k:integer; writeln;
begin end;
P[i]:=[ ]; end;
for k:=1 to n do
if a[k,i]=1 then begin
P[i]:=P[i] +[k]; citire_ matrice;
end; afisare_matrice;
84
formare_ close(f);
matrice_drumuri; end;
afisare_matrice; det_
tare_conexe; procedure
end. Roy_Warshall;
COMPONENTE TARE var i,j,k:byte;
CONEXE begin
EX: for k:=1 to n do
{Se considera o multime for i:=1 to n do
formata din n persoane in for j:=1 to n do
care fiecare persoana if a[i,j]=0 then
se cunoaste pe sine si a[i,j]:=a[i,k]*a[k,j];
eventual alte persoane. Sa end;
se formeze grupuri in
care fiecare persoana sa procedure componente;
var k,i,j:byte;
cunoasca toate celelalte viz:array[1..50] of
persoane din grup( o boolean;
persoana apartine unui begin
singur grup). for i:=1 to n do
Relalia „ x cunoaste pe y" viz[i]:=false;
nu este in mod normal nici k:=1;
simetrica, nici tranzitiva. for i:=1 to n do
if not viz[i] then
Rezolvare begin
Rezolvarea se bazeaza pe writeln('Componenta',k,':
algoritmul de determinare ');
a componentelor tare write(i,' ');
conexe intr-un viz[i]:=true;
graf orientat.} for j:=1 to n do
if(j<>i)and
program tareconexe; (a[i,j]<>0)and(a[j,i]<>0)th
type en
mat=array[1..50,1..50] of begin
byte; write(j,' ');
var f:text; viz[j]:=true;
n:byte; end;
a:mat; k:=k+1;
procedure citeste; writeln
var i,x,y:byte; end;
begin end;
assign(f,'in7.pas');
reset(f); begin
readln(f,n); citeste;
Roy_Warshall;
while not eof(f) do componente;
begin readln;
readln(f,x,y); end.
a[x,y]:=1;
end;
85
8.5 Drumuri minime si maxime in grafuri
orientate(Dijkstra,Roy-Floyd)
Consideram un graf orientat G=(X,U) cu n noduri, in care fiecarui arc ii este asociat un numar
intreg numit cost. Semnificatia
acestui cost poate fi foarte variata , in functie de domeniul pe care il descrie graful .
Matricea costurilor
Pentru evidentierea costurilor tuturor arcelor unui graf cu n noduri se poate defini o matrice a, cu
n linii * n coloane.Exista doua forme ale acestei matrici:
Forma a): Fiecare element a[i,j] poate fi:
c , daca exista un arc de cost c>0 intre nodurile i si j;
0 , daca i=j;
+∞ ,daca nu exista arc intre nodurile i si j .
Forma b): Este absolut similara,cu singura deosebire ca in loc de +∞ avem -∞.
Forma a) se foloseste pentru determinarea drumurilor de cost minim intre doua noduri , iar
forma b) este utilizata in aflarea drumurilor de cost maxim.
Daca dorim sa citim matrice costurilor ,evident ca nu putem introduce de la tastatura “+”! In
loc de + vom da un numar intreg foarte mare.
Algoritmul lui Dijkstra
Se consideră un graf neorientat, conex cu N noduri. Graful este dat prin matricea
costurilor A.
Se consideră un nod iniţial R. Se cer lungimile drumurilor minime de la R la celelalte noduri ale
grafului, precum şi nodurile prin care trec aceste drumuri.
Problema are numeroase aplicaţii practice. Să presupunem că dispunem de o hartă cu oraşele
unei ţări. Acestea sunt unite prin şosele. Oraşele formează nodurile grafului, iar şoselele – arcele
acestuia. Algoritmul furnizează drumurile optime de la un oraş iniţial la celelalte oraşe. Este
interesant de observat faptul că, spre deosebire de alţi algoritmi, acesta furnizează şi nodurile
prin care trec drumurile optime, nu numai lungimile acestora.
86
Pentru acest graf matricea costurilor este:
0 13 16 8
0 6 10
13 0 14 11
6 14 0 5 17
16 5 0 7
8 10 11 17 7 0
Prezentarea algoritmului.
P1) Nodul R este adăugat mulţimii S iniţial vidă (S(R)=1);
- costurile drumurilor de la R la fiecare nod al grafului se preiau în vectorul D de pe linia R
a matricii A;
- pentru toate nodurile I având un cost al drumului de la R la ele finit, se pune T(I)=R.
P2) Se execută de n-1 ori secvenţa
- printre nodurile neselectate se caută cel aflat la distanţa minimă faţă de R şi se selectează
adăugându-l mulţimii S;
- pentru fiecare din nodurile neselectate se actualizează în D costul drumurilor de la R la
el, utilizând ca nod intermediar nodul selectat, procedând în felul următor: se compară distanţa
existentă în vectorul D cu suma dintre distanţa existentă în D pentru nodul selectat şi distanţa de
la nodul selectat la nodul pentru care se face actualizarea distanţei (preluată din A), iar în cazul
în care suma este mai mică, elementul din D corespunzător nodului pentru care se face
actualizarea capătă ca valoare aceasă sumă şi elementul din T corespuzător aceluiaşi nod ia
valoarea nodului selectat (drumul trece prin acest nod). Presupunând că a fost selectat nodul K,
se actualizează distanţa pentru nodul L şi se compară D(K)+A(K,L) cu D(L).
87
P3) Pentru fiecare nod al grafului, cu excepţia lui R, se trasează drumul de la R la el.
S 1 0
0 0 0 0
T 0 0
1 0 1 0
1 1 2 1
D 0 8 3 5 5 8
S 1 0 0 0 0 1
T 0 6 1 6 6 1
Se selectează nodul 3.
D(3)+A(3,2)=13+>18D(2)=18.
D(3)+A(3,4)=13+14=27>25D(3)=13.
D(3)+A(3,5)=13+>15D(5)=15.
0 1 1 2 1
D 8 3 5 5 8
S 1 0
1 0 0 1
T
0 6 1 6 6 1
Se selectează nodul 5.
D(5)+A(5,2)=15+>18D(2)=18.
D(5)+A(5,4)=15+5=20D(4)=20 şi T(4)=5.
1 1 2 1
D 0 8 3 0 5 8
88
S 1 0 1 0 1 1
T 0 6 1 5 6 1
Se selectează nodul 2.
D(2)+A(2,4)=18+6=24>20D(4)=20.
1 1 2 1 8
D 0 8 3 0 5
S 1 1 1 0 1 1
1
T 0 6 1 5 6
Se selectează nodul 4.
În continuare, pentru fiecare nod se trasează drumul de la nodul iniţial la el.
Vom considera, ca exemplu, nodul 4. Distanţa de la nodul 1 la el D(4) şi anume 20.
Avem T(4)=5; T(5)=6; T(6)=1; drumul trece prin nodurile 1,6,5.
Avem A(1,6)=8; A(6,5)=7; A(5,4)=5.Rezultă 8+5+7=20.
Întrucât drumul se trasează în ordine inversă faţă de cum este găsit, în program se foloseşte o
procedură recursivă.
În cele ce urmează vom nota nodurile cu Ni1,Ni2,…,Nin. Acestea sunt tot nodurile 1,2,…,R,
…,N cosiderate în altă ordine. Nodului R îi corespunde nodul Ni1.
Demonstrarea algoritmului.
Lema 1. Algoritmul selectează nodurile în ordinea costului drumului de la nodul iniţial la ele.
Demonstraţie:
Utilizăm metoda inducţiei matematice. Prima dată se selectează nodul Ni2 (are costul drumului
minim faţă de Ni1). Aceasta înseamnă că ipoteza de inducţie se verifică pentru prima selecţie.
Presupunem că nu au fost selectate nodurile Ni2,Ni3,…,Nip (p<n) în ordinea costului drumului
de la Ni1 la ele. Se selectează nodul Nip+1. Presupunem, prin absurd, că există un alt nod N1,
neselectat, care are un cost al drumului de la Ni1 la el mai scăzut decât al nodului Nip+1. Atunci,
acesta poate fi plasat în şirul nodurilor deja selectate, aşezate în ordinea distanţei faţă de Ni1, în
următoarele două moduri:
1) Ni1,…,N1,…,Nip,Nip+1.
În acest caz, se contrazice ipoteza de inducţie (nodurile Ni1,…,Nip erau aşezate în ordine
distanţei faţă de Ni1).
2) Ni2,…, Nip,N1,Nip+1.
Aici este contrazisă alegerea lui Nip+1. Acesta a fost ales ca nod cu distanţă minimă faţă de Nil
dintre toate nodurile neselectate, iar N1 este un nod neselectat.
Lema 2. Orice drum optim de la nodul iniţial la oricare din nodurile selectate trece numai prin
noduri selectate.
Demonstraţie:
Presupunem prin absurd că există un drum de cost mai mic de la Ni1 la Nik (Nik este un nod
deja selectat) care nu trece numai prin noduri selectate. Fie Nz primul nod prin care trece acest
drum şi care nu este selectat. Aceasta înseamnă că nodul Nz are costul drumului de la Ni1 la el
mai mic decât cel de la Ni1 la Nik (nod care este selectat). Aceasta contrazice LEMA 1.
TEOREMĂ.
89
Odată selectat un nod, nu există un drum de cost mai mic între Ni1 şi el, decât drumul de cost
indicat de vectorul D.
Demonstraţie:
În demonstrarea acestui fapt utilizăm metoda inducţiei matematice.
Pentru selectarea lui Ni2 afirmaţia este evidentă, întrucât acesta este cel mai apropiat de Ni1.
Presupunem selectate nodurile Ni2,…,Nip. Selectăm Nip+1. Presupunem că de la Ni1 la el există
un drum de cost mai mic decât cel indicat de vectorul D.
Avem două posibilităţi:
90
end; write(‘r=’); readln(r);
if not gasit then write(v2,' '); for I:=1 to n do
end; begin
begin s[I]:=0; t[I]:=0;
citeste; a[I,I]:=0;
mat_drumuri; end;
if a[x,y]=infinit then writeln('Nu exista lant s[r]:=1;
elementar intre cele doua varfuri') for I:=1 to n do
else begin
begin d[I]:=a[r,I];
writeln('Drumul minim are lungimea:',a[x,y]); if I<>r then
write(x,' '); t[I]:=r;
drum(x,y); end;
end; for I:=1 to n-1 do
readln; begin
end. min:=30000;
for j:=1 to n do
ALGORITMUL DIJKSTRA if s[j]=0 then
Program dijkstra; begin
Type mat=array[1..10,1..10] of integer; min:=d[j];
vect=array[1..10] of integer; poz:=j;
var a:mat; end;
s,t,d:vect; s[poz]:=1;
n,I,j,r,min,poz:integer; for j:=1 to n do
if s[j]=0 then
procedure drum(I:integer); if d[j]>d[poz]+a[poz,j] then
begin begin
if t[i]<>0 d[j]:=d[poz]
then +a[poz,j];
begin t[j]:=poz;
drum(t[i]);write(i); end;
end end;
else write(I); for I:=1 to n do
end; if I<>r then
begin begin
write (‘n=’);readln(n); writeln(‘Distanţa de la nodul’,r,’la
writeln(‘Introduceţi matricea nodul’,’este ‘,d[I]);
costurilor’); drum[I];
for I:=1 to n do writeln;
for j:=I+1 to n do end;
begin end.
write(‘a[‘,I,’,’,j,’]=’);
readln(a[I,j]); a[j,I]:=a[I,j];
end;
writeln(‘Introduceţi nodul de pornire’);
91
matricea ponderilor este
019ω 3
ω 0 7 3 ω
ω ω 0 ω ω
1 ω 2 0 ω
ω 4 ω 2 0
Etapa 1)Caut drumurile optime intre oricare doua noduri dar drumurile trec prin nodul
intermediar 1
a[4,2]= ω >a[4,1]+a[1,2]=1+1=2 deci a[4,2]=2
a[4,5]=ω>a[4,1]+a[1,5]=1+3=4 deci a[4,5]=4
matricea ponderilor este
019ω 3
ω 0 7 3 ω
ω ω 0 ω ω
1 2 2 0 4
ω 4 ω 2 0
92
Etapa 2)Caut drumurile optime intre oricare doua noduri dar drumurile trec prin nodul
intermediar 2
a[1,3]=9>a[1,2]+a[2,3]=1+7=8 deci a[1,3]=8
a[1,4]=ω>a[1,2]+a[2,4]=1+3=4 deci a[1,4]=4
a[5,3]=ω>a[1,2]+a[2,3]=4+7=11 deci a[5,3]=11
a[5,4]=ω>a[5,2]+a[2,4]=4+3=7 deci neschimbat
0184 3
ω 0 7 3 ω
ω ω 0 ω ω
1 2 2 0 4
ω 4 11 2 0
Etapa 3)Caut drumurile optime intre oricare doua noduri dar drumurile trec prin nodul
intermediar 3 dar nu avem nimic nou.
Etapa 4)Caut drumurile optime intre oricare doua noduri dar drumurile trec prin nodul
intermediar 4
a[1,3]=ω>a[1,4]+a[4,3]=4+2=6 deci a[1,3]=6
a[2,1]=ω>a[2,4]+a[4,1]=3+1=4 deci a[2,1]=4
a[2,3]=ω>a[2,4]+a[4,3]=3+2=5 deci a[2,3]=5
a[2,5]=ω>a[2,4]+a[4,5]=3+4=7 deci a[2,5]=7
a[5,1]=ω>a[5,4]+a[4,1]=2+1=3 deci a[5,1]=3
a[5,3]=ω>a[5,4]+a[4,3]=2+2=4 deci a[5,3]=4
93
0164 3
4 0 5 3 7
ω ω 0 ω ω
1 2 2 0 4
3 4 4 2 0
94
drumul cel mai scurt intre doua write(ni,' ');
noduri(exemplu intre primul si drum(ni,nf);
ultimul end
) adica drumul care are costul else write('nu este drum de la
cel mai mic Se va introduce ',ni,' la ',nf);
acolo unde nu avem arc orientat writeln;
sau nu avem drum end;
intre doua noduri o cifra mare
cum ar fi 300 pe rol de procedure lungime;
infinit} var i,j,k:integer;
const minfinit=1.e20; begin
var a:array [1..50,1..50] of for k:=1 to n do
real; for i:=1 to n do
n,i,j:integer; for j:=1 to n do
if a[i,j]>a[i,k]+a[k,j] then
procedure drum(i,j:integer); a[i,j]:=a[i,k]+a[k,j];
var k:integer;gasit:boolean; end;
begin
k:=1; begin
gasit:=false; write('n=');
while (k<=n) and not gasit do readln(n);
begin for i:=1 to n do
if (i<>k) and (j<>k) and for j:=1 to n do
(a[i,j]=a[i,k]+a[k,j]) if i=j then
then a[i,j]:=0
begin else a[i,j]:=minfinit;
drum (i,k); for i:=1 to n do
drum(k,j); for j:=1 to n do
gasit:=true; if i<>j then
end; begin
k:=k+1; write('a[',i,',',j,']=');
end; readln(a[i,j]);
if not gasit then end;
write(j,' '); lungime;
end; for i:=1 to n do
for j:=1 to n do
procedure scriu(ni,nf:byte); scriu(i,j);
begin writeln;
if a[ni,nf]<minfinit then begin readln;
writeln('drumul de la ',ni,' end.
la ',nf,' are lungimea
',a[ni,nf]:5:0);
95
end;
var x:sir;
p,i,j,k,n,k1:integer; begin
as,ev:boolean;
a:array[1..50,1..50] of integer; write('dati numarul de noduri din graf');
readln(n);
procedure succesor(var x:sir;k:integer;var
as:boolean); for i:=1 to n-1 do
begin begin
if (x[k]<n) then begin for j:=i+1 to n do
as:=true; x[k]:=x[k]+1; begin
write('numarul ',i,',',j,' este ');
end readln(a[i,j]);
else a[j,i]:=a[i,j];
as:=false; end;
end; end;x[1]:=1;
k:=2; j:=0;
procedure valid(x:sir;k:integer;var x[k]:=1;
ev:boolean); while(k>0) do
var i:integer; begin
begin repeat
ev:=true; succesor(x,k,as);
if a[x[k-1],x[k]]=0 then ev:=false if as then valid(x,k,ev)
else until (as and ev) or (not as);
begin if as then
for i:=1 to k-1 do if (k=n) then
if x[k]=x[i] then ev:=false; afis(x,k)
if (k=n) and(a[x[n],x[1]]=0) then ev:=false; else
end; begin
end; k:=k+1;
x[k]:=1;
procedure afis(x:sir;k:integer); end
var i:integer; else
begin k:=k-1 ;
for i:=1 to k do end;
write( x[i] ,' '); readln;
write(x[1]:4); end.
writeln;
Grafuri euleriene
Definitie:
Se numeste ciclu eulerian intr-un graf, un ciclu care contine toate muchiile grafului.
Se numeste graf eulerian, un graf care contine un ciclu eulerian.
Teorema:
Un graf fara varfuri izolate este eulerian, daca si numai daca este conex, si gradele tuturor
varfurilor sunt numere pare
fara virfuri izolate si care are gradele fiecarui
{Stiind ca un graf conex(are o singura virf un numar par
componenta conexa) , Sa se determine daca este ciclu eulerian sa nu
ex:n=3
m=3 si anume (1,2),(1,3),(2,3)
96
=>1 2 3 1 e ciclu eulerian} begin
var eulerian:boolean; write(' cite noduri are graful n=');
e,grd,nd,c1:array[1..20] of integer; readln(n);
a:array[1..20,1..20] of integer; write(' cite muchii are graful m=');
n,m,i,j,k,k1,x,y,l:integer; readln(m);
viz:array[1..20] of byte; for I:=1 to n do
function izolate:boolean; for j:=1 to n do
var i,j,m,intr:byte; a[i,j]:=0;
begin writeln('dati muchiile ');
izolate:=false; for i:=1 to m do
for i:=1 to n do begin
begin writeln('primul nod al muchiei ',i,' este
intr:=0; ');readln(x);
for j:=1 to n do writeln('urmatorul nod al muchiei ',i,' este
intr:=intr+a[i,j]; ');readln(y);
grd[i]:=intr; a[x,y]:=1;
if intr=0 then begin a[y,x]:=1;
izolate:=true; end;
break; eulerian:=not izolate and gradepare and conex;
end; if not eulerian then writeln ('graful nu este
end; eulerian ')
end; else
function gradepare:boolean; begin
var i:byte; writeln('este eulerian ');
begin nd[1]:=1;
gradepare:=true; k:=1;
for i:=1 to n do repeat
if odd(grd[i]) then begin for j:=1 to n do
gradepare:=false; if a[nd[k],j]=1 then begin
break; k:=k+1;
end; nd[k]:=j;
end; a[nd[k-1],j]:=0;
function conex:boolean; a[j,nd[k-1]]:=0;
var b,viz:array[1..20] of byte; grd[j]:=grd[j]-1;
i,j,p,u,v:byte; grd[nd[k-1]]:=grd[nd[k-1]]-1;
begin break;
for j:=1 to n do end;
viz[j]:=0; until nd[k]=1;
b[1]:=1; while k-1 <m do begin
p:=1; for i:=1 to k-1 do
u:=1; if grd[nd[i]]>0 then begin
viz[1]:=1; c1[1]:=nd[i];
while p<=u do begin L:=i;
v:=b[p]; break;
for j:=1 to n do end;
if (a[v,j]=1) and (viz[j]=0) then k1:=1;
begin repeat
u:=u+1; for j:=1 to n do
b[u]:=j; if a[c1[k1],j]=1 then begin
viz[j]:=1; k1:=K1+1;
end; c1[k1]:=j;
p:=p+1; a[c1[k1-1],j]:=0;
end; a[j,c1[k1-1]]:=0;
conex:=true; grd[j]:=grd[j]-1;
for i:=1 to n do grd[c1[k1-1]]:=grd[c1[k1-1]]-1;
if viz[i]=0 then begin break;
conex:=false; end;
break; until c1[k1]=c1[1];
end; for j:=k downto L do
end; nd[j+k1-1]:=nd[j];
97
for j:=1 to k1-1 do for i:=1 to m+1 do
nd[j+1]:=c1[j+1]; write(' ',nd[i]);
k:=K+k1-1; end;
end; readln;
writeln('un ciclu care trece prin toate muchiile end.
este ');
Definiţie. Se numeşte arbore un graf orientat care este conex si nu conţine cicluri.
Problema. Se citeşte un graf sa se scrie un program care sa verifice daca este arbore.
1. Mai întâi trebuie văzut daca graful este conex. In cazul grafurilor orientate aceasta problema se rezolva printr-o
simpla parcurgere in adâncime (DF). Dar in cazul grafurilor neorientate? Aici apare o problema. De la nodul i la
nodul j exista doua arce, de la i la j si de la j la i. Aceasta conduce la semnalarea unui ciclu fals. Pentru rezolvarea,
după alegerea unei muchii ,de exemplu de la i la j se elimina muchia de la j la i. In final daca au fost atinse toate
nodurile(adică daca orice componenta a vectorului s retine numai 1) înseamnă ca graful este conex.
2. Trebuie analizat daca graful nu are cicluri. Aceasta problema se rezolva tot cu ajutorul parcurgerii in adâncime.
Parcurgerea asigura selecţia unei muchi o singura data. Daca graful are cel puţin un ciclu, atunci un nod este atins
de doua ori. Cum ne putem da seama ca aceasta are loc? simplu, daca a fost atins un nod i , după care s[i]=1.
program arbore ;
uses grafuri;
var s:array[1.. 50] of byte;
A:mat_ad;
gasit:boolean;
n,i,suma:integer;
procedure df_r(nod:byte);
var k:byte;
begin
s[nod]:=1;
for k:=1 to n do
if (a[nod,k]=1)
then
begin
a[k,nod]:=0;
if s[k]=0; then df_r(k)
else gasit:=true;
end;
end ;
begin
clrscr;
citiren( ` graf.txt `,a,n);
df_r(1);
suma:=0;
for i:=1 to n do suma:=suma +s[i];
98
if suma<>n then
writeln( `graful nu este conex `);
else if gasit then writeln( ` graful are ce putin un ciclu `);
else writeln( ` este arbore `);
end. .
Mai jos este reprezentat grafic acelasi arbore in mai multe feluri. Ultimele 3 reprezentări sunt
făcute considerând pe rând ca vârf al arborelui nodurile 1,3,2. de asemenea ultimele trei
reprezentări justifica si denumirea data grafurilor conexe si fara cicluri, cea de arbori.
Teorema. Fie G un graf neorientat cu n noduri. G este arbore daca si numai daca g are n-1 muchii si nu
contine cicluri.
Demonstraţie :
Vom demonstra prin inducţie. Daca n=1,numarul muchiilor este 0(se verifica). Vom presupune
proprietatea adevărata pentru arbori cu n noduri(vom avea n-1 muchii). Fie un arbore cu n+1 noduri.
Exista cel putin un nod terminal(nod care are o singura muchie incident). Daca nu ar exista un astfel de
nod, arborele va contine cicluri(se contrazice definiţia). Eliminam nodul terminal si muchia care ii este
incident. Obţinem un arbore cu n noduri. Conform ipotezei făcute aceasta va avea n-1 muchii.
Înseamnă ca arborele cu n+1 noduri va avea n muchii(n- 1 +1).
Fie un graf cu n-1 muchii care nu contine cicluri. Rămâne de dovedit ca G este conex. Vom
demonstra prin reducere la absurd. Presupunem ca G nu este conex. Fie G 1, G2, .. ,Gp componentele
conexe. Fiecare dintre ele indeplineste conditiile:
Rezulta ca fiecare dintre ele este arbore. Fie mi numarul muchiilor si ni numarul nodurilor fiecarui arbore
Gi. Avem mi=ni-1. Dar m1+m2+….+mp=n-1. Rezulta: n1-1+n2-1+…..np-1=n-1, deci n1+n2+…..+np=n+p-1.
99
Dar G are n noduri. Rezulta :n+p-1=n,deci p=1. In concluzie exista o singura componenta conexa care
nu contine cicluri. Deci G este arbore.
Din demonsratie s-a vazut ca un graf neorientat fara cicluri dar neconex este alcătuit,
din mai mulţi arbori. Din acest motiv, un astfel de graf se numeşte pădure !
Tot in aceasta demonstatie, a fost introdus termenul de nod terminal al unui arbore cu
o singura muchie incident.
Ati reţinut, ca arborele poate fi privit ca avand un anumit varf ! Varf al arborelui poate
fi oricare nod al sau, deci si unul termial !
Algoritmul lui Prim
Fie G=(X,) un graf neorientat şi conex. Graful este dat prin matricea costurilor. Se cere să se
determine arborele de cost parţial minim (între oricare două noduri să existe un drum), iar în plus suma
muchiilor să fie minimă.
O problemă concretă, în care intervine problema enunţată, este cea a conectării oraşelor cu
cost minim.
Avem N oraşe precum şi costul conectării anumitor perechi de oraşe. Se cere să se genereze
muchii care asigură existenţa unui drum între oricare două oraşe astfel încât costul cuplării să fie
minim.
Pentru rezolvare se folosesc trei vectori:
-vectorul S, vector caracteristic. Avem S(I)=0 dacă nodul I nu aparţine arborelui construit şi
S(I)=1 în caz contrar;
-vectorul T reţine pentru fiecare nod care se adaugă arborelui nodul părinte al acestuia (cu
ajutorul acestui vector se poate reconstitui arborele);
-vectorul P reţine pentru fiecare nod C costul arcului de la părinte la el.
Prezentarea algoritmului.
P1) Se citeşte N (numărul nodurilor), matricea costurilor A şi nodul de pornire V (S(V)=1);
P2) Se alege muchia de cost minim (L,C) care are o extremitate într-unul din nodurile
arborelui deja construit (S(L)=1), iar cealălaltă într-un nod care nu aparţine arborelui (S(C)=0). Se pune
T(C)=L şi P(C)=A(L,C);
3 2
5 2
5
2 1 5
4 3
4
Se porneşte cu nodul 1(v=1).
100
Alegem muchia de cost minim (1,2).
S=(0 0 2 2 1)
Pentru nodurile 1 şi 2, ca puncte de plecare, se alege muchia de cost minim (2,4) si s=(0 0 4 0 1)
2
1
21
4
2 3
5
11
3
2 5
1
4
101
3
4
s=(0 0 0 0 0)
Am ales patru muchii şi s-a obţinut muchia de cost minim.
Configuraţiile finale ale vectorilor T şi P sunt:
1 2 3 4 5
T 0 1 4 2 1
P 0 2 4 1 3
Dacă pornim dintr-un alt nod, este posibil să obţinem un alt arbore dar şi el va avea costul
minim.
Demonstrarea algoritmului.
În urma aplicării algoritmului se obţine un arbore (vom avea N noduri şi N-1 muchii).
Rămâne de demonstrat că acest arbore este de cost minim. Notăm cu Gk=(Xk,k) arborele
obţinut după alegerea a k muchii, cu k{1,2,…,N-1}. Fie G1 un arbore de cost minim. Fie M1,M2,
…,Mk primele k muchii găsite în urma aplicării algoritmului pentru arborele Gk+1. Considerăm că
muchia Mk este prima muchie care nu aparţine lui G1. Fie P şi Q cele două noduri unite de muchia Mk.
Este evident că în G1, cele două nu sunt unite direct (în caz contrar muchia Mk ar face parte din arborele
G1). Aceasta înseamnă că în G1, nodurile P şi Q sunt unite printr-un lanţ. Acest lanţ nu aparţine lui G k+1,
pentru că el împreună cu Mk ar forma un ciclu. Înseamnă că acest lanţ uneşte în G1 două noduri, P1 şi
Q1 cu P1Xk şi Q1Xk. În caz contrar dacă ar uni numai noduri din Xk înseamnă că Gkm ar conţine un
lanţ (conţine muchia Mk, care uneşte pe P şi Q, conţine şi restul lanţului din G1 pentru că primele k
noduri în G1 şi Gk sunt legate identic). Presupunem nodurile P1 şi Q1 unite prin muchia M1. Înlocuim
în G1 pe M1 cu Mk. În urma acestei înlocuiri,G1 se transformă într-un alt arbore G2. Dar
A(P,Q)A(P1,Q1) pentru că în caz contrar, prin logica algoritmului, s-ar fi ales muchia M1. Aceasta
înseamnă că arborele parţial G2 rămâne tot de cost minim. În plus G1 şi Gk+1 au k+1 muchii care
coincid. Repetăm procedeul până obţinem coincidenţa a n-1 muchii. Rezultă de aici că l-am
transformat pe G1 în arborele generat de algoritm fără a-i modifica costul. În concluzie arborele generat
de algoritm este de cost minim.
Program prim;
Type matrice=array[1..9,1..9] of integer;
vector=array[1..9]of integer;
var a:matrice;
s,t,p:vector;
n,I,j,k,v,min,l,c:integer;
begin
write(‘n=’); readln(n);
for l:=1 to n-1 do
for j:=I+1 to n do begin
write(‘a[‘,I,’,’,j,’]=’);
readln(a[I,j]);
a[j,I]:=a[I,j];
end;
write (‘nodul de pornire=’); readln(v);
for I:=1 to n do begin
s[I]:=0;
t[I]:=0;
p[I]:=0
end;
s[v]:=1;
for k:=1 to n-1 do begin
102
min:=30000;
for I:=1 to n do
for j:=1 to n do
if (s[I]=1)and (s[j]=0)and (min>a[I,j])then
begin
min:=a[I,j];
I:=I;
c:=j
end;
ARBORI SI ARBORESCENTE
Arbori
Noţiunea de arbore
Definiţie. Se numeşte arbore un graf orientat care este conex si nu conţine cicluri.
103
Problema. Se citeşte un graf sa se scrie un program care sa verifice daca este arbore.
1. Mai întâi trebuie văzut daca graful este conex. In cazul grafurilor orientate aceasta problema se rezolva printr-o
simpla parcurgere in adâncime (DF). Dar in cazul grafurilor neorientate? Aici apare o problema. De la nodul i la
nodul j exista doua arce, de la i la j si de la j la i. Aceasta conduce la semnalarea unui ciclu fals. Pentru rezolvarea,
după alegerea unei muchii ,de exemplu de la i la j se elimina muchia de la j la i. In final daca au fost atinse toate
nodurile(adică daca orice componenta a vectorului s retine numai 1) înseamnă ca graful este conex.
2. Trebuie analizat daca graful nu are cicluri. Aceasta problema se rezolva tot cu ajutorul parcurgerii in adâncime.
Parcurgerea asigura selecţia unei muchi o singura data. Daca graful are cel puţin un ciclu, atunci un nod este atins
de doua ori. Cum ne putem da seama ca aceasta are loc? simplu, daca a fost atins un nod i , după care s[i]=1.
program arbore ;
uses grafuri;
var s:array[1.. 50] of byte;
A:mat_ad;
gasit:boolean;
n,i,suma:integer;
procedure df_r(nod:byte);
var k:byte;
begin
s[nod]:=1;
for k:=1 to n do
if (a[nod,k]=1)
then
begin
a[k,nod]:=0;
if s[k]=0; then df_r(k)
else gasit:=true;
end;
end ;
begin
clrscr;
citiren( ` graf.txt `,a,n);
104
df_r(1);
suma:=0;
for i:=1 to n do suma:=suma +s[i];
if suma<>n then
writeln( `graful nu este conex `);
else if gasit then writeln( ` graful are ce putin un ciclu `);
else writeln( ` este arbore `);
end. .
Mai jos este reprezentat grafic acelasi arbore in mai multe feluri. Ultimele 3 reprezentări sunt
făcute considerând pe rând ca vârf al arborelui nodurile 1,3,2. de asemenea ultimele trei
reprezentări justifica si denumirea data grafurilor conexe si fara cicluri, cea de arbori.
Teorema. Fie G un graf neorientat cu n noduri. G este arbore daca si numai daca g are n-1 muchii si nu
contine cicluri.
Demonstraţie :
Vom demonstra prin inducţie. Daca n=1,numarul muchiilor este 0(se verifica). Vom presupune
proprietatea adevărata pentru arbori cu n noduri(vom avea n-1 muchii). Fie un arbore cu n+1 noduri.
Exista cel putin un nod terminal(nod care are o singura muchie incident). Daca nu ar exista un astfel de
nod, arborele va contine cicluri(se contrazice definiţia). Eliminam nodul terminal si muchia care ii este
incident. Obţinem un arbore cu n noduri. Conform ipotezei făcute aceasta va avea n-1 muchii.
Înseamnă ca arborele cu n+1 noduri va avea n muchii(n- 1 +1).
Fie un graf cu n-1 muchii care nu contine cicluri. Rămâne de dovedit ca G este conex. Vom
demonstra prin reducere la absurd. Presupunem ca G nu este conex. Fie G 1, G2, .. ,Gp componentele
conexe. Fiecare dintre ele indeplineste conditiile:
105
Rezulta ca fiecare dintre ele este arbore. Fie mi numarul muchiilor si ni numarul nodurilor fiecarui arbore
Gi. Avem mi=ni-1. Dar m1+m2+….+mp=n-1. Rezulta: n1-1+n2-1+…..np-1=n-1, deci n1+n2+…..+np=n+p-1.
Dar G are n noduri. Rezulta :n+p-1=n,deci p=1. In concluzie exista o singura componenta conexa care
nu contine cicluri. Deci G este arbore.
Din demonsratie s-a vazut ca un graf neorientat fara cicluri dar neconex este alcătuit, din mai mulţi
arbori. Din acest motiv, un astfel de graf se numeşte pădure !
Tot in aceasta demonsratie, a fost introdus termenul de nod terminal al unui arbore cu
o singura muchie incident.
Ati reţinut, ca arborele poate fi privit ca avand un anumit varf ! Varf al arborelui poate
fi oricare nod al sau, deci si unul termial !
- matricea de adiacenta;
- liste de adiacente.
2. O a doua forma de reprezentare a arborilor este legatura de tip TATA . arborele se
reprezinta sub forma unui vector t cu n componente: daca t[i]=k, atunci nodul i
este descendent al nodului k. Daca nodul i este varf, t[i]=0.
5 3 5 5 0 3 4 1 7--------- k
1 2 3 4 5 6 7 8 9 --------- t[i]
In mod evident, legatura de tip TATA este determinata si de nodul ales ca varf ! Daca, de exemplu
pentru acelasi arbor varful este 9, reprezentarea este alta. Este ca si cum „apucam” arborele de un nod
si celelalte cad !
106
035003 417
123456789
3.Codul lui Puffer(facultativ). Pentru a reprezenta un arbore oarecare se pot utiliza doi vectori, pe care-i
vom numi t-de la nodul terminal – si pt – de la parinte nod terminal. Modul in care acestia retin datele
este explicat mai jos:
Se cauta cel mai mic nod terminal, acesta este retinut in vectorul t iar parintele sau este
memorat in vectorul pt.
Se obtine un nou arbore renuntand la nodul terminal si la muchia care-l uneste de parinte.
Procedeul se rea pana cand ramane un arbore cu un singur nod.
Exemplu .
Pentru arborele alaturat cel mai mic nod terminal este doi,iar parintele trei.
In noul arbore ,cel mai mic nod terminal este 6, iar parintele lui 6 este 3.
107
Cel mai mic nod terminal este 8, iar parintele sau este 1.
Cel mai mic nod terminal este 1, iar parintele sau este 5.
108
Pana in acest moment am
memorat arborele prin utilizarea a 2 vectori t si pt. Fiecare dintre ei, are n-1 componente!
Prin logica altgoritmului nodul care ramane este cel mai mare adica nodul n. Acesta este ultimul
memorat in vectorul pt.Prin urmare, daca se cunoaste n sunt suficiente n-2 componente pentru vectorul
pt.
Foarte important! Vectorul t se poate reconstitui doar daca cunoastem vectorul pt. aceasta inseamna
ca un arbore cu n noduri a fost memorat doar printr-un vector cu n-2 componente!
Pentru reconstituirea vectorului t pornim de la pt,vom incepe prin a memora in pt, numarul n, pentru
componenta n-1. vectorul t se reconstituie prin formula:
i{1,2…n-1}
t[i]=min{kk{t[1]=t[2],…t[i-1],pt[i],pt[i+1]…pt[n-1]}}
- daca numarul se gaseste in pt[i],pt[i+1],…pt[n-1] inseamna ca nodul respectiv nu a fost eliminat pana
la pasul i, pentru ca este parinte.
- daca numarul se gaseste in t[1],t[2],…t[i-1] inseamna ca a fost extras la unul din pasii anteriori.
dintre nodurile care nu se gasesc ca mai sus , la pasul i a fost extras nodul minim.
Pasul 2
T={2}
Pt={3 3 5 1 5 4 7,9}
Se alege 6.
Pasul 3.
T={2 6 }
Pt={3 3 5 1 5 4 7,9}
Se alege 3.
109
Programul care urmeaza citeste de la tastatura n si pt, dupa care tipareste vectorul t.
Program puffer;
Var t,pt:array[1..50] of byte;
Var i,j,k,n:byte;
Gasit:boolean;
Begin
Write(`n=`);readln(n);
For i:=1 to n-2 do begin
Write(`pt[`,i,`]=`);readln(pt[i]);
End;
Pt[n-1]:=n;
K:=n;
For i:=1 to n-1 do
Begin
K:=1;
Repeat
Gasit:=false;
For j:=1 to i-1 do
If t[j]=k then
Gasit:=true;
If not gasit
Then
For j:=1 to n-1 do
If pt[j]=k then
gasit: = true;
if gasit then k:=k+1;
until not gasit;
st[i]:=k;
end;
for i:=1 to n-1 do
write(t[i],` `);
end.
Foarte important. Cati arbori cu n noduri exista? Vectorul pt are n-2 componente si
fiecare componenta poate retine valori intre 1 si n. Deci exista n n-2 arbori cu n noduri.
Pornind de la u un arbore ,i se asociaza prin codul lui Puffer un vector cu n-2
componente. Se arata usor ca daca arborii sunt diferiti codificarea lor este diferita. Tot
asa, pornind de la un vector cu n-2 componente, unde fiecare ia valori intr 1 si n se
ajunge la un arbore. Cu alte cuvinte am definit o functie f pe multim,ea arborilor care
ia valori in produsul cartezian:
(1,2,…n)*(1,2,…n)*…(1,2,…n)
Din cele aratate rezulta ca f este bijectiva. Prin urmare tinand cont de faptul ca functia
este definita pe o multime finita,numarul de elemente al codomeniului este egal cu
numarul de elemente al domeniului de definitie. Aceasta explica modul in care a fost
determinat numarul de arbori
Codul lui pruffer asociaza acelasi cod arborelui indiferent de reprezntarea grafica
folosita.
110
Arbori
Arbori binari
Definitie
Un arbore cu propietatea ca fiecare nod cu exceptia frunzelor , are cel mult doi descendenti
(succesori )
se numeste arbore binar.
Intr-un arbore binar ,cei doi succesori ai unui nod (daca exista), se numeste succesor stang
respectiv arbore drept.
Definitie
Un arbore cu propietatea ca fiecare nod ,cu exceptia frunzelor , are exact doi descendenti
(succesori) se numeste arbore binar complet .
Notiunea de arborescenta
Definitie. Fiind date doua noduri i si j ale unui graf orientat, se spune ca exista un lant de la i la j daca
exista o succesiune de arce, indiferent de sensul lor prin care cele doua noduri sunt unite.
Daca exista un lant de de la i la j, exista si unul de la j la i.
111
Definitie. Un graf orientat G=(x,) exte conex daca ijx
exista un lant de la i la j.
Daca un graf orientat este tare conex, atunci el este conex, dar reciproca nu este
adevarata. Graful de mai sus este conex.
Definitie. Un graf orientat admite un ciclu daca exista un mod i, pentru care exista un lant de la i
la i.
Definitie. Un graf orientat este arbore daca nu este conex si nu admite cicluri.
Exemple:
Definitie. Un graf orentat g=(x,) admite o radacina vx daca pentru orice xx-(v) exista un drum
(atnete, nu lant) de la v la x.
Exemple:
112
Definitie. Se numeste arborescenta un graf orientat care indeplineste simultant doua conditii :
1.Este arbore;
2.Admite radacina.
Intr-o arborestenta radacina este unica. Daca de exemplu exista doua radacini v 1 si v2 atunci exista
drum de la v1 la v2 si de la v2 la v1. aceasta presupune existenta unui ciclu, deci nu este arbore.
De regula, atunci cand se da o arborescenta se preciaza radacina sa.
Se observa ca din radacina pleaca arce, nu intra. Daca ar si intra s-ar obtine un ciclu.
de asemenea, orice nod are un singur predecesor. Daca, prin absurd, ar avea doi sau mai multi, s-ar
obtine un ciclu care include radacina.
Problema. Se citeste un graf orientat. Acesta este dat prin matricea de adiacenta.se cere ca programul
dv. sa decida daca graful este sau nu oarborescenta. In caz afirmativ, se va tipari radacina acesteia.
113
Rezolvare.
1. Tebuie decis mai intai daca graful orientat este arbore. Acesta se face printr-o singura
parcurgere in adancime,asemanator cu altgoriymul aplicat in cazul grafurilor orienta.
2. In cazul cand graful este arbore , trebuie vazut daca acesta are o radacina. Se testeaza, pe
rand, fiecare nod daca indeplineste conditia de radacina. Fiecare test se face printr-o
parcurgere in adancime pornind de la nodul respectiv.
114
Programatorii folosesc de multe ori prin abuz de limbaj, termenul de arbore, in loc de arborescenta.
In astfel de cazuri se specifica radacina care se mai numeste si varf si se considera ca sensul arcelor
este implicit,motiv pentru care nu se mai reprezinta grafic.
In cazul in care arborescenta are cel mult doi descendenti, unul stang si unul drept, spunem ca avem
un arbore binar.
Exemplu. Mai jos vedeti o arborescenta cu radacina 1 care este un arbore binar. Alaturat obs. Modul in
care se reprezinta grafic renuntand la sensurile arcelor, care sunt implicite.
115
Se presupune ca nodurile sunt asezate pe mai multe niveluri. Radacina este pe
nivelul 0, descenndentii direci directi ai radacini sunt pe nivelul 1, descendentii directi
ai nodurilor de pe nivelul 1 sunt pe nivelul 2 etc.
Numarul de niveluri mai putin cel al radacinii, ocupate de nodurile grafului,se numeste
adancimea arborelui binar.
Vom face dinstinctie intre descendentul stang si cel drept. De exemplu, arborii de mai
jos sunt considerati dinstincti.
2. Desigur, arborii binari pot fi reprezentati ca orice grf orientat, dar aceasta forma este deosebit
de greoaie in aplicatii. Din acest motiv sunt cu mult mai convenabile reprezentarile pe care le
urmarim in continuare.
116
Un arbore binar poate fi reprezentat cu ajutorul a doi vectori, pe care ii vom numi st (de la stanga ) si dr
(de la dreapta). Pentru fiecare nod i dintre cele n, st[i] retine nr. de ordine al nodului stang subordonat
de i, iar dr[i] retine nr de ordine al nodului drept subordonat de i. Daca nu exista nod subordonat retine
0.
st 2 4 5 0 0 0 0
1 2 3 4 5 6 7
dr 3 0 6 0 7 0 0
Programul va retine doar adresa radacinii (varfului). In aplicatii veti intalni numeroase exemple in acest
sens, motiv pentru care ne oprim aici cu aceasta reprezentare.
Aceasta a mai fost prezentata in cazul arborilor neorientati. Mentionam doar faptul ca aceasta
reprezentare este neconvenabila in majoritatea aplicatiilor.
117
In scopul prelucrarii,este necesar ca nodurile arborelui binar sa fie vizitate. Axista mai multe modalitati
de parcurgere a arborilor binari carer difera prin ordinea de vizitare a nodurilor.
Putem considera ca fiecare nod al arborelui binar subordoneaza un subarbore binar stang si unul drept.
Pe baza acestei observatii putem scrie usor subprograme recursive pentru diverse le modalitati de
pacurgere.
Parcurgerea in inordine – SVD – se se patrcurge mai intai subarborele stang, apoi varful apoi
subarborele drept.
Parcurgerea in preordine – VSD – se parcurge mai intai subarborele stang, apoi subarborele drept.
Parcurgerea in postordine – SD – se parcurge mai intai subarborele stang, apoi subarborele drept, apoi
varful.
Parcurgerea in adancime – a fost studiata pentru grafuri, aici se aplica in particular. Se parcurge
radacina, apoi nodurile de pe nivelul 1,apoi cele de pe nivelul 2 etc.
De exemplu parcurgerea SDV se face pe urmatoarea idee: varful subordoneaza doi subarbori: cel stang
si cel drept. Se trece la subarborele stang, apoi la varf, apoi la subarborele drept. Pentru fiecare
subarbore se repeta rationamentul.
Programul urmator citeste si parcurge in inordine,postordine si preordine un arbore binar. Arborele este
retinut in HEAP. Pentru a marca faptul ca descendentul unui anumit nod lipseste se introduce 0.
118
arb ^.st:=arb; end
arb ^. dr:=arb; end;
end
else arb:=nil begin
end; c:=arb;
writeln(`parcurg svd’);
procedure svd (c:ref); svd( c);
begin
if c<nil writeln(`parcurg vsd’);
then vsd( c);
begin writeln(`parcurg sdv’);
svd(c ^.st); sdv( c);
writeln(c^ .nr); end.
svd(c^ .dr)
124000350700600
Atat pentru introducerea arborelui, cat si pentru parcurgeri s-au utilizat tehnici
Program arbori;
Var n,i,v:integer;
St,dr:array[1..50] of integer;
Procedure sdv(nod:byte);
Begin
If (nod<>0)
Then
Begin
Sdv(st[nod]);
Sdv(dr[nod]);
Writeln(nod);
End;
End;
Pocedure vsd(nod:byte);
Begin
If (nod<>0)
Then
Begin
Writeln(nod);
Vsd(st[nod]);
Vsd(dr[nod]);
End;
End;
Begin
Citire;
Writeln(`svd’0;svd(v);
Writeln( `vsd’);vsd(v);
Writeln(`sdv’);sdv(v);
End.
119
9.1 Definirea bazei de date
SISTEME DE GESTIUNE A BAZELOR DE DATE
9.1.1Aspecte privind organizarea datelor
Organizarea datelor presupune umatoarelor activitati:
-definirea ,structurarea,ordonarea si gruparea in colectii de date;
-stabilirea relatiilor intre date,intre elementele unei colectii de date;
-reprezentarea lor pe un sport informational
Definirea uniu model de date impune precizarea urmatoarelor elemente:
-structurile de date si stabilirea relatiilor intre date;
-operatori;
-restrictii de integritate
Intre date se pot stabili urmatoarele tipuri relatii intre baze de date:
unu la unu ;
unu la mai multi;
multi la multi;
Operatori:citire,inserare,modificare,join etc.
Restrictii de integritate:corectitudinea datelor...
Modele de date:ierarhice,retea,relationale,orientate pe obiect,logice de date.
9.1.2 Baze de date
9.1.2.1 Definirea unei baze de date
Scopul principal al unei baze de date consta in stocarea datelor in vederea satisfacerii facile a cerintelor
utilizatorului,utilizand tehnica de calcul.deci,baza de date apare ca un sistem de
inmagazinare,regasire,actualizare si intretinere a datelor necesare procesului de fundamentare a
deciziei.
Definitia 1.1.2 O baza de date este o colectie structurata de date atasate unui fenomen al
lumii reale pe care incercam sa-l modelam.
Baza de date implica patru componenete:
date
hardware
software
utilizatori
9.1.2.2 Arhitecturi standardizate pentru bazele de date
Pe plan international exista mai multe grupuri specializate in standardizarea conceptelor ce
apar in dezvoltarea bazelor de date,cele mai importante fiind DBTG,CODASYL,ANSI/X3/SPARC,grupul
IMB.
In general ,o arhitectura cuprinde urmatoarele componente :
baza de date propriu-zisa in care se memoreaza colectia de date;
sistemul de gestiune al bazei de date
un dictionar al bazei de date
mijloace hard utilizate
personal implicat:utilizatori finali sau de specialitate,programatori si operatori.
Datele pot fi definite pe trei nivele:
-nivel intern;
-nivel conceptual;
-nivel extern.
9.1.2.3 Limbaje pentru baze de date
1. Limbaje pentru definirea datelor(LDD)
Realizeaza definirea entitatilor si a atributelor acestora prin nume,forma de memorare,lungime.
2.Limbaje pentru manipularea datelor(LMD)
In general,o comanda are urmatoarea structura:
-operatia care poate fi calcul aritmetic sau logic,editare,extragere,manipulare
-criterii de selectie
-mod de acces
-forma de editare.
2. Limbaje pentru controlul datelor(LCD)
120
Se refera la asigurarea confidentialitatii si integritatii datelor,la salvarea informatiei in carzul unor
incidente,la obtinerea unor performante,la rezolvarea unor probleme de concurenta.
9.1.2.4 Avantajele utilizarii bazelor de date
Acestea sunt urmatoarele:
Poate fi redusa redundanta datelor
Se poate evita inconsistenta datelor
Datele pot fi partajate
Se poate obtine standardizarea
Se pot aplica restrictii de securitate a datelor
Poate fi mentinuta integritatea datelor prin existenta unor proceduri de validare ,unor protocoale de
control concurent a unor proceduri de refacere a bazei de date dupa incidente
Pot fi echilibrate cerintele conflictuale
Intr-o baza de date nu se doreste ca aplicatiile sa fie deperndente de date din motivele :
-diferite aplicatii au nevoie de viziuni diferite ale acelorasi date
-administratorul bazei de date trebuie sa aiba sa schimbe structura de memorare sau strategia de acces
fara sa modifice aplicatii existente.
9.1.3 SISTEMUL DE GESTIUNE A BAZEI DE DATE(SGBD)
9.1.3.1 Definirea sistemului de gestiune a bazei de date
Definitia 1.1.3 Sistemul de gestiune a bazei de date reprezinta softwar-ul care asigura realizarea
urmatoarelor activitati:
-definirea structurii bazei de date
-incaracrea datelor in baze de date
-accesul la date
-intretinea bazei de date
-reorganizarea bazei de date
-securitatea datelor
9.1.3.2 Obiectivele unui sistem de gestiune a bazelor de date
1. Asigurarea independentei datelor
Aceasta trebuie privita din doua puncte de vedere:
-independenta fizica
-independenta logica
2. Asigurarea unei redundante minime si controlate a datelor din baza de date
3. Asigurarea unor facilitati sporite de utilizare a datelor
Aceasta presupune:
-folosira datelor de catre mai multi utilizatori in diferite scopuri;
-accesul cat mai simplu al utilizatorilor la date
-existenta unor limbaje performante de regasire a datelor
-acces multicriterial al sistemului de gestiune
-utilizarea unui limbaj natural
3. Sporire gradului de securitate a datelor
4. Asigurarea integritatii datelor
5. Asigurarea partajabilitatii datelor
121
9.2 Clasificarea bazelor de date (modelul relaţional,
modelul reţea, modelul ierarhic)
Aplicaţiile de tip “bază de date” se referă la acele produse livrate utilizatorului “la cheie” pentru
a-şi rezolva o problemă concretă. Aplicaţiile de tip “bază de date” existente pe piaţa românească se pot
împărţi în trei mari grupe, după finalitatea datelor manevrate:
a. a. baze de date personale;
b. b. baze de date informaţionale;
c. c. baze de date pentru gestiunea economică.
a. Bazele de date “personale” sunt mici colecţii de date care prezintă interes şi sunt manipulate
de un singur utilizator. Câteva exemple tipice sunt următoarele: agendă telefonică, planificarea de
întruniri, evidenţa cărţilor din biblioteca personală. Pentru astfel de utilizări restrânse ale unei baze de
date, se poate folosi aplicaţia Card File disponibilă în pachetul Windows 3.x.
b. Bazele de date de tip informaţional sunt în general caracterizate de un volum foarte mare de
date (informaţii) ce sunt destinate publicului larg. Ele pot fi considerate adevărate “birouri de informaţii”
computerizate. Domeniul de aplicabilitate a acestor baze de date este extrem de diversificat şi face
imposibilă o clasificare.
c. Bazele de date pentru gestiunea economică reprezintă colecţii de date necesare şi utilizate
pentru gestionarea unei întreprinderi. Aplicaţiile cele mai reprezentative care operează cu astfel de baze
de date sunt produsele CIEL.
Pentru a înţelege mai bine cum este alcătuită şi cum funcţionează o bază de date, trebuiesc
specificate câteva noţiuni privind teoria generală a bazelor de date, cu aplicabilitate în arheologie:
Datele dintr-o colecţie de entităţi pot fi unite şi rezumate în moduri
diferite pentru a produce informaţie. Informaţia este o colecţie de date plasată în
context, care poate fi furnizată de către o situaţie sau de alte date.
Pentru a creşte (mării) bazele umane de cunoştinţe mentale memorate,
omul colectează şi memorează date în formă automată. O astfel de colecţie se
numeşte bază de date. Ea reprezintă nu numai date despre entităţi dar şi date
despre relaţiile dintre entităţi. Pe baza aceleaşi structuri funcţionează o bază de
date şi într-un calculator.
Există două forme de baze de date:
a. a. baze de date fizice, care sunt reprezentări pe medii de memorare a
entităţilor, atributelor şi a relaţiilor dintre ele;
b. b. baze de date logice, care reprezintă entităţi, atribute şi relaţiile
independente de modul în care datele şi relaţiile sunt reprezentate şi
memorate într-o bază de date fizică.
Modele de baze de date
Există trei categorii de modele de baze de date:
1. 1. modelul relaţional;
2. 2. modelul reţea;
3. 3. modelul arborescent (ierarhic).
9.2 1. Modelul relaţional
Un model relaţional de baze de date cuprinde trei componente principale:
structura datelor prin definirea unor domenii (valori atomice)
şi a relaţiilor “n” (atribute, tupluri, chei primare);
122
integrarea datelor prin impunerea unor restricţii;
prelucrarea datelor prin operaţii din algebra relaţională sau
calcul relaţional.
Modelul relaţional se bazează pe noţiunea matematică de relaţie (din
teoria mulţimilor) definită ca o submulţime a produsului cartezian a unei liste
finite de mulţimi numite domenii. Elementele unei relaţii se numesc tupluri (sau
n-cupluri), iar numărul de domenii din produsul cartezian se numeşte arietatea
relaţiei (FOTACHE 1997, 102).
De obicei relaţiile sunt reprezentate sub forma unor tabele în care fiecare
rând reprezintă un tuplu şi fiecare coloană reprezintă valorile tuplurilor dintr-
un domeniu dat al produsului cartezian.
În reprezentarea sub formă de tabel a unei relaţii, coloanelor şi
domeniilor corespunzătoare lor, li se asociază nume intitulate atribute. Mulţimea
numelor atributelor unei relaţii se numeşte schemă relaţională.
Deci prin relaţie se înţelege o mulţime de funcţii definite pe o mulţime de
atribute cu valori în reuniunea unor domenii, cu restricţia ca valoarea
corespunzătoare fiecărui atribut să se afle în domeniul asociat acelui atribut.
Se numeşte cheie candidat al unei relaţii R coloana sau mulţimea de
coloane din R pentru care valorile corespunzătoare din oricare două tupluri nu
coincid, deci identifică tuplurile prin relaţia respectivă şi nu conţin strict o
submulţime de coloane cu această proprietate. Pentru fiecare relaţie se alege un
candidat de cheie care se numeşte cheie primară a relaţiei. Tuplurile unei relaţii
nu pot să conţină valoarea nulă în coloane ce aparţin cheii primare. Eventualii
candidaţi de chei diferiţi de cheia primară se numesc chei alternante. Se numeşte
cheie străină o coloană sau o mulţime de coloane a unei relaţii R 1 ale cărei valori,
dacă nu sunt nule, coincid cu valori ale unei chei primare dintr-o relaţie R, nu
neapărat distinctă de R1.
Mulţimea tuturor schemelor relaţionale corespunzătoare unei aplicaţii se
numeşte schema bazei de date relaţionale, iar conţinutul curent al relaţiilor, la un
moment dat, se numeşte bază de date relaţională.
În modelul relaţional, entităţile sunt reprezentate sub formă de relaţii în
care schema relaţională conţine toate atributele entităţii şi fiecare tuplu al
relaţiei corespunde unui element al entităţii.
Cele mai multe cereri ale unui utilizator privesc determinarea unor
informaţii cu anumite proprietăţi, iar răspunsul posibil este o relaţie care descrie
toate elementele cu aceste proprietăţi. Modul de prezentare al răspunsului
depinde de interfaţa dintre DBMS şi utilizator.
Exemplu:
9.2 2. Modelul reţea
Modelul reţea este cel mai apropiat de forma de reprezentare a bazelor de
date sub forma diagramelor entitate-relaţie. Deosebirea constă în faptul că toate
123
relaţiile ce apar pot fi numai binare şi de tipul 1:1 sau 1:N. Această restricţie
permite reprezentarea grafică a unei baze de date de tip reţea sub forma unui
graf direcţionat numit reţea.
Într-o reţea, nodurile corespund entităţilor şi relaţiile sunt reprezentate
prin săgeţi între noduri (de la tată la fiu) şi anume săgeţi simple dacă relaţia este
de tipul 1:1 şi săgeţi duble dacă relaţia este de tipul 1:N.
În modelul reţea, entităţilor le corespund fişiere logice care au drept
câmpuri atributele entităţii şi eventuale câmpuri de legătură pentru relaţii.
Fiecărui element al entităţii îi corespunde o înregistrare logică. Dacă
înregistrările sunt identificate numai prin relaţia cu alte entităţi, atunci se mai
adaugă la înregistrarea logică încă un câmp ce cuprinde un număr de ordine
care permite identificarea acestor înregistrări.
Operaţiile cele mai frecvente pentru modelul reţea se împart în două
categorii:
căutarea unor elemente ale unor entităţi cu anumite proprietăţi
sau căutarea unor informaţii prin utilizarea legăturilor între entităţi;
navigarea în reţeaua de date.
9.2 3. Modelul ierarhic
Modelul ierarhic (arborescent) este considerat un caz particular al
modelului reţea, în care diagrama asociată este o pădure (mulţime de arbori) şi în
care toate legăturile sunt pe direcţia drumului, de la rădăcină la nodul fiu din
relaţie, toate relaţiile fiind de tipul 1:N.
La fel ca în cazul celorlalte două modele, există posibilitatea interpretării
diagramelor entitate-relaţie sub forma modelului ierarhic. Pentru evitarea
redundanţelor în modelul ierarhic, se foloseşte noţiunea de element virtual, care
înlocuieşte dublura unui element prin adresa elementului respectiv, fiecare
element apărând în baza de date reală o singură dată.
Operaţiile din bazele de date de tip ierarhic se traduc în procese de
parcurgere a arborilor. Elementele virtuale permit legarea informaţiilor din
aceeaşi entitate sau din entităţi diferite.
Implementarea la nivel logic pentru modelul ierarhic poate fi cea utilizată
pentru modelul reţea sau prin înregistrări de lungime variabilă.
Datele sunt stocate pe mediul extern în ordinea dată de parcurgerea în
preordine a arborilor, ceea ce uşurează determinarea informaţiilor pentru
cererile care se referă la descendenţii unor noduri printr-un număr mic de
accese la mediul extern.
124
se informaţiile redundante. Este permis accesul simultan la aceleaşi date, situate în acelaşi loc sau
distribuite spaţial, a mai multor persoane prin mai multe tipuri de interogări (BÂSCĂ 1997, 11; DESPI &
1999, 2).
O bază de date poate fi:
integrată;
partajată.
Prin “integrată” înţelegem că baza de date poate fi gândită ca o unificare de mai multe fişiere
de date, distincte şi neredundante.
Prin “partajarea” unei baze de date se înţelege că bucăţile individuale de date
din baza de date pot fi partajate între mai mulţi utilizatori individuali, fiecare dintre ei
putând avea acces la aceeaşi bucată de date simultan (sisteme multiutilizator).
Hardul unui sistem de baze de date constă din volumele de memorare secundare (discuri,
dischete sau benzi magnetice) pe care rezidă baza de date, împreună cu aparatele, unităţile de control
şi canalele respective.
Între baza de date fizică (adică datele aşa cum sunt ele memorate pe suport) şi utilizatorii
sistemului există un nivel de software, numit sistem de gestionare a bazelor de date (DBMS – Data
Base Management System), care permite construirea unor baze de date, introducerea informaţiilor în
baza de date şi dezvoltarea de aplicaţii privind bazele de date.
Un DBMS dă posibilitatea utilizatorului să aibă acces la date folosind un limbaj de nivel înalt,
apropiat de modul obişnuit de exprimare, pentru a obţine informaţii, utilizatorul făcând abstracţie de
algoritmii aplicaţi pentru selectarea datelor implicate şi a modului de memorare a lor. DBMS-ul este deci
o interfaţă între utilizator şi sistemul de operare.
Orice DBMS conţine un limbaj de descriere a datelor (LDD) care permite descrierea structurii
unei baze de date, a fiecărei componente a ei, a relaţiilor dintre componente, a drepturilor de acces ale
utilizatorului la baza de date, a restricţiilor în reprezentarea informaţiilor, etc. LDD-ul este utilizat atât
pentru proiectarea bazelor de date, cât şi pentru redefinirea lor.
O altă componentă a DBMS este limbajul de cereri (LC) sau limbajul de prelucrare a datelor
(LPD), ce permite operaţii asupra datelor aflate în baza de date, cum ar fi:
încărcarea bazei de date;
inserarea unui nou element;
ştergerea unui element;
modificarea unui element;
căutarea unor elemente;
realizarea de diferite statistici asupra datelor.
Limbajele LDD şi LC sunt extinderi ale unor limbaje de programare numite limbaje gazdă.
Compilarea succesiunilor de comenzi pentru descrierea datelor sau pentru operarea cu date se reduce
la transformarea acestor comenzi într-o succesiune de instrucţiuni ale limbajelor gazdă care, prin
executare, să dea efectul dorit. O altă modalitate de operare este aceea a transformării comenzilor în
lansări de programe executabile.
125
Datele operaţionale sunt date din bazele de date, distincte de datele de intrare, ieşire
sau alte tipuri de date. O bază de date este o colecţie de date operaţionale folosite de către
aplicaţiile sistem ale unei instituţii (Muzeu, Bibliotecă, Intreprindere, etc.)
Datele de intrare sunt informaţii introduse în sistem din lumea exterioară, de obicei
prin terminale.
Datele de ieşire se referă la mesajele şi rapoartele extrase din sistem (tipărite sau
afişate pe ecran).
Entităţile de bază sunt elementele constitutive ale unei baze de date (expl. materialul
arheologic, materialul bibliografic, materialul grafic, etc.). Între aceste entităţi există
întotdeauna asociaţii sau relaţii ce le leagă într-o bază de date comună.
Relaţiile dintre entităţi sunt la rândul lor părţi ale datelor operaţionale, chiar mai
importante decât entităţile asociate. O relaţie poate fi asociată la una, două sau trei entităţi, iar
o entitate poate fi asociată la oricâte relaţii.
Independenţa datelor
Modul în care datele sunt organizate pe suportul secundar de stocare şi modul în care
ele sunt accesate depind de cerinţele aplicaţiei şi de ştiinţa organizării datelor şi tehnicile de
acces.
Imunitatea aplicaţiilor la modificările de structură a memorării şi a strategiei de acces
se numeşte independenţă a datelor.
Tipuri de modificări pe care administratorul bazei de date (DBA) poate să le facă:
reprezentarea datelor numerice (câmpul numeric poate fi memorat în formă
internă aritmetică sau ca un şir de caractere);
reprezentarea datelor caracter (un câmp şir de caractere poate fi memorat în
mai multe coduri de caractere : ASCII, EBCDIC, etc.).
Terminologie:
Un câmp este cea mai mică unitate de date stocată în baza de date.
Baza de date conţine mai multe ocurenţe sau instanţe pentru fiecare din
tipurile de câmpuri.
O înregistrare este o colecţie de nume de câmpuri asociate.
O ocurenţă sau instanţă de înregistrare constă dintr-un grup de ocurenţe de
câmp înrudite (asociate) şi reprezintă o asociere între ele.
Un fişier este o colecţie a tuturor înregistrărilor de unul sau mai multe tipuri.
Într-o bază de date, un câmp numeric poate avea două unităţi metrice (inches
şi centimetrii) la alegerea utilizatorului.
Structura înregistrărilor memorate
Într-o bază de date, două tipuri de înregistrări pot fi combinate într-unul singur.
Exemplu:
înregistrarea 1.: neolitic, Vinča, ceramică pictată, străchini (…)
înregistrarea 2.: neolitic, Petreşti, ceramică pictată, străchini (…)
structură integrată: neolitic, Vinča, Petreşti, ceramică pictată, străchini
(…)
Astfel se explică faptul că înregistrarea logică a unei aplicaţii poate consta dintr-o
submulţime a unei înregistrări memorate, adică anumite câmpuri memorate pot fi invizibile
pentru o aplicaţie particulară (de exemplu elementele care se repetă). La fel, un singur tip de
înregistrare memorată poate fi despicat în două, pentru a particulariza anumite aplicaţii.
Structura fişierelor memorate
Un fişier poate fi implementat fizic în memorie în mai multe moduri:
126
poate fi în întregime conţinut într-un volum de memorare (expl.: disc
magnetic);
poate fi împărţit pe mai multe volume de tipuri diferite;
poate fi sau nu fizic secvenţial, în concordanţă cu valorile unui anumit câmp;
poate avea unul sau mai mulţi indecşi asociaţi;
poate fi construit cu pointeri;
înregistrările pot fi blocate sau nu, etc.
Baza de date trebuie să fie în stare să crească fără a afecta aplicaţiile existente,
aceasta fiind raţiunea majoră a independenţei datelor.
Arhitectura unui sistem de baze de date
a. a. nivelul exterior scheme exterioare
(vederile utilizatorilor
individuali)
127
Schema externă este scrisă într-un sublimbaj de definire a datelor (SLDD) dintr-un DLL numit
adesea DLL extern.
Scheme conceptuale
O schemă conceptuală este o reprezentare a întregii informaţii conţinute în
baza de date ce combină subschemele vederilor ce privesc o anumită aplicaţie într-un
model unitar. Acest tip de schemă trebuie să se bazeze pe un model teoretic şi să fie
simplă, adică uşor de înţeles şi de prelucrat.
Sistemele de gestiune a bazelor de date au fost clasificate în trei grupe mari,
în funcţie de tipul elementelor cu care lucrează şi a structurilor obţinute:
a. a. modelul reţea – permite lucrul cu entităţi şi relaţii binare de tipul 1:1 şi 1:N,
diagrama rezultată fiind un graf oarecare;
b. b. modelul arborescent (ierarhic) – permite lucrul cu entităţi şi relaţii binare de
tipul 1:1 şi 1:N, iar diagrama este alcătuită dintr-o mulţime de arbori;
c. c. modelul relaţional – în care intervin numai relaţii şi operaţii cu aceste relaţii.
Scheme interne
Schemele interne descriu diferitele fişiere utilizate pentru memorarea
informaţiilor bazei de date şi modul de operare cu ele. Există mai multe moduri de
organizare a fişierelor, cele mai cunoscute fiind:
organizarea secvenţială;
organizarea cu index rar;
organizarea cu index dens;
organizarea cu dispersie;
organizarea folosind B-arbori.
Traducerea schemelor conceptuale în scheme interne se face, de obicei,
automat de către DBMS. Pe lângă stabilirea diferitelor tipuri de înregistrări utilizate
în reprezentarea fizică a datelor, se specifică şi existenţa indecşilor asociaţi unor
fişiere, semnificaţia câmpurilor înregistrărilor, ordinea de apariţie a înregistrărilor şi
modul de acces.
Corespondenţa dintre scheme poartă numele de mapare şi este de două tipuri:
mapare conceptuală / internă (vederea conceptuală / baza de date memorată);
mapare externă / conceptuală (vedere externă particulară / vedere
conceptuală).
Sistemul de gestiune a bazelor de date (DBMS) este softul (programul) care
coordonează toate accesele la baza de date, în modul următor:
a. a. un utilizator emite o cerere de acces, folosind un limbaj particular de
manipulare a datelor;
b. b. DBMS-ul interceptează cererea şi o interpretează;
c. c. DBMS-ul inspectează, pe rând, schema externă, maparea
externă/conceptuală, schema conceptuală, maparea conceptuală/internă şi
definiţia de structură de memorare;
d. d. DBMS-ul realizează operaţiile necesare asupra bazei de date memorate.
Administratorul bazei de date (DBA) urmează apoi să gestioneze operaţiile
specifice, responsabilităţile lui incluzând:
decizia asupra conţinutului informaţiei inclusă în baza de date;
decizia asupra structurii de memorare şi a structurii de acces;
legătura cu utilizatorii;
definirea procedurilor de verificări autorizate şi de validări;
128
definirea unei strategii pentru salvări şi restaurări;
monitorizarea performanţei şi răspunsuri la schimbări de cerinţe.
Pentru aceasta DBA are la îndemână un număr de programe utilitare pentru a
se ajuta în rezolvarea acestor sarcini:
rutina de încărcare (pentru a crea versiunea iniţială a bazei de date);
rutina de reorganizare (pentru a reorganiza baza de date prin eliminarea
datelor perimate şi introducerea altora noi);
rutine jurnaliere (pentru a nota orice operaţie asupra bazei de date împreună
cu identificarea utilizatorului care a efectuat-o);
rutine de restaurare (pentru a restaura baza de date la o stare anterioară unui
eşec hard sau de programare);
rutina de analiză statistică (pentru a sista în realizarea performanţei).
Instrumentul utilizat de DBA în lucrul cu programele utilitare este dicţionarul
de date. El este o bază de date ce conţine date despre date, adică descrieri ale
obiectelor sistemului.
De asemenea atât DBA cât şi utilizatorul beneficiază de o interfaţă utilizator
pentru a uşura accesul la date. Această interfaţă poate fi definită ca un ecran în sistem,
sub care totul devine invizibil pentru utilizator. Interfaţa se află întotdeauna la nivelul
extern.
Într-un sistem de baze de date (DBMS) datele sunt memorate la locaţia la care sunt folosite
mai des, dar ele sunt disponibile (prin reţeaua de comunicaţii) şi utilizatorilor din alte locaţii. Acest tip de
bază de date, împrăştiată într-o reţea de calculatoare se numeşte bază de date distribuite.
STRUCTURA RELATIONALA A DATELOR
129
nume de atribut ii corespunde un domeniu Di numit domeniu numit domeniul atributului Ai ,1 in si se
va nota cu dom(Ai) .Pt a diferentia coloanele care contin valori ale aceluiasi domeniu si a elimina astfel
dependenta de pozitie in cadrul tabelei , se asociaza fiecarei coloane un nume distinct.
Pentru tabelul din figura 2.2.1 avem atributele NR,PD,PA,OD,OA si domeniile asociate
dom(NR), dom(PD), dom (PA), dom (OD),dom (OA).
De exemplu , dom (PD) ={Bucuresti ,Craiova,Timisoara}.
Fie D1 , D2 , …,Dn domenii finite , nu neaparat disjuncte.Produsul cartezian D1xD2x…xDn
al acestora este definit de multimea tuplurilor <v1,v2,…, vn> unde v1єD1,v2єD2,…,vn єDn. Numarul n
defineste aritatea tuplului.
Definitia 2.2.2 O relatie r pe multimile D1,D2,…,Dn este o submultime a produsului
cartezian D1x D2 x … Dn , deci o multime de tupluri.
Exista si un alt mod de a defini o relatie, si anume , ca o multime finita de functii. Asociem
fiecarui domeniu Di un atribut Ai si definim relatia r ca fiind o multime de tupluri {t1,t2,… ,tn} , unde ti :
{A1, A2, … ,An} - D1 D2 … Dn si ti (A j) єDj pentru orice valori ale lui i si j .Intr-o relatie ,
tuplurile trebuie sa fie distincte (nu se admit duplicari ale tuplurilor). De obicei ,vom nota relatia cu r sau
r{A1,A2, … , An} .
Orarul din figura 2.2.1 reprezinta un exemplu de relatie pe care o vom numi orar.Continutul
informational al liniei nu depinde de ordinea coloanelor , de exemplu coloanele PS si PA pot fi
interschimbate.
Definirea unei relatii ca o multime de tupluri sau ca o multime de functii se refera la
multimi care variaza in timp (se adauga , se sterg, sau se modifica elemente).Pentru a caracteriza o
relatie este nevoie de un element invariant in timp , iar acest invariant este dat de structura relatiei
(schema relatiei).
Definitia 2.2.3 Multimea tuturor atributelor R={A 1, A2 , … , An}corespunzatoare unei
relatii o numim schema relatiei si o notam r(A1 , A2 , … , An) .
Schema relatiei orar se defineste astfel: orar (NR,PD,PA,OD,OA).
Schema unei relatii mai este cunoscuta si sub numele de intensia unei relatii , ca expresie a
proprietetilor comune si invariante ale tuplurilor care compun relatia .Spre deosebire de intensie ,
extensia unei relatii reprezinta multimea tuplurilor care compun la un moment relatia , multime care este
variabila in timp . De obicei , extensia unei relatii este stocata fizic in spatiul asociat bazei de date , caz
in care relatia se numeste relatie de baza .Exista situatii in care extensia nu este memorata in baza de
date . Este cazul asa numitelor relatii virtuale , cunoscute si sub numele de relatii derivate sau viziuni.
Acestea sunt definite implicit , pe baza altor relatii , prin intrmediul unei expresii relationale iar stabilirea
tuplurilor care o compun se face prin evaluarea expresiei.
Asadar , putem reprezenta o relatie printr-un tabel bidimensional in care fiecare linie
corespunde unui tuplu si fiecare coloana corespunde unui domenui din produsul cartezian. Numarul
atributelor defineste gradul relatiei , iar numarul de tupluri cardinalitatea relatiei .
Fiecare linie a relatiei este o multime de valori , cate una pentru fiecare nume de
atribut .Linia relatiei se numeste tuplu. In figura 2.2.1 relatia orar este formata din 5 tupluri . Unul dintre
acestea , notat cu t , este definit astfel:
t(NR)=75 , t(PD) = Craiova , t(PA)=Bucuresti,t(OD)=7.25, t(OA)=8.25
Valoarea concreta a tuplului t pentru atributul A o numim Avaloarea tuplului t , iar daca t
este considerata ca functie , atunci Avaloarea tuplului o vom nota cu t(a). Pentru X R, restrictia
tuplului t la X o notam cu t/X sau t(X) si o vom numi Xvaloarea tuplului t .
Pentru relatia orar , consideram un tuplu t oarecare , de exemplu primul tuplu din relatie .
{PD , PA} – valoarea tuplului t este tuplul t’ pentru care t’(PD)=Bucuresti, t’(PA)= Craiova.
130
Fie relatiile r(X,Y), s(X,Z) si X,Y,Z multimi de atribute , XZφ.Prin join-ul natural al
relatiilor r si s se intelege :
r⊲⊳s={(x(t),y(t),z(v)) t r, v s,y(t)=y(v)}
O relatie r se poate descompune in mai multe relatii noi : r1 ,r2 ,…,rm.Aceasta
descompunere este corecta , daca : r= r 1⊲⊳r2 ⊲⊳… ⊲⊳rm.
Vom da un exemplu de descompunere care nu este corecta .Fie relatiile :
r[NUME,VARSTA,SALARIU,LOCALITATE]
r1[NUME,SALARIU]
r2[VARSTA,SALARIU,LOCALITATE].
si presupunem ca pt r avem urmatoarea extensie:
NUME VARSTA SALARIU LOCALITATE
NUME SALARIU
Ionescu 800000
Popescu 1200000
Georgescu 1500000120000
Calinescu 0
r2
VARSTA SALARIU LOCALITATE
30 800000 Arad
40 1200000 Oradea
60 1500000 Iasi
25 1200000 Arad
r1 ⊲⊳r2
NUME VARST SALARIU LOCALITATEA
A
Ionescu 30 800000 Arad
Popescu 40 1200000 Oradea
Popescu 40 1200000 Arad
Avram 60 1500000 Iasi
Calinescu 25 1200000 Arad
Calinescu 25 1200000 Oradea
Este posibil , ca in diverse aplicatii sa apara atribute (simple sau compuse), ce au mai
multe valori pt un element din relatie.Aceste atribute formeaza un atribut repetitiv .Prin atribut simplu
vom intelege un singur atribut din relate, iar prin atribut compus o multime de atribute (cel putin doua).
Consideram , de exemplu relatia :
131
persoana[NUME,AN-NASTERE,PROFESIA,NUME-COPIL,AN-NASTERE-COPIL] cu
atributul NUME cheie primara.Perechea {NUME-COPLI,AN-NASTERE-COPIL}este un grup repetitiv ,
deoarece relatia poate avea urmatoarea extensie:
Popa 1970 inginer Daniel 1992
Anca 1994
Viorel 1998
Ionescu 1966 economist Andrei 1989
Magda 1993
De asemenea, relatia:
carte [COTA,AUTOR,TITLU,EDITURA,AN-APARITIE,CUVINTE-CHIE]cu atributul cheie
COTA cheie primara , are atributele respective AUTOR si CUVINTE-CHEIE.Ocarte poate avea mai
multi autori si mai multe cuvinte cheie.
Grupele de atribute repetitive creeaza greutati in memorarea diverselor relatii si de aceea
se incearca emiterea lor,fara apierde insa din informatii.Daca r[A1, …,An]este o relatie , unde Am+1 ,
…,An formeaza un grup repetitiv , atunci relatia r se poate descompune in doua relatii fara atribute
repetitive .Daca A1`,…,Ap, p<m , este o cheie pt relatia r atunci cele doua relatii in care se descompune
r sunt:
r′[A1,A2,…,Am]=A1,…,Ap,Am+1,..,An(r)
r″[A1,A2,…,Ap,Am+1,…,An]=A1,…,Ap,Am+1,…,An (r)
132
Daca depndenta functionala DISCIPLINAPROFESOR nu este respectata , atunci poate
apare o inconsistenta .Fie doua elemente din relatie:
T …DISCIPLINA … PROFESOR
……………………………………
t1 …ANALIZA … POPA
t2 …ANALIZA … POPA
……………………………………..
133
X Y A-X-Y
t1 v u1 w1
t2 v u2 w2
t3 v u1 w2
t4 v u2 w1
COTA AUTOR
1 Popescu I.
1 Slavici I.
2 Tudor P.
2 Ioan S.
2 Vigu T.
COTA CUVANT-
CHEIE
1 Rom
1 Roman
2 Bdate
2 Rom
Definitia 2.2.15 Fie relatia r [A1, A2, …, An]si r1[x1],…,rm[xm] o descompunere a relatiei r
. Relatia r satisface dependenta join notata *(r1,…,rm) , daca r = r1 ⊲ ⊳ r2 ⊲ ⊳ … ⊲⊳rm .Daca
una din relatiile ri este egala cu r , atunci aceasta dependenta este triviala.
Sa consideram o relatie r si o dependenta join*(r1,r2) , unde r1[X],r2[Y] sunt relatii . Cu
aceste presupuneri , avem : r = r1⊲⊳r2 .
134
Fie t1, t2 r si valotile lor date prin urmatorul tabel:
X-Y XY Y-X
x(t1) u1 V ….
x(t2) u2 V ….
………………………………………….
y(t1) …… V w1
y(t2) …… V w2
Daca se calculeaza r1⊲⊳r2 , care este egala cu r , rezulta faptul ca mai avem doua
elemente t3 si t4 din r cu valorile urmatoare:
X-Y XY Y-X
t1 u1 v
t2 w1
u2 v
t3 w2
t4 …………………………………
………………
u1 v
w1
u2 v
w2
De aici , se deduce ca XYX sau XY Y , deci dependenta join*(r1,..,rm) este
echivalenta cu dependenta functionala multipla.
Definitia 2.2.16 [5] O relatie este in forma normala cinci (FN 5) cu respectarea unei multimi
D de dependente functionale multiple sau join , daca fiecare dependenta *(r1 ,…,rm) este fie triviala , fie
Xi este cheie (avem ri[Xi])pt r , pt toate valorile lui i.
Cu alte cuvinte , o relatie r este in FN5 daca orice dependenta join definita pe r este
implicata de cheile candidat ale lui r.
Exemplul 2.2.10 Fie relatia cursa [CP#,CA#,PD,PA], unde CP-codul pilotului , CA-codul
avionului, PD si PA punctul de decolare , respectiv aterizare.
In aceasta relatie , care este in FN4 , nu exista dependente functionale multiple, dar exista
o redundanta logica , care va ridica probleme la actualizare.
cursa
C C PA PD
P# A#
1 1 Sibiu Iasi
1 00 Iasi Sibiu
1 1 Sibiu Iasi
0 00 Sibiu Iasi
1 1
0 00
1 1
0 01
135
r1
CP CA#
#
11 100
10 100
10 101
r2
C PD PA
P#
1 Sibiu Iasi
1 Iasi Sibiu
1 Sibiu Iasi
0
1
0
r3
C PD PA
A#
1 Sibiu Iasi
00 Iasi Sibiu
1 Sibiu Iasi
00
1
01
r1⊲⊳r2
C C PD PA
P# A#
1 1 Sibiu Iasi
1 00 Iasi Sibiu
1 1 Sibiu Iasi
0 00 Iasi Sibiu
1 1 Sibiu Iasi
0 00
1 1
0 01
1 1
0 01
136
In obtinerea unei baze de date performanta , un rol important il are tehnica normalizarii
relatiilor .Aceasta tehnica permite obtinerea schemei conceptuale printr-un proces de ameliorare
progresiva a unei scheme concepute initial,prin utilizarea formelor normale.Dupa fiecare etapa de
ameliorare , relatiile din baza ating un anumit grad de perfectiune , prin eliminarea unui anumit tip de
dependente nedorite (dependente functionale partiale,tranzitive,multivaloare), deci se afla intr-o anumita
forma normala.
Procesul de ameliorare , trebuie sa satisfaca urmatoarele cerinte:
sa garanteze conservarea datelor , adica in schema conceptuala finala trebuie sa figureze
toate datele din schema initiala;
sa garanteze conservarea dependentelor dintre date, adica in schema finala fiecare
dependenta trebuie sa aiba determinantul si determinatul in schema aceleiasi relatii;
sa reprezinte o descompunere minimala a relatiilor initiale.Nici una din relatiile care compun
schema finala nu trebuie sa fie continuta intr-o alta relatie din aceasta schema .
Necesitatea normalizarii este ilustrata in exemplul urmator.
Fie schema relationala avion(NR,TIP,CAPACITATE,LOCALITATE), cu cheia primara
numarul avionului (NR).
avion
N TIP CAPACITATE LOCALITATE
R
1 IAR500 90 Brasov
00 IAR500 90 Arad
1 ROMBAC 100 Bucuresti
01 TU154 200 Timisoara
1
02
1
03
Presupunem ca in cadrul companiei , exista restrictia : “toate avioanele de acelasi tip au
aceeasi capacitate” care este de fapt o dependenta functionala de forma TIPCAPACITATE .
Datorita acestei dependente , pot exista redundante in date sau pot sa apara anomalii la
reactualizare.Astfel , in relatia de mai sus , avem o redundanta logica (perechea <IAR 500 ,90>apare de
mai multe ori)precum si anomalii l areactualizare : daca dorim sa stergem avionul cu nr 102 , vom
pierde informatia care ne arata ca un avion ROMBAC are capacitatea 100.
De asemenea , daca dorim sa modificam capacitatea avionului IAR 500 , de la 90 la 190
de locuri putem intalni urmatoarele anomalii: modificand un singur tuplu,relatia devine incoerenta
(restrictia nu mai este verificata), iar daca modificam toate tuplurile cu IAR 500 , costul modificarii creste
semnificativ.
Prezentam in continuare procedeul de ameliorare a schemei conceptuale initiale , care
consta in aducerea acesteia la diferite forme normale([4]).
Aducerea relatiilor la FN1
Presupune eliminarea atributelor compuse si a celor repetitive.Aducerea unei relatii in FN1 se
realizeaza atfel:
1.Se trec in relatie , in locul atributelor compuse componentele acestora , ca atribute simple.
137
fi formata din atributul/atributele din determinantul dependentei functiona-
le partiale,care a stat la baza constituirii relatiei.
4.Se analizeaza relatiile rezultate la pasul 1.Daca aceste relatii contin depen-
dente functionale partiale se reia procesul de aducere in FN2,astfel procesu
s-a terminat.
Aducerea relatiilor in FN3
Presupune aducera unei relatii in FN2 in FN3 prin aliminarea dependente-
lor tranzitive.
1.Pentru fiecare dependenta functionala tranzitiva se transfera atributele implicate in
dependenta tranzitiva intr-o noua relatie.
2.Se determina cheia primara a fiecarei noi relatii creata la pasul 1.
3.Se introduc in relatia initiala in locul atributelor transferate,cheile primare determinate
la pasul2.
4.Se reanalizeaza relatia initiala .Daca in cadrul ei exista noi dependente
tranzitive,atunci se face transfer la pasul1,altfel procesul de aducere la FN3
s-a terminat.
A treia forma normala poate fi obtinuta si cu ajutorul unei scheme sinteza
([8],[9]).Algoritmul de sinteza construieste o acoperire minimala F+ a depen-
dentelor functionale totale.Se elimina atributele si dependentele functionale
redundante.Multimea F este partitionata in grupuri Fi,astfel incat in fiecare
grupa Fisunt dependente functionale care au acelasi membru stang si nu esxis
ta doua grupuri cu acelasi membru stang.Fiecare grup Fi produce o schema
FN3.Algoritmul realizeaza o descompunere ce conserva dependentele.
Vom ilustra algoritmul pe un exemplu.Fie A1.A2,…,Am o multime de atribute
Si fie E o multime de dependente functionale f1,f2,fn de forma fi:xi->yj,unde
Xi=Ai1,Ai2,Aik si Yj=Aj1,Aj2,…,Aj
Modelul relational al datelor a fost acceptat aproape fara rezerve de atat specialistii din domeniu bazelor
de date cat si de utilizatori ,inca de la aparitia primului articol al lui Codd E. F. [1] , prin care erau puse
bazele acestui model asamblist al datelor a fost lansata de catre Childs D.F. in 1968 ,care a subliniat
faptul ca orice structura de date poate fi reprezentata printr-una sau mai multe tabele de date , in cadrul
carora este necesar sa existe informatii de legatura , in vederea stabilirii unor legaturi intre acestea.
S-a constatat ca, prin utilizarea sistemelor relationale este posibila atingerea unor obiective importante
ale organizarii datelor in comparatie cu modelele ierarhice si retea [2]:
1. Asigurare unui grad sporit de independenta a programelor de aplicatie fata de modul de
reprezentare interna a datelor si metodele de acces la date.In precizarea prelucrarilor asupra
datelor ,programele nu fac apel la pointeri sau alte elemente ale schemei interne a bazei de date .
2. Furnizarea unor metode si tehnici eficiente de control a coerentei si redundantei
datelor .Modelul relational ,prin tehnica normalizarii relatiilor permite definirea unei structuri conceptuale
optime a datelor , prin care se minimizeaza riscurile de eroare la actualizare, reducandu-se redundanta
datelor.
3. Oferirea unor facilitati multiple de definire si manipulare a datelor.In primul rand modelul
relational ofera posibilitatea utilizarii unor limbaje procedurale ,bazate pe algebra relationala ,precum si
a unor limbaje neprocedurale ce au la baza calculul relational.
138
4. Ameliorarea integritatii si confidentialitatii datelor.Modelul relational realizeaza acest lucru prin
mecanisme flexibile si eficace de specificare si utilizare a restrictiilor de integritate si a relatiilor virtuale.
Componentele modelului relational sunt: structura relationala a datelor, prin care datele sunt organizate
sub forma unor tablouri bidimensionale (tabele ) de date , numite relatii, operatorii modelului relational ,
ce definesc operatiile care se pot efectua asupra relatiilor ,in scopul realizarii functiilor de prelucrare
asupra bazei de date ,respectiv consultarea ,inserarea,modificarea si stergerea datelor ,precum si
restrictiilede integritate care permit definirea starilor coerente ale bazei de date.
1.1.1 SRUCTURA RELATIONALA A DATELOR
Prezentarea sructurii relationale a datelor impune definirea notiunilor de domeniu , atribut , relatie si
schema a unei relatii [6].
In figura 2.2.1 se prezinta un model relational ce corespunde unei multimi concrete de caracteristici
despre lumea reala .Orarul de zbor al avioanelor poseda o sructura de date relationala .Pentru fiecare
linie aeriana din orarul de zbor sunt date caracteristicile :numarul cursei, aeroportul de decolare,
aeroportul de aterizare, ora decolarii, ora aterizarii.
Fiecare avion este determinat de multimea valorilor de fiecare linie.Trebuie sa ne limitam numai la
actele date care pot sa apara in definirea coloanei.Coloana cu numele ,Punct de decolare(PD) contine
numele aeroporturilor liniilor aeriene considerate.Coloana Ora decolarii (OD) (respectiv, Ora aterizarii
(OA))exprima ora la care are loc decolarea (respectiv , aterizarea).Coloana cu numele Punct de
aterizare (PA) contine numele aeroportului unde se aterizeaza.
Nr zbor(nr) Punct de Punct de aterizare(pa) Ora de decolare(Od) Ora de aterizare(oa)
decolare(Pd)
70 Bucuresti Craiova 16:59 17:50
75 Craiova Bucuresti 07:25 08:25
80 Bucuresti Timisoara 17:30 19:30
85 Timisoara Bucuresti 07:15 09:25
90 Timisoara Craiova 10:15 13:20
Definitia 2.2.1 Domeniul reprezinta o multime de valori ,caracterizat printr-un nume si este definit fie
explicit prin enumerarea tuturor componentelor sale,fie printr-o proprietate distinctiva a valorilor din
domeniul respectiv.
Penrtu tabelul din figura 2.2.1 se pot da urmatoarele exemple:
D1={Bucuresti,Craiova,Timisoara}
D2={x / xєN , xє[1,100]}
Atributul reprezinta coloana unei tabele de date , caracterizata printr-un nume. Numele coloanei
(atributului ) exprima de obicei semnificatia valorilor din cadrul coloanei respective .Fiecarui nume de
atribut ii corespunde un domeniu Di numit domeniu numit domeniul atributului Ai ,1in si se va nota cu
dom(Ai) .Pt a diferentia coloanele care contin valori ale aceluiasi domeniu si a elimina astfel dependenta
de pozitie in cadrul tabelei , se asociaza fiecarei coloane un nume distinct.
Pentru tabelul din figura 2.2.1 avem atributele NR,PD,PA,OD,OA si domeniile asociate dom(NR),
dom(PD), dom (PA), dom (OD),dom (OA).
De exemplu , dom (PD) ={Bucuresti ,Craiova,Timisoara}.
Fie D1 , D2 , …,Dn domenii finite , nu neaparat disjuncte.Produsul cartezian D1xD2x…xDn al
acestora este definit de multimea tuplurilor <v1,v2,…, vn> unde v1єD1,v2єD2,…,vn єDn. Numarul n
defineste aritatea tuplului.
Definitia 2.2.2 O relatie r pe multimile D1,D2,…,Dn este o submultime a produsului cartezian D1x
D2 x … Dn , deci o multime de tupluri.
Exista si un alt mod de a defini o relatie, si anume , ca o multime finita de functii. Asociem fiecarui
domeniu Di un atribut Ai si definim relatia r ca fiind o multime de tupluri {t1,t2,… ,tn} , unde ti : {A1, A2,
… ,An} - D1 D2 … Dn si ti (A j) єDj pentru orice valori ale lui i si j .Intr-o relatie , tuplurile trebuie
sa fie distincte (nu se admit duplicari ale tuplurilor). De obicei ,vom nota relatia cu r sau r{A1,A2, … , An}
.
Orarul din figura 2.2.1 reprezinta un exemplu de relatie pe care o vom numi orar.Continutul
informational al liniei nu depinde de ordinea coloanelor , de exemplu coloanele PS si PA pot fi
interschimbate.
Definirea unei relatii ca o multime de tupluri sau ca o multime de functii se refera la multimi care
variaza in timp (se adauga , se sterg, sau se modifica elemente).Pentru a caracteriza o relatie este
nevoie de un element invariant in timp , iar acest invariant este dat de structura relatiei (schema relatiei).
139
Definitia 2.2.3 Multimea tuturor atributelor R={A 1, A2 , … , An}corespunzatoare unei relatii o
numim schema relatiei si o notam r(A1 , A2 , … , An) .
Schema relatiei orar se defineste astfel: orar (NR,PD,PA,OD,OA).
Schema unei relatii mai este cunoscuta si sub numele de intensia unei relatii , ca expresie a
proprietetilor comune si invariante ale tuplurilor care compun relatia .Spre deosebire de intensie ,
extensia unei relatii reprezinta multimea tuplurilor care compun la un moment relatia , multime care este
variabila in timp . De obicei , extensia unei relatii este stocata fizic in spatiul asociat bazei de date , caz
in care relatia se numeste relatie de baza .Exista situatii in care extensia nu este memorata in baza de
date . Este cazul asa numitelor relatii virtuale , cunoscute si sub numele de relatii derivate sau viziuni.
Acestea sunt definite implicit , pe baza altor relatii , prin intrmediul unei expresii relationale iar stabilirea
tuplurilor care o compun se face prin evaluarea expresiei.
Asadar , putem reprezenta o relatie printr-un tabel bidimensional in care fiecare linie corespunde
unui tuplu si fiecare coloana corespunde unui domenui din produsul cartezian. Numarul atributelor
defineste gradul relatiei , iar numarul de tupluri cardinalitatea relatiei .
Fiecare linie a relatiei este o multime de valori , cate una pentru fiecare nume de atribut .Linia
relatiei se numeste tuplu. In figura 2.2.1 relatia orar este formata din 5 tupluri . Unul dintre acestea ,
notat cu t , este definit astfel:
t(NR)=75 , t(PD) = Craiova , t(PA)=Bucuresti,t(OD)=7.25, t(OA)=8.25
Valoarea concreta a tuplului t pentru atributul A o numim Avaloarea tuplului t , iar daca t este
considerata ca functie , atunci Avaloarea tuplului o vom nota cu t(a). Pentru X R, restrictia tuplului t
la X o notam cu t/X sau t(X) si o vom numi Xvaloarea tuplului t .
Pentru relatia orar , consideram un tuplu t oarecare , de exemplu primul tuplu din relatie . {PD ,
PA} – valoarea tuplului t este tuplul t’ pentru care t’(PD)=Bucuresti, t’(PA)= Craiova.
Asupra tuplurilor unei relarii se pot efectua urmatoarele operatii:
Adaugarea. Permite adaugarea de noi tupluri la o relatie .
Astfel , pentru relatia r{A1 , A2 , … , An} operatia are forma :
ADD(r: A1= d1 , A2 = d2 , … ,An = dn)
De exemplu , adaugarea unui tuplu la relatia orar se face astfel:
ADD(orar : NR =99, PD =Oradea , PA = Bucuresti , OD = 20 , OA = 22)
Cand ordinea atributelor este fixata aceasta poate fi scrisa sub forma :
ADD(orar : 99, Oradea , Bucuresti, 20 , 22)
Scopul operatiei de adaugare este de a adauga un tuplu la o anumita relatie r ,dar rezultatul
adaugarii nu este conform cu scopul acesteia in urmatoarele cazuri:
tuplul de adaugat nu corespunde schemei relatiei;
anumite valori ale tuplului nu apartin domenuilui respectiv ;
tuplul de adaugat coincide dupa cheie (vezi 2.2.1.3) cu tuplul din relatie .
De exemplu , adaugarea in relatia orar , a tuplului :
ADD (orar: NR :90 , PD :Iasi , PA : Sibiu , PD :16 , PA :12)
nu e permisa , deoarece nu respecta prima conditie .
2. Stergerea. Aceasta operatie se introduce pentru a elimina tupluri din relatie . Pentru o relatie r ,
operatia are forma :
DEL(r :A1 =d1 , A2 =d2 , … , An =dn)
Atunci cand numele atributelor sunt ordonate , se pot scrie mai simplu :
DEL( r : d1 , d2 , … , dn)
De exemplu , pentru relatia orar , stergerea primului tuplu , se realizeaza astfel:
DEL(orar : 70 , Bucuresti , Craiova , 16:59 , 17:50)
Deoarece , intr-o relatie , tuplurile sunt identifcate unic prin valoarea unei chei (vezi 2.2.1.3) , este
suficient pentru a realiza stergerea , sa definim numai valoarea cheii .
Daca K= {B1 , B2 , … , Bn} este o cheie , atunci se poate utiliza urmatoarea forma directa:
DEL ( r : B1 = c1 , B2 =c2 , … , Bn = cn )
De exemplu , varianta scurta a operatiei de strgere din relatia orar este :
DEL (orar : 70)
Daca tuplul ce doreste a fi sters , nu exista in relatia r atunci se genereaza o eroare .
3.Modificarea . Se refera la faptul ca anumite valori dintr-un tuplu se pot modifica .
Pentru o relatie oarecare r si pentru submultimea {c1 , c2 , … , cp} {A1 , A2 , … , An} , operatia de
modificare are forma:
CH (r : A1 =d1 , A2 =d2 , … , An =dn ; C1 = c1 , … , Cp = cp)
Daca K ={B1 , … , Bn } este o cheie , atunci operatia de modificare se poate scrie :
CH( r : B1 = d1 ,…, Bm = dm ; C1 = c1 ,…, Cp = cp)
Pentru relatia orar , operatia de modificare a primului tuplu are forma :
140
CH(orar : NR = 70 , PD = Bucuresti , PA = Craiova , OD = 16:59 , OA = 17:50 , OD =
18 , OA = 19) sau utilizand numai cheia operatiei :
CH (orar : NR = 70 , OD = 18 , OA = 19)
orar 2
NR PD PA OD OA
141
2.Diferenta . Reprezinta o operatie definita pe doua relatii r si s cu aceeasi schema R, si consta in
construirea unei noi relatii q , cu aceeasi schema R si avand drept extensie tuplurile din r care nu se
regasesc in s .
Notatiile uzuale pentru aceasta operatie sunt : r-s , REMOVE (r,s), MINUS(r,s)
Considerand tuplurile ca transformari , avem urmatoarea definitie formala a diferentei :
r-s ={t / t є r }-{t / t є s}
Diferenta relatiilor orar1 si orar 2 din exemplul 2.2.1 ne conduce la urmatoarea relatie:
NR PD PA OD OA
85 Timisoara Bucuresti 07:15 09:25
90 Timisoara Craiova 10:15 13:20
Intersectia reprezinta o operatie derivata , care poate fi exprimata prin intermadiul diferentei astfel: r
s= r – (r -s) sau rs= s – (s- r).
4.Produs cartezian . Reprezinta o operatie definita pe doua relatii r si s de schema R ,respectiv S ,
si consta in construirea unei noi relatii q , a carei schema Q , se obtine din concatenarea schemelor
relatiilor r si s iar extensia lui q se obtine din toate combinatiile tuplurilor din r cu cele din s.
Notatiile uzuale pentru aceasta operatie sunt : r x s, PRODUCT(r,s) , TIMES(r,s).
Considerand tuplurile ca transformari , avem urmatoarea definitie formala a produsului cartezian :
r x s = {t / (t1 є r)(t2 є s ) (t[R]=t1) (t[S]=t2)}
Fie pilot o relatie cu urmatoarela extensie :
pilot
NUME VARSTA
Popa 35
Vigu 40
Produsul cartezian al relatiei orar 1 din exemplul 2.2.1. si pilot , ne conduce la urmatoarea relatie:
NR PD PA OD OA NUME VARSTA
142
5. Selectia. Reprezinta o operatie definita asupra unei relatii r , si consta in construirea unei relatii
s , cu schema identica cu cea a relatiei r si a carei extensie este constituita din acele tupluri din r care
satisfac o conditie mentionata explicit in cadrul operatiei . Conditia este in general de forma :< atribut
operator de comparatie valoare>.
Notatiile uzuale in aceasta operatie sunt : σconditie (r) , r[conditie ] sau RESTRICT(r ,conditie ).
Considerand tuplurile ca transformari , operatorul de selectie se poate defini astefel :
σA=a (r)={t ε r / t (A)=a}
Selectia σ PD=Timisoara (orar 1 ) se aplica relatiei orar 2 din exemplul 2.2.1, ne conduce la urmatoarea
relatie:
NR PD PA OD OA
6.Proiectia. Reprezinta o operatie definita aupra unei relatii r si consta in construirea unei relatii s in
care se regasesc numai acele atribute din r specificate explicit in cadrul operatiei.Suprimarea unor
atribute din r poate avea ca efect aparitia unor tupluri duplicate ce vor trebui eliminate.Prin operatia de
proiectie se trece la o de la relatie de grad n la o relatie de grad m, mai mic decat cel initial.
Notatiile uzuale pt aceasta operatie sunt: Π A1 ,A2,…,Am (r), PROJECT(r, A1, A2,…,Am).
Considerand tuplurile ca transformari , operatorul de proiectie se poate defini astfel :
Πx = {t(X) / t ε r}
Aplicarea operatorului ΠPD,PA(orar 1) relatiei orar 1 din exemplul 2.2.1 ne conduce la urmatoarea
relatie:
PD PA
Craiova Bucuresti
Bucuresti Timisoara
TImisoara Bucuresti
Timisoara Craiova
7.Join(Jonctiunea sau unirea) [7] Reprezinta o operatie definita pe doua relatii r si s , operatie care
consta din construirea unei noi relatii q , prin concatenarea unor tupluri din r cu tupluri din s.Se
concateneaza acele tupluri din r si s care satisfac o anumita conditie.Extensia relatei q va contine acele
tupluri care satisfac conditia de concatenare.
Notatiile uzuale pentru aceasta operatie sunt : r ⋈ codities sau JOIN(s,r,conditie).
In general conditia de concatenare are urmatoarea forma :
<atribut din r operator de comparatie atribut s>.
In functie de operatorul de comparatie , join-ul poate fi de mai multe tipuri.Cel mai important tip ,
in sensul celei mai frecvente utilizari este echijoin-ul , care reprezinta o operatie de join, dirijata de o
conditie de forma urmatoare :<atribut din r =atribut din s>.
Definitia 2.2.4. fie relatiile r si s de schema R respectiv S, cu Ai є R si Bi є S, dom(Ai)=dom (Bi ),
i=1 ,…, m . Relatia:
q(RS)={t : tr ε s , astfel incat t(R) =tr , t(S)=ts , t(Ai)=t(Bi), i=1,…,m}
se numeste echijoin-ul relatiilor in raport cu A1=B1=…=Am=Bm si se noteaza cu r[A1=B1=…=Am=Bm]s
.
Considerand relatia oras , de forma urmatoare:
oras
PD JUDET
Timisoara Timis
Craiova Dolj
Oradea Bihor
143
Operatia orar 1⋈PD=PDoras aplicata relatiilor orar 1 din exzemplul 2.2.1 si oras definita sus, ne
conduce la urmatoarea relatie:
NR PD PA OD OA PD JUDET
Operatia de mai jos se poate exprima cu ajutorul operatiilor de produs cartezian si selectie ,
rezultatul unui join fiind acelas cu rezultatul unei selectii operate asupra unui produs cartezian , adica :
JOIN (r,s,conditie )=RESTRICT(PRODUCT(r,s,conditie ), conditie)
Produsul cartezian reprezinta o operatie laborioasa si foarte costisitoare , ceea ce face ca in locul
produsului sa fie utilizat join-ul ori de cate ori acest lucru este posibil.
In cazul echijoin-ului , schema relatiei rezultat , contine toate atributele celor doi operanzi si de
aceea vor exista cel putin doua valori egale in fiecare tuplu . Join-ul natural elimina aceasta redundanta
, fiind definita in mod similar cu echijoin-ul cu observatia ca atributele cu acelas nume se trec o singura
data i relatia rezultat iar extensia se compune din concatenarea tuplurilor lui r cu tuplurile lui s care
prezinta aceleas valori pentru atributele cu acelas nume . Notatia uzuala pt aceasta operatie este : r ⋈s.
Join-ul natural al relatiilor orar 1 din exemplul 2.2.1. si oras definita mai sus , ne conduce la
urmatoarea relatie:
NR PD PA OD OA JUDET
75 Craiova Bucuresti 07:15 08:25 Dolj
85 Timisoara Bucuresti 07:15 09:25 Timis
90 Timisoara Craiova 10:15 13:20 Timis
Join extern . Atunci cand relatiile care participa la join nu au proiectii identice pe atriburul de
jonctiune (atributul nu are acelaesi valori in relatiile care se jonctioneaza ), operatia de join conduce la
pierderea de tupluri , cel putin dintr-o relatie . pt a evita pierderile de informatie a fost definit join-ul
extern , ca o operatie prin care din doua relatii r si s se obtine o noua relatie q prin join-ul relatiilor s si
r , relatie la care se adauga si tuplurile din r si s care nu au participat la join .Aceste tupluri sunt
completate in relatia q cu valori “null” pt artibutele relatiei corespondente (r, respectiv s).
Notatiile uzuale pt desemnarea unei join extrem sunt :r ⋈.s sau EXT-JOIN(r,s).
Join-ul extern al relatiilor orar 1si oras conduce la urmatoarea relatie :
NR PD PA OD OA JUDET
Semi-join . Aceasta operatie a fost introdusa de Bernstein P.A. , fiind necesara la definirea
procesului de optimizare a interogarilor .Semi-jonctiunea conserva atributele unei singure relatii
participante la join si reprezinta o operatie pe doua relatii r si s in urma careia rezulta o noua relatie ce
contine numai tuplurile din relatia r care participa la join .Notatiile uzuale pt aceasta operatie sunt : r ⋈s
sau SEMIJOIN(r,s).
Astfel , orar1><oras conduce la urmatoarea relatie :
NR PD PA OD OA
75 Craiova Bucuresti 07:15 08:25
144
85 Timisoara Bucuresti 07:15 09:25
90 Timisoara Craiova 10:15 13:20
8.Diviziunea . Reprezinta o operatie din AR definita asupra unei relatii r de schema : R(A1:D1 ,
…,Ap: Dk, Ap+1: D1, …,An: Dm), operatie care consta din construirea , cu ajutorul unei relatii
s(Ap+1 : D1 , … , An : Dm) a relatiei q (A1 : D1 , …, Ap : Dk) . Tuplurile relatiei q , concatenate cu
tuplurile relatiei s permit obtinerea tuplurilor relatiei r .
Definitia 2.2.5 Fie r si s doua relatii de schema R respectiv S , cu S R si R’=R-S .Relatia :
r’(R’)={t :ts s , tr r astefel incat tr (S)=ts , tr (R’ )=t } se numeste diviziunea relatiei r la s .
Operatia de diviziune este o operatie derivata , care poate exprima prin intermediul diferentei ,
prudusului cartezian si proiectiei astfel :
r / s =A1,A2,…,Ap(r) - A1,A2,…,Ap((A1,A2,…,Ap(r)x s )-r)
Consideram relatiile drept si tip de forma urmatoare :
drept
Pilot Tip avion
Dan AIRBUS
Dan TU154
Ion TU154
Ion AIRBUS
Mihai TU154
tip
Tip avion
AIRBUS
TU154
Daca dorim sa obtinem pilotii care au drept de zbor pe toate tipurile de avionane, calculam drept+tip ,
si rezulta relatia :
Pilot
Dan
Ion
145
Pilot Tip avion
Dan IAR500
Ion IAR500
Mihai AIRBUS
Mihai IAR500
Andrei IAR500
Andrei AIRBUS
Andrei TU154
10.Splitarea (spargerea). Este o operatie aditionala din AR , definita asupra unei relatii r si
care, pe baza uneiconditii definite asupra atributelor lui r permite construirea a doua relatii r1 si
r2 , cu aceeasi schema cu r .Extensia lui r1 contine tuplurile din r care indeplinesc conditia
specificata , iar r2 pe cele care nu verifica aceasta conditie.
Pt relatia drept definita mai sus si conditia Pilot=”Dan”, operatia de splitare produce ca
rezultat relatiile drept 1 si drept 2:
drept 1
Pilot Tip avion
Dan AIRBUS
Dan TU154
drept2
Pilot Tip avion
Ion TU154
Ion AIRBUS
Mihai TU154
11.Inchiderea tranzitiva . Este o operatie aditionala din AR prin care se pot adauga noi
tupluri la o relatie .Operatia de inchidere tranzitiva presupune efectuarea in mod repetat a
secventei de operatii : join-protectie-reuniune. Numarul de executii depinde de continutul relatiei
. Inchiderea tranzitiva se defineste asupra unei relatii r , a carei schema contine doua atribute A1
si A2 cu acelasi domeniu , si consta in adaugarea la relatia r a tuplurilor care se obtin succesiv
prin tranzitivitate , in sensul ca , daca exista in r tuplurile <a,b> si <b,c> se va adauga la r si
tuplul <a,c>.Notatiile uzuale pt aceasta operatie sunt : (r), r, CLOSE()r.
Prezentam mai jos , o relatie legatura ce ne arata legaturile aeriene intre anumite localitati
precum si inchiderea tranzitiva a relatiei (legatura).
Legatura
PD PA
Bucuresti Iasi
Bucuresti Timisoara
Timisoara Arad
Timisoara Craiova
(legatura)
PD PA
Bucuresti Iasi
146
Bucuresti Timisoara
Timisoara Arad
Timisoara Craiova
Bucuresti Arad
Bucuresti Craiova
Crearea unei baze de date se face la fel ca in formele anterioare de fox cu CREATE
NUME_TABELA si apare ceva de forma:
147
Calculul unei formule economice cu conditii seface cu BROWSE
,TABLE/REPLACE FIELD
Pozitionarea pe anumite inregistrari:
Stergerea unor inregistrari care
indeplinesc anumite conditii se face cu
TABLE/DELETE RECORDS
LUCRAREA DE LABORATOR
CREAREA SI MODIFICAREA STRUCTURII FISIERELOR
Scop
Insusirea modului de lucru privind crearea si modificarea structurii fisierelor.
Studiu necesar
Lungu i.,N. Musat,M. Velicanu FoxPro 2.6. Prezentare si aplicatii Ed.All,1966
148
principal,la memorarea unor informatii, urmata de extragerea acestora sub diferite
forme.
Baza de date reprezinta structura logica in care este memorata o cantitate de
informatii,pe un suport fizic de memorare .La nivel inferior,baza de date reprezinta
unul sau mai multe fisiere,care respecta conditiile impuse de sistemul de operare.
Pentru a determina in mod univoc structura unui fisier trebuie specificate
campurile care compun fisierul,impreuna cu caracteristicile acestora.Fiecarui camp ii
sunt caracteristice:
-nume -identifica campul printre celelalte elemente
-tipul - stabileste prelucrarile care se pot aplica datelor memorate in campul respectiv
-lungimea -numarul de octeti ocupati de camp(adica latimea coloanei in tabel)
necesar pentru rezervarea spatiului de memorie pe disc
-zecimale -pentru campurile numerice ,stabileste pozitia punctului zecimal in cadrul
campului respectiv
Pentru manipularea unui fisier Foxpro foloseste o zona de memorie in care
memoreaza unele informatii referitoare la starea acestuia..,numita zona de
lucru.Acest SGBD poate lucra simultan cu mai multe fisiere,deci va avea mai multe
zome de lucru(25 la numar).Modul de lucru cu o baza de date este urmatorul:-se
deschide fisierul(acestuia I se atribuie o zona de lucru)
-se executa operatiile dorite asupra fisierului(adaugare inregistrari,stergere
inregistrari,etc)
-la terminarea lucrului aceasta se inchide;
La deschiderea unui fisier(intr-o zona de lucru ) acestuia I se atribuie un nume numit
alias,prin care este identificat.Aliasul poate fi furnizat de utilizator sau poate fi atribuit
automat de FOXPRO . Identificarea unei date memorate intr-un fisier se face prin
specificare inregistrarii si campului de care aceasta apartine.
Zone de lucru
Pentru identificarea zonelor de lucru se folosesc doua metode:
-primele 10 zone de lucru se identifica prin litele de la A la J ,adica primele 10 litere
din alfabet.
-pentru toate cele 25 de zone de lucru putem folosi pentru identificare numere de la 1
la 25.
La deschiderea unui fisier intr-o zona de lucru, acestei I se atribuie un nume pe care
il vom numi’alias’. Deci fisierul deschis in zona de lucru va putea fi identificat si
prin alias-ul respectiv.La un moment dat, o singura zona este curenta..Aceasta
inseamna ca o anumita comanda ,in interiorul careia nu s-a specificat explicit fisierul
la care se refera ,va actiona asupra fisierului din zona de lucru curenta .
La pornirea FOXPRO zona de lucru curenta va fi zona A sau 1.
Aceasta se poate schimba folosind comanda SELECT<expN>|<expC> unde <
expN> reprezinta numarul zonei de lucru ce va deveni curenta(activa).Daca <expN>
este 0 se va selecta prima zona de lucru neocupata (in care nu s-a deschis nici un
fisier) iar <expC> reprezinta alis-ul fisierului deschis in acea zona de lucru.
Exemplul 1
SELECT 1 && zona curenta va fi zona 1
SELECT A && echivalenta cu prima comanda
Sa presupunem ca in zona de lucru 2 avem deschis fisierul STUDENT,,pentru
selectarea acestei zone putem folosi comenzile:
SELECT 2
SELECT B
SELECT STUDENT
SELECT ‘STUDENT’
149
Pentru a afla care este zona de lucru curenta se foloseste functia SELECT( ) ,aceasta
returnand numarul zonei de lucru curenta sau numarul ultimei zone de lucru
nefolosite.Sintaxa este:SELECT([0|1])
0-functia returneaza numarul zonei de lucru curente
1-functia returneaza numarul ultimei zone de lucru nefolosite
SELECT() si SELECT(0) sunt echivalente
Exemplul 2
?SELECT ( )
1
?SELECT(1)
25
?SELECT SELECT() +1 && se selecteaza prima zona de lucru dupa cea curenta
2
Structure:C:\fox\student.dbf
Name Type With Dec Field
Matricol Numeric 4 <Insert>
Nume Character 10 <Delete>
Grupa Numeric 3 <ok>
Adresa Character 10 <cancel>
Datan Date 8
Notabd Numeric 5 2
Codl Numeric 4
Prima coloana nu poarta nici un nume.Cand cursorul se afla in aceasta coloana se pot
apasa doua taste : INSERT pentru a insera un camp nou in aceasta pozitie,DELETE
pentru a sterge campul existent in pozitia curenta.Lungimea maxima a unei
inregistrari =4000 caractere.
Deschiderea si inchiderea unui fisier
150
Deschiderea unei baze de date se realizeaza folosind comanda USE cu sintaxa:
USE [<fisier>|?]
[IN<zona de lucru>]
[AGAIN] [INDEX<lista fisiere index>|?
[ORDER [<expN>|<fisier index .idx>| [TAG] <nume eticheta>
[OF<fisier .cdx>] [ASCENDING|DESCENDING]]]]
[ALIAS<alias>] [EXCLUSIVE] [NOUPDATE]
<fisier> reprezinta fisierului bazei de date ce va fi deschis ,caruia ,daca nu I se
specifica nici o extensie ,I se va atribui implicit extensia DBF.Implicit,baza de date
specificata va fi deschisa in zona de lucru curenta.De asemenea inchiderea unei
baze de date se refera tot la aceasta zona de lucru.Pentru a ne referi la o alta zona se
foloseste clauza IN specificand prin<zona de lucru > aceasta zona.
Exemplul 3
? SELECT ( ) && afiseaza zona de lucru curenta
1
USE student && s-a deschis in zona 1
USE && s-a inchis
USE student IN 2 && s-a deschis in zona 2 chiar daca zona de lucru curenta a
&& a fost si va ramane 1
USE IN 2 && se va inchide baza din 2
In Foxpro exista posibilitatea deschiderii unei baze de date in mai multe zone de
lucru..In acest scopse foloseste clauza AGAIN.
Exemplul 4
SELECT A && se selecteaza zona de lucru 1
USE student
USE student IN 2 AGAIN && se deschide si-n zona 2
USE IN 2 && se inchid bazele
USE
Observatie : Daca la deschiderea unei baze de date , in zona de lucru exista anterior
o alta baza de date ,cea veche este inchisa automat inainte de deschiderea celei noi.
Clauza NOUPDATE se introduce pentru a proteja fisierul la scriere .
Exemplul 5
SELECT A
USE student NOUPDATE
USE
INDEX-se refera la indexarea bazei de date
EXCLUSIVE- se refera la folosirea intr-o retea a bazei de date
ALIAS-se refera la alias-ul atribuit de utilizator bazei de date
Inchiderea bazelor de date se poate utiliza so cu comenzile CLOSE ALL si CLOSE
DETABASE.
CLOSE ALL inchide toate fisierele din toate zonele de lucru si selecteaza zona de
lucru 1.Printre aceste fisiere se afla si bazele de date care vor fi inchise cu aceasta
comanda.CLOSE DETABASE inchide toate
bazele de date si selecteaza zona de lucru 1.Pentru a obtine informatii despre zonele
de lucru ale FOXPRO si bazele de date deschise inele se vor folosi doua functii
USED( )si DBF( ).
USED( ) ne informeaza daca o zona de lucru este libera sau este ocupata de un
fisier .Sintaxa:
USED([<expN>|<expC>]) in care <expN> sau <expC> specifica zona de lucru despre
care dorim informatii(prin numarul sau prin alias-ul corespunzator).Functia returneaza
.T. daca in zona de lucru respectiva este deschis un fisier si .F. daca zona de lucru este
151
libera.Daca nu se specifica o zona de lucru , functia se refera la zona de lucru
curenta .Daca se secifica un alias, functia returneaza un alias ,functia returneaza
adevarat , daca un fisier cu acest alias este deschis intr-una din zonele de lucru
FoxPro.
Exemplul 6
SELECT A
USE student IN 4
USE student AGAIN
? USED()
.T.
?USED(2)
.F.
?USED(‘student’)
.T.
-USE
USE IN 4
Pentru a afla ce fisier este deschis intr-o anumita zona de lucru se foloseste functia
DBF().Aceasta returneaza un sir de caractere ce contine numele fisierului deschis
intr-o zona de lucru sau care are un anumit alias.
Exemplul 7
SELECT a
USE student
?DBF(‘stuent’)
C:\FPD 26\STUDENT.DBF
?DBF(‘a’)
C:\FPD 26\STUDENT .DBF
?DBF(1)
C:\FOXPRO 20\STUDENT .DBF
?DBF(2)==‘ ‘
.T.
USE
Exemplul 8
SELECT student IN b ALIAS info
SELECT info
?SELECT0
2
USE IN b
Alias-ul implicit ce se atribiue unui fişier, la deschidere, de către FoxPro este numele
fişierului, fără extensie.
Exemplul 9
SELECT a
USE student IN b
152
SELECT student
?SELECT0
2
USE IN b
Exemplul 10
SELECT a
USE student
COPY STRUCTURE TO studenti.dfb FIELDS matricol, nume, grupă
USE studenti
LIST STRUCTURE
O modalitate de transmitere a unei structuri a bazei de date, şi anume printr-o
bază de date intermediară, în care se încarcă srtuctura de copiat. Comanda folosită
este COPY STRUCTURE EXTENDED cu următoarea sintaxă:
COPY TO fisier STRUCTURE EXTENDED
Stuctura bazei de date se copiază în înregistrările unei noi baze de date, fisier, care
are o srtuctură fixă, formată din patru câmpuri.
153
3 Grupa N 3 0
4 Adresa C 10
5 Datan D - -
6 Notbad N 5 2
7 Codl N - -
Accesul la câmpurile unei baze de date este controlat de comanda SET FIELDS, care
are sintaxa:
SET FIELDS ON OFF
SET FIELDS TO [[ câmp1 [câmp2…]] ALL ]
câmp1 ,câmp2… reprezintă lista câmpurilor ce pot fi accesate în cazul SET
FIELDS ON.
Exemplul 11
SET FIELDS ON
SET FIELDS TO nume, grupa
Iar pentru a reveni la normal se introduce fie SET FIELDS TO ALL fie SET FIELDS
OFF.
Numărul câmpurilor dintr-o bază de date este returnat de funcţia FCOUNT () ce are
următoarea suntaxă:
FCOUNT ([ expN expC]), expN - zona de lucru în care este deschis fişierul
la care se referă funcţia;
expC - alias-ul fişierului respectiv.
Exemplul 12
CLOSE ALL
USE student
?’Fişierul are’,FCOUNT(),’câmpuri’
?FCOUNT()=FCOUNT(1)
.T.
?FCOUNT(1)=FCOUNT(‘student’)
.T.
?FCOUNT(2)
0
USE
154
Funcţia FIELD () returnează numele unui câmp dintr-un fişier identificat prin
numărul câmpului în cadrul structurii bazei. Funcţia are următoarea sintaxă:
FIELD ( expN1 [, expN2 expC]) în care expN1 specifică numărul de
ordine al câmpului ( primul câmp are numărul de ordine 1 al doilea 2 s.a.m.d.), iar
expN2 sau expC identifică baza de date la care se referă funcţia, prin zona de
lucru în cazul specificăriiexpN sau prin alias-ul bazei de date ( când se specifică
expC ).
Exemplul 13
CLOSE ALL
USE student
?FIELD(1)
matricol
USE student IN 2 AGAIN
?FIELD(1,2)
matricol, nume
?FIELD(7)= ‘’
.T.
?FIELD(FCOUNT())
adresa
CLOSE ALL
Funcţia FSIZE ()returnează mărimea unui câmp al unui fişier. Sintaxa este:
FSIZE ( expC1 [, expN expC2 ]) rezultatul fiind numeric. expC1 este un
şie de caractere ce reprezintă numele câmpului, iar prin expN sau expC2 se
specifică zona de lucru, respectiv fişierul la care se referă funcţia.
Exemplul 14
CLOSE ALL
USE student
?’structura fişierului :’,DBF()
?’câmp’,’nume’,’lăţime’
TOTAL=0
FOR I=1 to FCOUNT()
?I,FIELD(1),TYPE(),FSIZE(FIELD(I))
TOTAL=TOTAL+FSIZE(FIELD(I))
ENDFOR
?’**Total**’,TOTAL+1
USE
Domeniul înregistrărilor
Există comenzi în FoxPro care acţionează asupra mai multor înregistrări ale
unui fişier. Selectarea acestora se face specificând în comandă condiţia de selectare,
cu ajutorul căreia, din mulţimea totală a înregistrărilor se aleg doar acelea care
respectă condiţia respectivă. Mulţimea înregistrărilor selectate formează “domeniul
înregistrărilor” la care se referă comanda. Domeniul înregistrărilor se specifică prin
clauzele domeniu ,FOR, WHILE incluse opţional în comanda respectivă. Clauza
domeniu se va înlocui cu una din următoarele construcţii, în funcţie de necesităţi:
ALL selectează toate înregistrările din baza de date
NEXT exp N se referă la următorele exp N înregistrări, începând de la
înregistrarea curentă inclusiv.
155
RECORD exp N acţionează numai asupra înregistrării cu numărul exp N
REST selectează înregistrările începând de la cea curentă, inclusiv, şi până la sfârşitul
fişierului.
Clauza FOR se foloseşte pentru selectarea înregistrărilor în funcţie de o condiţie
logică exp L . Se selectează acele înregistrări pentru care exp L este
adevărată. Clauza WHILE ( cât timp) cu sintaxa WHILE exp L - este
asmănătoare clauzei FOR. Spre deosebire de clauza FOR, după găsirea unei
înregistrări ce nu respectă condiţia exp L , continuă testarea celorlalte, clauza
WHILE întrerupe testarea înregistrărilor când găseşte o înregistratre ce nu respectă
condiţia dată.Dacă se specifică ambele clauze FOR şi WHILE, prima care contează
este clauza WHILE. Folosind clauza FOR viteza de preluare creşte foarte mult, de
aceea se recomandă folosirea acesteia, oricând este posibil.
LUCRAREA DE LABORATOR
Scop
Însuşirea modalităţilor de adăugare, modificare, ştergere şi vizualizare a
informaţiiolor dintr-un fişier. Utilizarea indicatorului de înregistrări, filtrarea şi
căutarea informaţiilor.
Studiu necesar
Lungu I., N. Muşat, M. Velicanu FoxPro2.6. Prezentare şi aplicaţii. Ed. All,
Bucureşti, 1996.
Adăugarea de înregistrări
156
Clauza ON determină copierea îregistrării curente în cea nouă pe când clauza OFF
opreşte aceasstă copiere. Opţiunea implicită este OFF. Cea de-a doua formă a
comenzii se foloseşte când se doreşte copiera numai a anumitor câmpuri ale
înreigstrării curente în noua înregistrare, aceste câmpuri fiind specificate în lista de
câmpuri listă câmpuri. Dacă se include în comandă şi opţiunea ADDITIVE, la
vechea listă de câmpuri, are ca efect întoarcerea la lista implicită, în care sunt
specificate toate câmpurile. Prima formă a comenzii SET CARRY ON OFF se
referă doar la zona de lucru pe când cea de-a doua formă, SET CARRY TO, se referă
la zona de lucru curentă.
Eemplul 1
Să presupunem că introducem informaţii într-un fişier în care unul din câmpuri este
data curentă. În cadrul unei zile, această dată nu se schimbă, iar introducerea în
fiecare înregistrare a datei curente este ineficientă, De aceea se recomandă copierea
automată a datei curente pentru fiecare nouă înregistare ce se adaugă. Aceasta se
realizează cu secvenţa de comenzi :
SET CARRY ON
SET CARRY TO data_intr
Iar la sfîrşitul zilei se introduce secvenţa de comenzi :
SET CARRY TO
SET CARRY OFF
pentru anularea acestei stări (inhibarea copierii datei de la o inregistrare la alta).
Comanda APPEND BLANK are ca efect adăugarea unei noi înregistrări “ blank”
(goală) la sfîrşitul bazei, urmând ca informaţia utilă să se încarce mai târziu, prin alte
comenzi FoxPro.
Adăugarea de înregistrări la sfîrşitul bazei active se poate realiza cu comanda
APPEND FROM. Înregistrările ce se vor adăugabazei de date active vor fi preluate
din fişierul fişier.
APPEND FROM fişier ?
[FIELDS listă câmpuri]
[FOR expL]
[TYPE] [DELIMITED [WITH TAB WITH delimitator WITH
BLANK]
[DIP FWZ MOD PDOX RPD SDP SYLK WK1 WK3 WKS
WR1 WRK XLS]
fişier reprezintă numele fişierului din care se preiau înregistrările ce se vor adăuga
la fişier.
Dacă nu se specifică numele fişierului, trebuie specificată clauza ?, utilizatorului
oferindu-i-se astfel posibilitatea selectării fişierului printr-o fereastră de dialog. Dacă
se doreşte ca din fişier fişier să se preia doar anumite câmpuri, se va include clauza
FIELD. Dacă nu se specifcă asfel, întreg fişierul va fi adăugat la sfârşitul bazei de
date. Pentru a prelua din fişier doar anumie înregistrări, se va specifica domeiul
acestora, prin clauza FOR. Se foloseşte clauza TYPE pentru a specifica tipul acestui
fişier.
Exemplul 2
CLOSE ALL
USE student
APPEND FROM studenti FIELDS nume, grupa FOR codl = 1100
LIST
USE
157
Transferul invers de la o bază de date la un alt fişier de pe disc se realizează cu
comanda COPY TO cu următoarea sintaxă :
COPY TO fişier[FIELDS listă câmpuri]
[domeniu][FOR expL1][WHILEexpL2]
[[WITH]CDX] [[WITH] PRODUCTION]
[NOOPTIMIZE]
[TYPE][FOXPLUS DIF MOD SDF SYLK WK1 WKS WR1 WRK
XLS DELIMITED [WITH delimitator WITH BLANK WITH TAB]]
Comanda copiază înregistrări din baza de date activă într-un fişier nou, cu numele
fişier. Acestuia dacă nu se specifică o extensie, i se va atribui automat
extensia .DBF. În cazul în care nu se specifică alt tip, fişierul nou creat va fi o bază de
date FoxPro în care se copiază înregistrări din baza de date activă.
Ce de-a doua metodă de adăugare a unei înregistrări noi la un fişier o
reprezintă inserarea înregistrării în interiorul bazei de date folosind comanda
INSERT.
Fie Ik înregistrarea curentă.
Înregistrarea I se introduce între Ik şi Ik+1. Comanda INSERT are următoarea sintaxă :
INSERT [BEFORE][BLANK]
Şi are ca efect înscrierea unei înregistrări noi, după înregistrarea curentă. Dacă se
specifcă clauza APPEND, completarea câmpurilor este influenţată de SET CARRY.
Clauza BEFORE determină adăugarea unei înregistrări noi înaintea înregistrării
curente.
Exemplul 3
USE student
GOTO 2
INSERT BEFORE
USE
158
Lista de câmpuri de la clauza FIELDS reprezintă o înşiruire de câmpuri, ale unei baze
de date sau calculate,separate prin virgulă, ce se vor edita, având următoarea sintaxă :
câmp [:R] [:V=expr1[:F][:E=expC1]] [:P=expC2]
[:B=expr2,expr3[:F]] [:H=expC3]
[:W=expL1] [,câmp2[:R]…]
Câmpurile calculate reprezintă câmpuri din fereastra de editare, create prin evaluarea
unei expresii şi afişate în fereastra respectivă ca un câmp de sine stătător. Aceste
câmpuri se pot vizualiza, dar nu se pot modifica. Sintxa de definiţie a unui câmp
calculat este :
nume câmp calculat=expr
exemplul 4
Având fişierul student.dbf, vom deschide o fereastră de editare în care vom
afişa doar câmpurile nume, vârstă, codl. Primul şi ultimul sunt cîmpuri ale bazei de
date, vârsta fiind un câmp calculat în funcţie de data naşterii (câmpul născut din fişier)
şi data curentă.
CLOSE ALL
USE student
BROWSE FIELDS nume vârstă=(date()-datan)/365,codl
USE
În sintaxă există posibilitatea ataşării fiecărui câmp a uneia sau mai multor
opţiuni :
:R -câmpul se poate vizualiza, nu şi modifica
:V=expr1 -permite validarea câmpului introdus. După ce câmpul s-a modificat şi
se iese din editarea acestuia, se evaluează expr1. Dacă expr1 este evaluată la .T.
data introdusă în câmp este corectă, iar dacă este evaluată la .F. data se consideră
incorectă, aflându-se un mesaj de eroare. În cazul când expresia este de tip numeric,
iar valoarea ei este 0, data introdusă în câmp este incorectă, afişându-se un mesaj de
eroare.
exemplul 5
USE student
BROWSE FIELDS nume:R,codl:V=codl=1100 AND codl =2000:F:E= ‘codl
159
Modificarea conţinutului unei baze de date se poate face şi cu comanda
REPLACE care, spre deosebire de cea anterioară nu deschide o fereastră ci realizează
propriu-zis actualizarea bazei de date cu datele precizate prin comandă. Sintaxa este :
REPLACE
câmp1WITHexpr1[additive]
[,câmp2WITHexpr2[additive]…]
[domeniu][FORexpL1][WHILEexpL2]
[NOOPTIMIZE]
Comanda înlocuieşte vechea valoare din câmpul câmp1 cu valoarea
rezultată în urma evaluării expresiei expr1, vechea valoare din câmpul câmp2 cu
valoarea expresiei expr2 şi aşa mai departe. Pentru câmpuri numerice, dacă nu se
reuşeşte încadrarea valorii expresiei în câmpul respectiv, acesta va fi umplut cu
asteriscuri. Pentru câmpuri memo, specificând clauza ADDITIVE, acestea nu sunt
înlocuite, expresia fiind adăugată la sfârşitul lor. domeniu, FOR şi WHILE
specifică domeniul înregistrărilor la care se referă comanda REPLACE, domeniul
implicit fiind înregistrarea curentă.
Exemplu 6
USE student
Append blank
REPLACE nume WITH ‘Toma’
REPLACE codl WITH 1100
REPLACE ALL grpa WITH 231
Ştergerea înregistrărilor
Ştergerea unei înregistrări dintr-un fişier se poate realiza la două nivele şi anume :
- la nivel logic când înregistrarea nu este propriu-zis ştearsă din fişier ci ea este
marcată într-un anumit mod (‘marcată pentru ştergere’) indicând astfel această
stare a înregistrării.
160
- la nivel fizic când înregistrarea este ştearsă, efectiv din fişier, ea neputând fi în
nici un fel accesată sau refăcută. Marcarea pentru ştergere a uneia sau mai multor
înregistrări se face cu ajutorul comenzii DELETE:
DELETE [domeniu ][FOR expL1 ][WHILE expL2 ][NOOPTIMIZE]
domeniu ,FOR,WHILE identifică înregistrările ce vor fi marcate pentru
ştergere. Domeniul implicit al comenzii DELETE este înregistrarea curentă. Accesul
la înregistrările marcate pentru ştergere este controlat de comanda SET DELETED :
SET DELETED ON OFF
Când se alege opţiunea ON, înregistrările marcate pentru ştergere nu vor fi accesibile
celorlalte comenzi care folosesc domeniul înregistrărilor (domeniu , FOR,WHILE )
iar când este aleasă opţiunea OFF, înregistrările sunt accesibile indiferent de marcajul
de ştergere.
Starea iniţială este OFF. Comenzile care acţionează asupra unei singure înregistrări
sau care au ca domeniul implicit înregistrarea curentă nu sunt afectate de această
comandă.
Exemplul 7
USE student
DELETE FOR MOD(RECNO(),2=0
SET DELETED OFF
LIST FOR DELETED()=.F.
USE
Acest exemplu este echivalent cu:
USE student
DELETE FOR MOD(RECNO(),2=0
SET DELETED ON
LIST
USE
În interiorul unui program testatrea marcajullui de ştergere a unei ănregistrări se face
cu funcţia DELETED (). Aceasta returnează valoarea logică adevărat, dacă
înregistrarea curentă este marcată pentru ştergere, altfel funcţia returnează fals.
O înregistrare marcată pentru ştergere nu este ştearsă fizic din fişier. Eliminînd
marcajul de ştergere, înregistrarea este refăcută, ea redevenind accesibilă pentru toate
comenzile, înlăturarea marcajului de ştergere se realizează cu comanda RECALL ce
are aceaşi sintaxă cu comanda DELETE.
Exemplul 8
USE student
DELETE FOR MOD(RECNO(),3<=0
LIST
RECALL ALL
LIST
USE
Pentru ştergerea la nivel fizic se foloseşte comanda PACK cu următoarea sintaxă :
PACK [MEMO][DBF]
Comanda realizează ştergerea fizică a tuturor înregistrărilor marcate pentru ştergere
din fişier. După aplicarea comenzii PACK înregistrările sunt şterse definitiv. Dacă o
bază date conţine un câmp de tip memo, informaţiile conţinute în acest câmp sunt
depozitate într-un fişier asociat bazei de date (cu acelaşi nume dar cu extensie FTP).
Clauza MEMO a comenzii PACK are ca efect eliminarea spaţiului nefolosit
din fişierul MEMO asociat, fără a afecta fişierul bazei de date propriu-zis. Clauza
DBF se foloseşte pentru a şterge fizic înregistrările marcate pentru ştergere din fişier,
161
fără a modifica fişierul MEMO asociat. Comanda PACK fără nici o clauză se referă
atât la fişierul bazei de date cât şi la fişierul MEMO asociat.
Exemplu 9
USE student
DELETE RECORD 5
PACK
LIST
USE
Comanda ZAP şterge fizic toate înregistrările din fişier activ fiind echivalentă cu
secvenţa de instrucţiuni:
DELETE ALL
PACK
Comanda ZAP este mult mai rapidă decât secvenţa anterioară de instrucţiuni.
Înregistrările şterse cu ZAP nu mai pot fi refăcute.
Înainte de execuţia comenzii dacă opţiunea SET SAFETY este ON se va mai afişa un
mesaj de confirmare a ştergerii înregistrărilor.
Accesul la înregistrări
162
? FILTER() &&codl>1100
CLOSE ALL
163
LIST
USE
Indicatorul de înregistrări
164
Dacă se sare peste ultima înregistrare, indicatorul de înregistrări va conţine numărul
de înregistrări +1, iar funţia EOF () va returna .T. . în cazl saltului înaintea primei
înregistrări, funcţia BOF () va returna .T. .
expN2 expC specifică fişier prin zona în care este deschisă sau prin alias-ul
corespunzător.
Comanda SKIP este echivalentă cu SKIP 1.
Exemplul 17
USE student
1
SKIP 2
DISP RECO RECNO()
SKIP-1
?RECNO()2
Următoarele comenzi sunt echivalente :
SKIP
SKIP 1
SKIP IN SELECT()
GOTO RECORD RECNO()+1
Pentru a insera o înregistrare blank pe poziţia a 2-a şi a 4-a a bazei de date se foloseşte
următoarea secvenţă de instrucţiuni:
USE agenda
GOTO 2
INSERT BLANK BEFORE
SKIP 2
INSERT BLANK BEFORE
USE
Funcţiile BOF() şi EOF() având sintaxele:
BOF()([expN expC])
EOF()([expN expC])
Testează dacă indicatorul de înregistrări se află la începutul, respectiv la sfârşitul
bazei de date active, sau a celeii specificate ca parametru. Rezultatul este de tip logic
(.T. dacă condiţia este îndeplinită şi .F. în caz contrar). Numărul de înregistrări este
returnat de funcţia RECCOUNT () cu sintaxa :
RECCOUNT([expN expC])
Dimensiunea unei înregistrări se obţine folosind funcţia RECSIZE () cu sintaxa :
RECSIZE([expN expC])
Dacă nu se specifică alt fişier ultimile duoă funcţii se referă la fişier activ.
165
fişier pot exista mai multe înregistrări ce respectă o condiţie dată. Prima dintre acestea
va fi găsită de comanda LOCATE. Următoarele vor fi găsite folosind comanda
CONTINUE. Testarea reuşitei sau nereuşitei căutării se face ca la comanda LOCATE
cu funcţiile RECNO(), FOUND(),EOF().
Funcţia FOUND() cu sintaxa:
FOUND ([expN expC])
Este folosită pentru testarea rezultatului unei căutări într-un fişier, returnând valoarea
adevărată în cazul unei căutări cu succes şi fals în caz contrar. expN şi expC
identifică fişierul la care se referă funcţia (zona de lucru sau alias-ul)
Exemplul 18
CLOSE ALL
USE student
LOCATE FOR grupa=231
?FOUND()
.T.
=EOF()
.F.
?RECNO()
1
CONTINUE
?FOUND()
.T.
?EOF()
.F.
?RECNO()
3
USE
Un alt tip de căutare într-un fişier este realizat cu funcţia LOOKUP (). Aceasta caută
într-un fişier prima apariţie a unei expresii date. În caz de reuşită indicatorul de
înregistrări se poziţionează pe înregistrarea pe care a fost găsită expresia, funcţia
returnând un anumit câmp al înregistrării respective. În caz de nereuşită indicatorul de
înregistrări se poziţionează după ultima înregistrare a bazei de date iar funcţia va
returna şirul vid. Sintaxa acestei funcţii este următoarea:
LOOKUP ( câmp1 , expr , câmp2 [, expC ])
în care câmp1 reprezintă câmpul a cărui valore va fi returnată de funcţie, în caz de
căutare reuşită. expr specifică expresia de căutat în fişier, câmp2 se foloseşte
pentru a realiza căutarea expresiei numai în acest cîmp ; expC se foloseşte pentru
baze de câmp indexate. Rezultatul este de tip şir de caractere, numeric,logic sau data
calendaristică, în funcţie de tipul de câmp returnat.
Exemplul 19
CLOSE ALL
LIST student
? LOOKUP (nume,231,grupă)
?RECNO()
2
USE
INDEXAREA TABELELOR
In prealabil baza de date care o sortez trebuie deschisa iar baza de date sortata
trebuie si ea deschiosa si sortata .
166
SORT ON< campul dupa care se sorteaza >[A/C/D]
TO<nume tabela sortata> FOR< conditie de sortare >
INDEX ON <campul dupa care se indexeaza >TO <fisierul simplu index ce se creaza
>|TAG <cheia principala daca am mai multe campuri de indexat>[ OF <fisierul de
unde iau campurile de indexare >][ FOR L<conditie de indexare >][COMPACT]
[ASCENDING][DESCENDING] [ADDITIVE]
Comanda SELECT
Proiectarea vizuala a interogarilor simple si incrucisate
Fisiere View
Query Designer
Sub numele de interogare sau cerere sunt referite acele solicitari de date in mod direct
fara indicarea de obtinere.
O cerere SQL se poate lansa din fereastra de comenzi sau din interiorul unui program
FoxPro pentru ca ea functioneaza ca orice alta comanda dar se poate proiecta intr-un mod
interactiv cu ajutorul utilitarului Query Designer.
Definirea interogarilor prin comanda SELECT
Comanda SELECT -SQL permite specificarea datelor care vor constitui iesirea din
interogare precum si sursa acestora . Cum se vor obtine aceste date ramane in sarcina
optimizatoruluide cereri Rushmore
Clauza ALL/DISTINCT determina prelucrarea tuturor inregistrarilor (ALL) sau
numai a articolelor unice (DISTINCT).
Clauza <col1>[AS <nume 1>]…permite definirea coloanelor care vor constitui iesirea din
interogare . Coloanele pot fi campuri apartinand tabelelor definite in clauza
167
FROM ,constante ,expresii,functii utilizatori .Coloanele pot primi un alt nume prin clauza
AS .
Pot fi utilizate functii cum sunt:
AVG(<exp>) calculeaza media aritmetica COUT(<art selectat>) numara selectiile,SUM (<art
-selectat>) calaculeaza suma,MIN(<art-selectat>),MAX(<art -selectat) determina extremul.
Clauza FROM specifica listalista fisierelor de intrare in prelucrare.
Destinatia rezultatelor se specifica prin dour clause:INTO/TO dintre care INTO este
prioritara.Clauza INTO <det_into> determina forma de stocare a datelor.<Dest_into> poate
fi:ARRAY <tablou>/CURSOR<fis>/DBF<fis.dbf>.Forma de stocare cursor este o tabela
temporara ,de tip “READ ONLY”,stearsa automat in momentul inchiderii ei.Clauza TO
<dest_to>se foloseste atunci cand lipseste clauza INTO.<Dest_into> poate fi :TO FILE
<>fis.txt>[ADDITIVE]/TO PRINTER [PROMPT]/TO SCREEN unde TO FILE
directioaneaza iesirea catra un fisier catre un fisier ASCII (fie prin suprascriere ,implicit,fie
prin adugarea datelor la vechiul contin daca este prezenta cluza ADDTIVE),TO PRIN catre
imprimanta,iar TO SCREEN catre ecran.
Exemplu:
1. Afisati elevii claselor la imptimanta. Select cls,nume from elevi to print
2. Copiati elevii intr-o alta baza da date. select cod,nume from elevi into dfb
manelevi.dbf
Clauza WHERE <cond> permite introducerea legaturilor intre tabele si a filtrelor .Conditiile
<cond> sugereaza sistemului FoxPro sa includa anumite inregistrari in rezultatele cererii.
Exemple:
Care sunt elevii cu medii intre 8si 10 din clasa select nume,med from elevi
A “12A”. where med between 8 and 10 and cls =”12A”
Care sunt elevii cu media 10 precum si numele select elevi.nume,elevi.cls,
Dirigintilor lor .Care sunt elevii dirigintelui X?clase.diriginte from elevi,clase
Where elevi.cls=clase.cls and elevi.med=10
Accept ‘nume professor diriginte?; to x
Select elevi .nume,elevi.med from elevi,
Clase where clase.cls=elevi.cls;
And clase.diriginte=x
168
-trebuie lucrat direct cu numele de baze de date, campuri; nu dispune de nici un dictionar de
date.
Crearea unui fisier de cereri se face interactiv prin deschiderea ecranului de
proiectare QUERY DESIGN din meniul File-New-Query sau prin comanda
CREATE/MODIFY QUERY . Se va crea un fisier cu extensia(.qpr) pe care il vom numi fisier
de cereri si care va putea fi executat tot prin comanda DO (fis qpr) .
Pasul1 vom apela generatorul de interogari prin FILE -NEW-QUERY-NEW sau prin
comanda Create Query.
Se deschide o fereastra de proiectare cu mai multe parti si un meniu .
Meniul Query
Meniul contextual se deschide, asa cum stim , prin butonul drept al mouse-ului si contine
cateva actiuni legate de Query cum ar fi: executie(run), adaugarea unei tabele(add table),
stergerea unei tabele (remove table) , vizualizearea comenzi Select(view SQL), deschiderea
ferestrei cu butoane pentru alegrerea destinatiei Query(output setting)
Pasul 2. In fereastra de proiectare a interogarii vom deschide tabelele . Tabelele, incluse sau
nu intr-o baza de date , trebuie deschise pe rand in aceasta fereastra folosind fie meniul
contextual fie meniul principal Qyery.
Deci vom deschide fisierele Contracte si Facturi. Pentru ca legatura dintre ele era
definite la nivelul bazei de date observam conservarea ei. Legatura este Contracte-Facturi de
tip 1-n
Atentie-Daca dorim sa afisam structura sau datele dintr-un fisier deja trecut in fereastra de
proiectare , vom plasa cursorul pe titlul tabelei in meniul View aparand optiunea Browse care,
asa cum stim , asociaza si meniul Table folosit pentru modificare\ indexare\filtrare.
Pasul 3.Vom fixa coloanele rezultat ale cererii in tab-ul Fields prin mutarea campului selectat
din fereastra Available Fields sau a expresiei \ functiei construite cu generatorul de expresii in
fereastra Functions , in fereastra Select fields.
Pentru ca in dorim sa se afiseze nr. De facturi (gruparea pe contracte o vom defini
mai tarziu ) vom alege una dintre functiile numerice : COUNT ( facturi . nr_fact.) . Pentru
valoarea contractului vom defini expresia contracre. can+ contracte . prêt_promis. Pentru
facturata putem scrie SUM (facturi , cant+facturi . prêt) AS val-facturata atribuind un nume
coloanei.
In general pentru grupuri se pot folosi functiile urmatoare:
COUNT() -numara inregistrarilegrupului.
SUM(…) - insumeaza valorile pentru toate inregistrarile grupului.
AVG(…) - calculeaza media valorilor articolelor din grup.
MIN(…) - extrage valoarea minima a expresiei din grup .ul query-clue se face prin caseta
Number f
MAX(…) - extrage valoarea maxima din grup .
COUNT(DISTINCT) - numara aparitiile grupului .
SUM (DISTINCT) - insumeaza valorile pentru articolele distincte etc.
Pasul 4. Vom fixa conditia de legatura prin tab-ul Join.
Tipuri de legaturi:
INNER JOIN-numai articole commune care satisfac crtiteriul
LEFT OUTER JOIN-toate inregistrarile din tabela din stanga si cele care satisfac
criteriul din drapta
RIGHT OUTER JOIN-toate articolele dindreapta reklatiei si numai care satisfac
criteriul din tabela din stanga
FULL JOIN -toate articoleledin ambele tabele
Pasul 5.Vom fixa conditia de filtrare prin tab-ul Filter.
Pasul 6.Vom fixa campurile de ordonare prin tabul Order.
Pasul 7.Vom specifica grupul prin Group By.Calculele se fac prin
functiile:AVG,COUNT ,MAX,MIN,SUM.
Pasul 8. Vom fixa alte conditii ale interogarii prin tabul Miscellaneous
No duplicates
Cross tabulate
169
Stabilirea unui numar sau procent de vizualizare din rezultatul query-lui se face prin caseta
Number of records sau comutatorul Percent.Pasul 8.vom vizualiza comanda SELECT
generata de Query Designer fie prin meniul principal sau contextual fie prin butonul de pe
toolbar cu caleasi nume view sql.pasul
Pasul 9.Vom allege destinatia finala a rezulatatelor interogarii prin meniul principal ,prin
toolbar sau din meniul contextual.
Ecranul |Query destination permitre alegerea dintre:
a) browse-afisare in fereastra browse
b) cursor-afiasre intr-o tabela temporara
c) table/dbf-nformatiile sunt scrise intr-o tabela
d) garph-reprezentari grafice
e) screen-datele sunt afisate pe ecran
f) report-afisrea sub forma de raport
g) label-afiasrea sub forma unei etichete
Pasul 10.vom verifica modul de construire prin butonul run observand rezulatele din fereastra
browse
Pasul 11. Vom salva si vom inchide generatorul query designer
Pasul 12.vom lansa in executie prin comanda DO fis.qpr.
b. Proiectarea rapida a interogarilor cu Query Wisard
pentru proiecterea rapida a interogarilor dispunem de asistentul Query wisrd apela t din
Tools-wisard-query.In fereastra de dialog deschisa vom allege query wizard
Pasul 1. selectarea campurilor care vor forma iesirea dorita din interogare .
Pasul 2.Daca sunt mai multe tebele se cere specificarea relatiei.
Pasul 4.Se fixeaza campurile de ordonare.
Pasul 5. Se salveaza ca fisier .Qpr.
c. Poiectarea interogarilor incrucisate cu Cross Tab wizard
O incrucisare sete rezultat unei interogari speciale care permite analizarea relatiei
dintre un camp al tabelei de date si alt camp al aceluias table.
Proiecatrea fisierelor View
Spre deosebire de interogari vederile ,perspectivele sau imaginile sunt fisiere care se
pot modifica si transmit aceste corectii tabeleor sursa din care sunt create.Pespectivele sunt de
dour tipuri:locale sau la distanta
a. Proiectarea fisierelor vedere prin View Designer
Apelul utilitarului pentru crearea unui view sw face fie direct prin meniul system file -New-
View fie prin tastarea comenzii CREATE VIEW in fereastra de comenzi
Trebiue stiut ca :
Un camp cheie nu pote fi modificat
Se pot modiifca doar campurile marcate pentru aceasta operatie
Schimbarea setarii initiale a indicatorilor asociatia cooaneleor view-ului se face prin
pozitioanrea pe numele campului si selectarea comutatorului corespunzator
comutatorul Send SQL Updates care trebiue activat pentru a se putea folosi view-ul la
actaulizarea datelor din surse
partea dreapta a ferestrei update se foloseste pentru view0uri la distanta si o vom
discuta la lectia uarmatoare.
B.Proiectarea rapida a vederilor cu Local View Wizard
Pentru localizarea rapida a unei vederi se poate folosi asistentul Lacl View wizard
prin Tools-wizard -Query-local wiev.Utilitarul parcurge de fapt aceleasietape ce si vrajitorul
pentru interogari insa in loc sa salveze rezultatul intr-un fisier de interogare il salveaza in
definitia unei vederi in baza de date deschisa .Asistentul realizeaza de fapt o vedere care nu
este actualizabila.
Proiectarea interogarilor cu exteriorul aplicatiei
Accesarea datelor situate le distanta ,View Designer ,Remote View Wizard
Publicarea datelor pe internet ;Web Publishing Wizard
Proiectarea documentelor pentru E-mail
Prooiectarea fisierelor perspectiva cu date situate la distanta
170
Pasi:
1. Stabilirea unei conexiuni la distanta cu alta baza de date ,se realizeaza astfel:se
deschide aplicatia Control Panel si se selecteaza pictograma ODBC pentru a vedea ce surse de
date sunt disponibile
2. se deschide FoxPro.
3. se deschide o baza de date
4. se apeleaza File-New-Connectivity
5. se apeleaza generatorul de vederi prin File-New-remote view-new
6. se adauga tabelele necesare din baza de date
7. se dauga criteriile de selectie prin tab-ul join
8. se filtreaza ,se stabileste ordinea ,gruparea ,criteriile de catualizare la fel ca si in cazul
unei vederi locale
9. se precizeaza conditiile de acceptare a actalizarilor prin update criteri
Por exista anumite conflicte de cataulizrea tinand cont ca in conditiile existentei mai multor
utilizatori acceasi tabela poate fi solicitata la atualizare simultan de la mai multe
statii.Clauzele SQL WHERE ne ajuta in aceasta privinta:
key fields only-se efectueaza actualizarile atata vreme cat campul cheie al tablei sursa
nu s-a modificat
key and uptable fields-interzice atualizarea atunci cand oricare dintre campurile
marcate pentru actualizare si-a schimbat valoarea in tabela de la distanta
key and modified fields- interzice actualizarea daca pentru un camp a carui valoare s-
a modificat local valoarea acestuia secshimbase si in tabela sursa
key and timestamp-interzice atualizarea daca valoarea cheii sau a amrcii temporare a
fosta modificata in tabela initiala
171
pot sa fac grupari,filtrari de date ,functii statistice si sa anulez duplicatele sa aduc tabele:
172
2. 2. relaţie unul-la-mai-mulţi (notată 1:N), în cazul în care fiecărui
element al primei entităţi îi pot corespunde mai multe elemente din
a doua entitate, dar fiecărui element din a doua entitate îi
corespunde cel mult un element din prima entitate.
3. 3. relaţie mai-mulţi-la-mai-mulţi (notată M:N), în cazul în care
fiecărui element al primei entităţi îi pot corespunde mai multe
elemente din a doua entitate şi reciproc.
e. e. Informaţiile privind structura unei vederi sunt sintetizate grafic
într-o diagramă entitate-relaţie, care pune în evidenţă entităţile ce
intervin, reprezentate prin dreptunghiuri, atributele asociate lor
reprezentate prin elipse, şi diferite relaţii ce se stabilesc între entităţi
reprezentate prin săgeţi (cu vârf dublu către entitatea pe care pot
apărea mai multe elemente în relaţie cu un element din cealaltă
entitate).
STABILIREA RELATIILOR
Inainte de a incepe legarea bazelor de date trebuie sa va asigurati ca sunteti in forma ecran
“View” a ferestrei “View”.Toate fisierele pe care doriti sa le legati trebuie sa fie deschise in zone de lucru
distincte.
Din lista zonelor de lucru,selectati baza de date care va deveni baza de date parinte.Alegeti
butonul Relations.Numele bazei de date parinte va apare in lista Relations cu o sageata care pleaca din
el.In continuare,din lista zonelor de lucru,selectati baza de date legata.
Daca baza de date legata este indexata si are stabilit indexul principal,va fi activat
generatorul de expresii.Daca baza de date legata este ordonata dupa un camp care exista identic in
baza de date parinte,FOXPRO va introduce automat acel camp in expresia de legatura.Puteti schimba
acest camp sau puteti crea alta relatie de legatura.
Daca baza de date legata este indexata dar nu are stabilit indexul principal,va apare un
dialog Set Index Order pentru a stabili indexul principal in maniera discutata la indexare.
Daca baza de date legata nu este indexata,FOXPRO presupune ca doriti sa creati o expresie
de legatura bazata pe numarul de articole.
Cand expresia de legatura are forma dorita,alegeti optiunea <<OK>> si observati in fereastra
“View” stabilirea relatiei.
UTILIZAREA INFORMATIILOR DIN
MAI MULTE BAZE DE DATE
173
O aplicatie complexa lucreaza cu informatii multiple,aranjate in mai multe baze de date.Scopul
fragmentarii este acela de a conferi viteza de lucru,de a nu gestiona inutil,in diferite parti ale
aplicatiei,informatii care nu se prelucreaza si,nu in ultimul rand,acela de a conferi siguranta datelor
manipulate.Vulnerabilitatea datelor scade prin fractionarea lor.
Informatiile atasate unei aplicatii pot exista in mai multe baze de date,dar,in general,aceste baze
de date sunt legate pe baza unui camp comun,unic in fiecare articol.Acest camp se numeste camp
cheie si are rol esential in utilizarea informatiilor distribuite in mai multe baze de date.
FOXPRO permite utilizarea simultana a maximum 25 de baze de date.Pentru fiecare baza de
date,sistemul de gestiune rezerva o zona de lucru curenta,numerotata de la 1 la 25 (sau de la A la J si
de la 11la 25).Programatorul are acces la un moment dat numai la o singura zona de lucru;aceasta
zona de lucru se numeste “zona de lucru curenta”.Zona de lucru curenta poate fi modificata de
programator prin selectare.Vom explica cele spuse anterior printr-un exemplu.
Exemplu:
Consideram doua fisiere baza de date CLIENTI.DBF cu structura:
Cod_client N 7
Den_client C 35
Cont_banca C 15
Den_banca C 20
Cont_cec C 15
Adresa C 25
Den_loc C 20
Telefon C 12
Fox C 12
Si FACTURI.DBF cu structura
Nrf N 8
Dataf D 8
Cod_ben N 7
Val_fact N 14 2
SELECT 1
USE CLIENTI
SELECT 2
USE FACTURI
Deci instructiunea de selectare a zonei de lucru este SELECT si poate avea urmatoarea sintaxa:
SELECT n|alias
Implicit este activa zona de lucru 1.Puteti selecta o anumita zona de lucru precizandu-i numarul prin
n.SELECT 0 are ca efect
selectarea zonei de lucru ne folosite cu cel mai mic numar de ordine.
Dupa deschiderea unei baze dedat intr-o anumita zona,acesta poate fi selectata prin aliasul
sau.Aliasul implicit al unei baze de date este numele sau (fara extensia.DBF).Se poate atribui bazei de
date un alt nume _alias decat numele implicit prin specificarea lui in comanda USE astfel:
USE…ALIAS nume_alias
Un nume_alias poate fi format din maximum 10 caractere (litere,cifre si liniuta de subliniere) si
incepe obligatoriu printr-o litera sau cu liniuta de subliniere.
Specificarea campurilor dintr-o baza de date deschisa in alta zona de lucru decat zona curenta se
face cu ajutorul numelui_alias astfel:alias.camp sau alias->camp.
Inchiderea bazelor de date deschise in diferite zone de lucru se face prin selectarea fiecarei zone
in parte si inchiderea bazei de date din zona respectiva astfel:
SELECT 1
USE
174
SELECT 2
USE
1. Pe baza numarului de secventa a articolelor din bazele de date in cauza (se presupune de
regula,ca bazele de date au acelasi numar de articole);este o legatura fizica intre bazele de date;
2. Pe baza unei chei de indexare;prin acest procedeu,frecvent utilizat,se stabileste o legatura logica
intre articolele din bazele de date deschise simultan.
In ambele cazuri,sistemul gestioneaza pointeri de articol pentru fiecare zona de lucru .Pointerii se
pot sincroniza prin comanda:SET RELATION.
Formatul comenzii este:
Comanda SET RELATION stabileste o relatie intre doua baze de date deschise.Inainte de a
stabili relatia,o baza de date (baza de date parinte sau principala ) trebuie deschisa in zona de lucru
curenta iar cealalta(baza de date fiu sau legata) sa fie deschisa in alta zona de lucru.
Dupa crearea relatiei, o mutare a pointerului de articol in baza de date parinte,este insotita de
mutarea pointerului de articol in baza de date legata pe articolul corespunzator.Daca nu se gaseste un
articol corespondent in baza de date legata,pointerul de articol din baza de date fiu este pozitionat la
sfarsitul bazei de date.
Expresia de legatura expr_1este de obicei cheia de indexare a indexului principal al bazei de date
fiu.
INTO n1 | alias1,indica prin numar sau alias,zona de lucru in care este deschisa baza de date fiu.
Comanda SET RELATION TO anuleaza toate relatiile de legatura ale bazei de date din zona de
lucru curenta .
Se pot crea mai multe relatii de legatura intre baza de date din zona de lucru curenta si baze de
date deschise in alte zone de lucru prin precizarea mai multor relatii separate prin virgula in forma
comenzii.
Utilizarea clauzei ADDITIVE are ca efect pastrarea tuturor relatiilor stabilite in zona de lucru
curenta,anterior.In caz contrar acestea sunt anulate.
Exemplu:
Considerand bazele de date descrise anterior si tinand cont de faptul ca in baza de date
FACTURI campul cod_ben constituie codul unui client,printr-o relatie intre cele doua baze de date
astfel:
SELE 1
USE clienti
INDEX ON cod_client TO codcind
SELE 2
USE facturi
SET RELA TO cod_ben INTO clienti
BROW FIELDS nrf,dataf,clienti.den_client,valf
Un caz particular al relatiilor intre bazele de date il constituie legatura”Unu la n” (1-To –Many).O
legatura”Unu la n”,pune in corespondenta mai multe articole din baza de date fiu,unui singur articol din
baza de date parinte .
Cand se prelucreaza baze de date legate prin legatura”Unu la n”,pointerul de articol ramane pozitionat
pe un articol din baza de date parinte,pana se prelucreaza toate articolele care ii corespund in baza de
date fiu.
Stabilirea unei relatii”Unu la n” se realizeaza intr-o maniera similara cu cea pentru stabilirea unei
relatii “Unu la unu”.Se incepe cu stabilirea unei relatii normale “Unu la unu” intre fiu si parinte (prin
175
comanda SET RELATION) dupa care se foloseste comanda SET SKIP pentru a transforma legatura
stabilita intr-o legatura”Unu la n”.]
Sintaxa comenzii SET SKIP este urmatoarea :
Daca baza de date parinte este legata de mai multe baze de date fiu (care au aliasurile alias1,
alias2, …) atunci relatiile respective pot fi transformate in relatii”Unu la n”printr-o comanda SET SKIP.
In comenziile care au efect asupra unui anumit domeniu de articole
(DISPLAY,LIST,etc.),articolele din baza de date parinte se vor repeta pentru fiecare articol
corespondent din baza de date fiu.
Anularea unei relatii “Unu la n” se realizeaza cu comanda SET SKIP TO (fara parametrii).
Exemplu:
In exemplul antertior s-a considerat ca parinte baza de date FACTURI iar baza de date CLIENTI
a fost considerata baza de date fiu.Daca schimbam modul de abordaresi consideram baza de date
CLIENTI ca baza de date parinte si baza de date facturi ca baza de date fiu si tinem cont de faptul ca
unui client ii pot corespunde mai multe facturi putem evidentia o relatie “Unu la n” astfel:
SELE 1
USE CLIENTI
SELE 2
USE FACTURI
INDEX ON cod_ben to FACTBEN
SELE CLIENTI
SET RELA TO cod_client INTO FACTURI
SET SKIP TO FACTURI
BROWSE FIELDS facturi.nrf,facturi.dataf,;den_client,facturi.valf
11.Reţele. Internet
11.1 Reţele de calculatoare, clasificarea reţelelor, protocoale
de reţea (noţiuni generale)
Structura reţelelor de calculatoare
Două sau mai multe calculatoare pot să facă schimb de date între ele prin două modalităţi:
On line – schimbul de date realizându-se prin intermediul unui cablu electric sau linii de
comunicaţie.
O reţea se formează atunci când mai multe PC sunt conectate unele la altele, astfel încât să
poată comunica între ele.
Dacă reţeaua este compusă din PC aflate în acelaşi loc este numită reţea locală (LAN).
Acestea sunt calculatoare care de obicei se afla în acelaşi departament, secţie de lucru sau sediu de
firma. O reţea locală a unei firme este denumită intranet, pentru a face distincţia de internet. Accesul la
intranet este în general limitat la angajaţii unei firme. Informaţiile existente în intranet sunt informaţii ale
firmei, şi deci intră din punct de vedere juridic şi organizatoric sub incidenţa secretului de serviciu.
In cazul în care calculatoarele sunt răspândite pe o arie mult mai mare, reţeaua este numită
reţea de mari dimensiuni (WAN). Aceste reţele pot fi alcătuite din calculatoare aflate în oraşe sau ţări
diferite.
176
Internet-ul este un conglomerat la scară mondială de reţele de calculatoare. Internetul nu este
proprietatea nici unei firme şi nu este coordonat de nici o firmă şi reprezintă o reţea de reţele de
calculatoare care pot comunica între ele.
Majoritatea reţelelor sunt formate din câte un server şi clienţii conectaţi la reţea.
O reţea de calculatoare oferă o gamă largă de avantaje, printre care putem enumera:
Resursele pot fi partajate între calculatoare (de exemplu modemuri, imprimante, etc);
Intr-o reţea locală de componente similare (tip Peer-to- peer) toate staţiile de lucru sunt
interconectate şi partajează imprimantele, fişierele, dosarele şi alte resurse. Toate persoanele care
folosesc reţeaua îşi salvează fişierele în propriile calculatoare, ceea ce face ca gestionarea fişierelor să
fie dificilă. Aceste reţele nu trebuie să includă mai mult de 10 calculatoare.
Intr-o reţea client-server, informaţiile sunt stocate mult mai eficient, prin intermediul calculatorului
principal folosit ca server de fişiere, în care toţi utilizatorii reţelei îşi salvează propriile date. Serverul de
fişiere este de regulă un calculator ce se află de obicei într-o cameră specială separată şi nu este folosit
individual.
Utilizatorii trebuie doar să ştie să se conecteze la reţea şi să acceseze resursele care sunt puse
la dispoziţie de către administrator. In Windows 95, dacă este folosită o reţea, pe suprafaţa de lucru
apare pictograma denumita Network Neighborhood, care prin activare afişează punctele de acces la
calculatoarele şi imprimantele din reţea. Dosarul Entire Network, a cărui pictogramă apare în dosarul
Network Neighborhood, afişează punctele de acces la resursele de calculatoare din afara grupei de
lucru.
După deschiderea ferestrei Network Neighborhood, se execută dublu clic pe un server sau alt
calculator din fereastră, pentru a vedea ce resurse sunt la dispoziţie pentru solicitant. Apoi se activează
dosarul sau un periferic cu care se lucrează ca şi cum ar aparţine calculatorului solicitant. Pentru
aceasta se foloseşte bara orizontală superioară.
Pentru închiderea ferestrei Network Neighborhood se foloseşte aceeaşi metodă ca pentru orice
fereastră Windows 95, selectând din meniul File opţiunea Close din meniul ferestrei sau executând clic
pe butonul Close (X) din coltul din dreapta sus al ferestrei. Inchiderea ferestrei nu determină
deconectarea de la reţea, decât atunci când se comandă întreruperea legăturii sau este închis
calculatorul.
177
11.2 Reţeaua Internet – descriere generală, adresarea în
Internet
Utilizarea internetului
a. Scurt istoric
In 1986, Fundaţia Naţională pentru ştiinţă a SUA a creat NSFNET (National Science Fondation
Network) pentru a conecta supercalculatoarele de mare viteză din SUA, aceasta din raţiuni ştiinţifice.
Această ultimă reţea a preluat şi reţelele ARPAnet.
Dezvoltarea reţelei Internet a fost spectaculoasă, astfel că în 1985 erau conectate aproximativ
2.000 de calculatoare, în 1997 cca. 9 milioane de calculatoare.
In prezent oricare posesor al unui calculator conectat la o linie telefonica poate avea acces la
Internet.
World Wide Web (WWW) sau pe scurt Web, este uriaşă colecţie de documente care conţin
informaţii ce sunt păstrate pe calculatoare răspândite în toată lumea. WWW a fost creat în
Elveţia la Centre Europeen de Recherche Nucleare (CERN). Documentele sunt create cu o
tehnologie specială, numită hipertext. Mulţi pun semnul egalităţii între Internet şi Web,
întrucât Web-ul are cea mai mare pondere în serviciile Internet. De altfel a apărut expresia Surf
in Web, care înseamnă plimbare prin Internet.
Use Net, protocol ce poate fi folosit pentru cuplarea la grupurile de discuţii, pentru a colabora
cu alţi colaboratori conectaţi la Internet.
Internet Relay Chat, poate fi folosit pentru a purta conversaţii în direct, chiar se pot organiza
conferinte video şi audio.
178
Pentru a lucra în Web sunt folosite mai multe protocoale:
Internet protocol (IP), fiind cel mai simplu protocol de comunicare între calculatoare;
Transmission Control Protocol (TCP), care este mai performant decât cel de mai sus
întrucât asigură corectarea erorilor de transmisie.
Deoarece cele două protocoale prezentate mai sus sunt folosite de regulă împreună, ele sunt
menţionate mereu împreună sub forma TCP / IP.
File Transfer Protocol (FTP), defineşte modul în care este transferat un fişier generic dintr-
un calculator în altul. fişierul poate fi de forma: document, program, o imagine, etc.
Hyper Text Markup Language (HTML), care defineşte o metodă de adăugare a atributelor
de formatare în fişierele de text, pentru a fi vizualizate fişierele de text citite ca nişte titluri,
paragrafe centrate şi imagini înglobate.
Hyper Text Transfer Protocol (HTTP), defineşte modul în care calculatoarele transmit
fişierele HTML în ambele direcţii.
WWW este o colecţie de milioane de documente cu diferite informaţii care sunt păstrate pe
calculatoare răspândite în întreaga lume. Pentru a uşura accesul la aceste informaţii se dau în
continuare câteva definiţii:
Situl Web este o colecţie de pagini Web, care aparţin aceleaşi instituţii sau persoane;
Pagina sursă (Home Page) este pagina principală dintr-un sit Web;
Hipertextul reprezintă metoda folosită pentru a organiza informaţia în reţeaua Web.
Folosindu-se această metodă, textele sau imaginile evidenţiate într-un document reprezintă
trimiteri la alte documente care conţin informaţii suplimentare;
Hypermedia reprezintă o extindere a metodei hypertext, prin care trimiterile sunt extinse şi la
alte medii cum sunt sunetele şi imaginile video;
URL (Uniform Resource Locator) reprezintă adresa unei locaţii cu informaţii din reţeaua
Internet. Aceasta este formată din trei părţi:
Numele protocolului. Precizează tipul resursei Internet. In tabelul 8.3 sunt prezentate
câteva tipuri de resursă.
Numele gazdei. Prezintă numele calculatorului pe care este stocată informaţia.
Calea fişierului. Precizează numele fişierului în care se găseste informaţia şi calea de
cataloage până la catalogul în care se află fişierul.
Browserul este un program care ajută la găsirea şi citirea informaţiilor în documentele html
ale reţelei Web şi asigură următoarele operaţii mai importante:
179
Folosirea semnelor de carte şi a istoricului pentru regăsirea rapidă a informaţiilor;
Internet Explorer a fost creat de Microsoft şi inclus în sistemele de operare Windows 95
şi 98.
Netscape Navigator, care a fost creat de Netscape Communication Corporation, poate fi
folosit în sistemele windows 95 şi 98.
Poşta Internet – Email-ul este o formă modernă de comunicare, ce combină rapiditatea unui apel
telefonic cu înregistrarea şi expedierea unei scrisori. Transmiterea scrisorii durează doar câteva
secunde, iar destinatarul poate răspunde când doreşte şi în plus nu trebuie contactat direct destinatarul
pentru transmiterea scrisorii.
Un alt avantaj al poştei electronice este preţul scăzut al abonamentului, de cca. 2…3 $ pe lună şi
respectiv costul scăzut al transmisiei şi recepţiei scrisorilor prin E-mail, care se taxează pentru
impulsurile telefonice de câteva secunde dintre abonat şi server, server care se află de obicei în acelaşi
oraş cu abonatul.
O adresă de E-mail are două părţi, Prima parte este numele utilizatorului sau orice alt nume ales de
utilizator urmată de semnul @ şi a doua parte este numele contului de la posta electronică urmat adesea de
simbolul tării în care se află serverul. De obicei numele contului se confundă cu numele serverului la care
este abonat calculatorul gazdă. Deci o adresă poate fi scrisă sub forma: aalecu@fx.ro unde aalecu
reprezintă numele utilizatorului calculatorului gazdă., fx numele serverului şi ro prescurtarea de la România.
In caz că nu apare numele tării, se subînţelege că serverul se află în SUA şi în general aparţine de una din
următoarele şapte domenii de organizaţie diferite, aşa cum se observă din Tabelul 8.1
Tabelul 8.1.
Cod Domeniu
.com Entităţi comerciale
.edu Instituţii educaţionale
.gov Instituţii guvernamentale non-militare ale SUA
.int Instituţii internaţionale (NATO).
.mil Instituţii militare SUA.
180
.net Resurse de reţea
.org Organizaţii non-profit.
Pentru utilizarea poştei electronice, firma gazdă la care se face abonamentul pentru E-mail
livrează clientului pachetul de programe care asigură funcţia de agent utilizator, printre care enumerăm:
Eudora.
Cu Outlook Express Mail se poate trimite mesaje prin E-mail oricărei persoane a cărei adresă de
E-mail există pe Internet, intranet şi post individual abonat la un server. Se pot trimite în plus fişiere,
rapoarte, scrisori şi foi de calcul tabelar – sub formă de anexe la mesajele transmise. De obicei
programul Outlook Express Mail este folosit de clienţii abonaţi la Internet.
Eudora este un pachet de programe folosit de obicei de clienţii abonaţi la o postă electronică (un
server), numai pentru E-mail.
Administrarea mesajelor primite: vizualizarea, arhivarea pe disc sau tipărirea lor, ştergerea;
Antetul (Header), care este un text cu care începe mesajul. Conţine informaţii despre destinatar,
autor, subiect şi ora transmisiei;
Semnătura (Signature), care este un text care se adaugă la sfârşitul mesajului poştal, şi
cuprinde cel puţin numele autorului. Mulţi autori introduc de obicei în plus numele firmei şi
numărul de telefon unde pot fi contactaţi.
181
La compunerea unui mesaj, este bine să se ţină cont de anumite facilităţi pe care programele
de postă electronică le asigură, prezentate în
Tabelul 8.2.
Facilitatea Semnificaţia
Pseudonim (Alias) Permite să se definească nume alternative, scurte
şi familiare pentru anumiţi utilizatori.
Copii (Carbon Copy) Permite să se transmită mesajul la mai multe
adrese.
Inserarea de fişiere Permite înserarea de fişiere în corpul mesajului.
(Including File)
Lista de adrese Se defineşte o lista de adrese sau grupuri de
(Mailing List) adrese cărora li se pot trimite mesaje prin
E-mail-uri .
Confirmarea primirii Permite trimiţătorului unui mesaj să primească
(Receipt Notification) confirmarea sosirii la destinaţie a mesajului.
Transmiterea unui mesaj se realizează în acelaşi mod, indiferent de clientul de postă (serverul)
folosit:
Se apelează butonul aferent (New, Compose) pentru a se deschide o nouă fereastră de
mesaj;
- To – Se scrie adresa de E-mail sau se activează săgeata din dreapta câmpului şi apare
lista de adrese din care se alege destinatarul mesajului
- Cc – Se scrie o listă de adrese la care se pot trimite copii ale mesajului;
- From – Automat, adresa expeditorului şi data transmiterii sunt completate de computer.
Se execută clic pe un buton din fereastră pentru a expedia mesajul. Acest buton este
denumit de obicei Send;
Se face conectarea la reţea şi se execută clic pe comanda de expediere ( Send / Send
Only), şi / sau pe cea de expediere şi primire mesaje (Get All) sau alte comenzi similare pe
care le asigură programul. După ce s-a transmis mesajul, conţinutul acestuia este mutat
automat în dosarul Send items.
Dacă se doreşte doar primirea unor mesaje depuse la server, se face conectarea la reţea
prin comanda Get Mail sau alta asemănătoare, funcţie de programul folosit.
182
Se poate răspunde la un mesaj în mai multe moduri:
Răspuns către expeditor (Reply). In acest caz adresa destinatarului este completată automat,
fiind preluată din adresa expeditorului la al cărui mesaj se răspunde. Răspunsul poate fi de
două feluri, cu păstrarea textului sosit sau fără păstrarea lui în răspuns. La clicarea pe
butonul (Reply), apare mesajul (Quote original message) la care se poate răspunde cu
(Yes) sau (No).
Reexpedierea mesajului (Forward), acţiune prin care mesajul este retransmis către un alt
destinatar. Adresa expeditorului iniţial este înlocuită cu adresa utilizatorului care reexpediază
mesajul;
Redirecţionarea mesajului (Redirect), prin care mesajul este transmis către un alt destinatar,
păstrându-se ca adresă de expeditor, adresa expeditorului iniţial.
Dacă este folosită posta electronică, nu este nevoie de fax sau oficiu poştal pentru a trimite
documente. Acestea pot fi ataşate la un mesaj şi trimise destinatarului.
Pentru a ataşa un fişier la un mesaj, se trage cu mouse-ul fişierul din Windows Explorer şi se
plasează în corpul mesajului cu care trebuie transmis. Va apare o pictogramă şi numele fişierului în
corpul mesajului. Se pot ataşa oricâte fişiere în corpul unui mesaj.
In cazul utilizării programului Outlook Express Mail, se alege din meniul principal Insert, opţiunea
File Attachment. Apoi se alege fişierul dorit din caseta de dialog File Attachment şi în final se execută
clic pe Attach. Va apare un panou în partea de jos a ferestrei în care se află textul mesajului, care va
conţine câte o pictogramă pentru fiecare fişier ataşat la mesaj.
In cadrul programului Outlook Express, se poate afişa conţinutul unui fişier ataşat, efectuând
dublu clic pe icoana aferenta..
183
Se pot economisi timp, efort şi bani, comprimând fişierele înainte de a le ataşa la un mesaj de
postă. Pentru a crea un fişier Zip şi a adăuga fişiere în el, se vor executa următoarele manevre:
Se execută apoi clic-dreapta pe fişierele selectate şi în continuare se va alege comanda Add
to Zip. Dacă această comandă nu apare, înseamnă că programul WinZip nu este instalat pe
PC.
Se execută apoi clic pe Add, iar WinZip va adăuga fişierele selectate în fişierul ZIP.
După examinarea conţinutului fişierului ZIP, se închide WinZip executând clic pe butonul X
din bara de titlu. Acum fişierul comprimat poate fi ataşat la mesajul E-mail.
Extragerea unui fişier ZIP ataşat la un mesaj de postă E-mail, se face după cum urmează:
Se execută dublu-clic pe pictograma fişierului ZIP din cadrul mesajului. Programul WinZip va
afişa conţinutul fişierului.
Se alege din meniul principal Action, Extract şi se va vizualiza caseta de dialog Extract.
Se execută dublu-clic pe fişierul ZIP din mesajul E-mail şi în cadrul programului WinZip va fi afişat
conţinutul fişierului ZIP.
World Wide Web (WWW) sau pe scurt Web, este uriaşă colecţie de documente care conţin
informaţii ce sunt păstrate pe calculatoare răspândite în toată lumea. WWW a fost creat în
Elveţia la Centre Europeen de Recherche Nucleare (CERN). Documentele sunt create cu o
tehnologie specială, numită hipertext. Mulţi pun semnul egalităţii între Internet şi Web,
întrucât Web-ul are cea mai mare pondere în serviciile Internet. De altfel a apărut expresia Surf
in Web, care înseamnă plimbare prin Internet.
Use Net, protocol ce poate fi folosit pentru cuplarea la grupurile de discuţii, pentru a colabora
cu alţi colaboratori conectaţi la Internet.
Internet Relay Chat, poate fi folosit pentru a purta conversaţii în direct, chiar se pot organiza
conferinte video şi audio.
184
Internet protocol (IP), fiind cel mai simplu protocol de comunicare între calculatoare;
Transmission Control Protocol (TCP), care este mai performant decât cel de mai sus
întrucât asigură corectarea erorilor de transmisie.
Deoarece cele două protocoale prezentate mai sus sunt folosite de regulă împreună, ele sunt
menţionate mereu împreună sub forma TCP / IP.
File Transfer Protocol (FTP), defineşte modul în care este transferat un fişier generic dintr-
un calculator în altul. fişierul poate fi de forma: document, program, o imagine, etc.
Hyper Text Markup Language (HTML), care defineşte o metodă de adăugare a atributelor
de formatare în fişierele de text, pentru a fi vizualizate fişierele de text citite ca nişte titluri,
paragrafe centrate şi imagini înglobate.
Hyper Text Transfer Protocol (HTTP), defineşte modul în care calculatoarele transmit
fişierele HTML în ambele direcţii.
WWW este o colecţie de milioane de documente cu diferite informaţii care sunt păstrate pe
calculatoare răspândite în întreaga lume. Pentru a uşura accesul la aceste informaţii se dau în
continuare câteva definiţii:
Situl Web este o colecţie de pagini Web, care aparţin aceleaşi instituţii sau persoane;
Pagina sursă (Home Page) este pagina principală dintr-un sit Web;
Hipertextul reprezintă metoda folosită pentru a organiza informaţia în reţeaua Web.
Folosindu-se această metodă, textele sau imaginile evidenţiate într-un document reprezintă
trimiteri la alte documente care conţin informaţii suplimentare;
Hypermedia reprezintă o extindere a metodei hypertext, prin care trimiterile sunt extinse şi la
alte medii cum sunt sunetele şi imaginile video;
URL (Uniform Resource Locator) reprezintă adresa unei locaţii cu informaţii din reţeaua
Internet. Aceasta este formată din trei părţi:
Numele protocolului. Precizează tipul resursei Internet. In tabelul 8.3 sunt prezentate
câteva tipuri de resursă.
Numele gazdei. Prezintă numele calculatorului pe care este stocată informaţia.
Calea fişierului. Precizează numele fişierului în care se găseste informaţia şi calea de
cataloage până la catalogul în care se află fişierul.
Browserul este un program care ajută la găsirea şi citirea informaţiilor în documentele html
ale reţelei Web şi asigură următoarele operaţii mai importante:
185
Copierea informaţiilor în fişiere în calculatorul propriu.
Internet Explorer a fost creat de Microsoft şi inclus în sistemele de operare Windows 95
şi 98.
Netscape Navigator, care a fost creat de Netscape Communication Corporation, poate fi
folosit în sistemele windows 95 şi 98.
Tabelul 8.3.
Format Exemplu
http:// http:// www.pub.ro
telnet:// telnet://onramp.net
Gopher:// gopher:// gopher.umc.edu
ftp:// ftp:// ftp.mcp.com/que
file:/// file:/// cIwindows/readme.bat
Reţeaua Web funcţionează pe baza relaţiei client-server, serverul fiind calculatorul pe care se
găsesc unul sau mai multe situri Web, iar clientul este calculatorul de pe care se emite cererea de
informaţii.
In continuare este prezentat un exemplu de căutare a unor informaţii folosind browserul Internet
Explorer în cadrul unui calculator utilat cu sistemul de operare Windows 95 şi conectat la un server la
care este abonat.
Se execută un clic pe caseta Internet explorer din suprafaţa de lucru a mediului Windows 95.
186
Va apare pe ecran tabloul Dial-up Connection. Se vor completa rubricile: User name şi
Password cu cuvintele din protocolul de închiriere pentru folosirea reţelei Internet încheiat cu
serverul. Apoi se antrenează tasta Connect.
Va apare o suprafaţă de lucru pentru Internet. Se introduce în bara orizontală superioară
adresa unei locaţii în care se caută anumite informaţii.
In cazul prezent se va scrie www.pub.ro care reprezintă adresa în Web pentru Universitatea
Politehnică Bucuresti.
Va apare pagina sursă. Se va clica pe caseta relansin şi vor apărea o serie de informaţii
referitoare la programul de cercetare Relansin.
Apare din nou suprafaţa de lucru a mediului Windows 95. Se clichează caseta cu două
monitoare cuplate din bara orizontală de jos şi apare un tablou şi se va clica pe tasta
Disconnect.
Nu daţi adresa cutiei poştale unor persoane necunoscute, pentru ca să nu aveţi surprize
neplăcute.
Utilizatorii de Internet folosesc codul de conduită numit Netiquette. Dintre regulile sale se
enumera în continuare:
Nu scrieţi mesajele cu majuscule, sunt mai greu de citit şi dau impresia de nepoliteţe.
187
Furnizorul de servicii Internet la care sunteţi abonat poate închide conexiunea, dacă prea
mult timp fiind conectat on-line, nu o folosiţi.
Nu folosiţi munca altora fără a le cere permisiunea. Astfel unii utilizatori preiau din reţea
texte, imagini şi videoclipuri asupra cărora acţionează legea dreptului de autor.
Dacă doriţi să citaţi o sursă on-line în propriile lucrări, informaţi-vă care sunt modalităţile legale
prin care se obţine aprobarea pentru citare.
Pentru citarea în lucrarea proprie a unor paragrafe sau informaţii culese on-line, Asociaţia
Americană de Fiziologie a propus aşa cum se vede din Tabelul 8.3, următorul standard pentru
integrarea citatelor: Autor (i), Data publicării, Titlul documentului, Tipul documentului, URL, Data
vizionării.
Tabelul 8.4.
Titlul Conţinutul
Autor ( i ) Numele fiecăruia dintre autorii documentului. Dacă pagina
Web conţine doar / şi o adresă de e-mail sau un pseudonim,
treceţi-le şi pe acestea.
Data publicării Data la care a fost publicat documentul. De obicei la sfârşitul
documentului se găseşte data celei mai recente actualizări a
unei pagini Web.
Titlul Titlul paginii Web aşa cum apare în bara de titlu a
documentului browserului.
Tipul Poate fi unul din tipurile de documente enumerate în Tabelul
documentului 8.5.
URL Adresa URL completată, poate fi una din adresele
enumerate în Tabelul 8.3.
Data vizitării Data la care aţi găsit materialul citat în vizita pe Internet.
Este bine să fie menţionat deoarece informaţiile Internet se
schimbă în mod frecvent.
Tabelul 8.5.
188
On-line Search Query Rezultatul unei interogări on-line
On-line Serial Mesaj distribuitor periodic prin e-mail
On-line Service Serviciu accesat prin Telnet
PostScript File Fişier Postcript.
Text File Fişier de text simplu.
WAIS Database Bază de date WAIS cu acces public
WAIS Query Rezultatul unei interogări WAIS
WWW document Pagină Web
Bibliografie:
1. Manuale de informatică aprobate de Ministerul Educaţiei şi Cercetării
2. Albeanu G., Sisteme de operare, Ed. Petrion, 1996
3. Albeanu G., Programarea în Pascal ºi Turbo Pascal, Ed. Tehnică, 1994
4. Andonie R., Gârbacea I., Algoritmi fundamentali, o perspectivã C++, Ed. Libris,
1995
5. Barbu Gh., Văduva I,. Boloşteanu M., Bazele informaticii, Ed. Tehnică, 1997
6. Bălănescu T., Gavrilă S., Georgescu H., Gheorghe M., Sofonea L., Văduva I.,
Pascal ºi
Turbo Pascal, Ed. Tehnică, Bucureşti, 1992
7. Beu T., Analiza numericã în Turbo Pascal, Ed. Microinformatica, Cluj Napoca,
1992
8. Bulăceanu C., Reþele locale de calculatoare, Ed. Tehnică, 1995
9. Cadar C., Gheorghiţă V., Tehnologia informaþiei - manual pentru clasa a IX-a, Ed.
L&S
189
Infomat, 1999
10. Calude C., Complexitatea calculului. Aspecte calitative, Ed. Ştiinţifică şi
Enciclopedică,
Bucureşti, 1982
11. Calude C., Teoria algoritmilor, Ed. Universităţii Bucureşti, 1987
12. Cerchez, E., Internet – manual opþional pentru liceu, Ed. Polirom Iaşi, 2000
13. Cerchez, E., Informatica – Culegere de probleme pentru liceu, Ed. Polirom Iaşi,
2002
14. Cerchez, E., Şerban, M. Informatica – manual pentru clasa a X-a. Ed. Polirom
2000, Iaşi
15. Cerchez, E., Şerban, M. PC pas cu pas. Ed. Polirom 2001, Iaşi
16. Cormen T., Leiserson Ch., Rivest R., Introducere în algoritmi, Ed. Computer
Libris
Agora, Cluj
17. Cristea V., Kalisz E., Athanasiu I., Pănoiu S., Turbo Pascal, Ed. Teora, 1992
18. Dima G., Dima M., FoxPro, Ed. Teora, 1994
19. Frâncu C., Informatica economicã - Fox Pro, Ed. L&S Infomat, Bucureşti, 1998
20. Georgescu H., Livovschi L., Analiza ºi sinteza algoritmilor, Ed. Ştiinţifică şi
Enciclopedică, Bucureşti, 1986
21. Giumale C., Negreanu L., Călinoiu S., Proiectarea ºi analiza algoritmilor.
Algoritmi de
sortare, Ed. All, 1997
22. Grigoriu, D., ş.a. – Informatica – subiecte rezolvate de bacalaureat date în anii
1999-
2001, Ed. Niculescu, Bucureşti 2002
23. Horowitz E., Fundamentals of Data Structures in C++, Computer Science Press,
1995
24. Horowitz E., Fundamentals of Programming Languages, Springer Verlag, 1983
25. Ionescu C., Zsako I., Structuri arborescente, Ed. Tehnică, Bucureşti,1990
26. Ivaşc C., Prună M., Bazele informaticii, Ed. Petrion, 1995
27. Ivaşc C., Prună M., Mateescu E., Bazele Informaticii (Grafuri ºi elemente de
combinatoricã) - Caiet de laborator, Ed. Petrion, 1997
28. Ivaşc C., Prună M., Tehnici de programare (Aplicaþii), Ed. Petrion, 1999
29. Ivaşc C., Prună M.,ş.a. Informatica – manual pentru clasa a XI-a, Ed. Petrion,
Bucureşti
2001
30. Jamsa K., Succes cu C++, Ed. All, 1997
31. Knuth D. E., Tratat de programarea calculatoarelor, vol. I, II, III, Ed. Teora
Bucureşti
2002
32. Lica D., Onea E., Informatica, manual pentru clasa a IX-a, Ed. L&S Infomat,
1999
33. Lica D., Onea E., Informatica, manual pentru clasa a X-a, Ed. Prognosis, 2000
34. Lica. D., Popescu, D.A., ş.a. – Bacalaureat la informaticã – Ed. L&S Infomat,
Bucureşti
2002
35. Lungu I., Muşat N., Velicanu M., Sistemul FoxPro 2.6 - Prezentare ºi aplicaþii,
Ed. All,
1996
190
36. Lupulescu M., Munteanu M., Giulvezan C., FoxPro, de la iniþiere la
performanþã, Ed. de
Vest, Timişoara, 1994
7
37. Mateescu G. D., C++, limbaj ºi programare, Ed. Petrion, 1998
38. Mateescu G. D., Analiza numericã, Ed. Petrion, 1995
39. Mârşanu R., Voicu A, şa, Tehnologia informaþiei, manual pentru clasa a IX-a, Ed.
All,
Bucureşti, 1999
40. Miloşescu M., Sisteme de calcul, Editura Teora, 1998
41. Mitrana V., Provocarea algoritmilor, Ed. Agni, Bucureşti, 1994
42. Negrescu L., Limbajul C ºi C++, Ed. Microinformatica. Cluj
43. Niculescu S., Pintea R., Tehnologia informaþiei ºi Informaticã-Tehnologii asistate
de
calculator - manual pentru clasa a IX-a, Ed. E.D.P., 1999
44. Niculescu S., Butnaru L., Butnaru V., Informaticã- manual pentru clasa a IX-a,
Ed.
E.D.P, 1999
45. Niculescu R., Albeanu G., Domocoş V., Programarea calculatoarelor - probleme
rezolvate în limbajul Turbo Pascal, Ed. Tempus, 1992
46. Odăgescu I., Copos C., Luca D., Furtună F., Smeureanu I., Metode ºi tehnici de
programare, Ed. Intact, Bucureşti, 1994
47. Odăgescu I., Furtună F., Metode ºi tehnici de programare, Editura Computer
Libris
Agora, 1998
48. Panţiru M., Panţiru I., Baze de date, Ed. L&S Infomat, Bucureşti, 1999
49. Panţiru M., Panţiru I., Informatica – manual pentru clasa a XII-a, Ed. L&S
Infomat,
Bucureşti, 2002
50. Pătrăşcoiu O., Marian Gh., Mitroi N., Informaticã - elemente de grafuri ºi
combinatoricã,
metode, algoritmi ºi programe, Ed. All, Bucureşti,
51. Pătruţ B., Miloşescu M., Informaticã - manual pentru clasa a IX-a, Ed. Teora,
1999
191