Sunteți pe pagina 1din 17

COLEGIUL NAIONAL TEFAN CEL MARE, TRGU NEAM

Grafuri neorientate
Lucrare pentru atestarea competenelor profesionale la informatic

Profesor coordonator,
Elev,
Savescu Andrei - Sergiu
Clasa a XII-a RD

2015
CUPRINS

Grafuri neorientate

1.

Introducere. Elemente de teorie....................................................................3

2.

Componente conexe....................................................................................5

3.

Tipuri de grafuri........................................................................................6
a)

Grafuri Hamiltoniene.................................................................................6

b) Grafuri euleriene.................................................................................6
c) Graf partial si subgraf..........................................................................7
d) Graf complet si graf bipartit................................................................7
4.

Parcurgerea grafurilor................................................................................8
a) Parcurgerea in latime (BF-Breath First)................................................8
b) Parcurgerea in adancime (DF-Depth First).........................................14

5.

Conexitate..............................................................................................15

Grafuri neorientate
2

Grafuri neorientate

1. Introducere. Elemente de teorie


Informatica este stiinta procesarii sistematice a informatiei. in special a procesarii cu
ajutorul calculatoarelor. Istoric, informatica s-a dezvoltat ca stiinta din matematica, in timp ce
dezvoltarea primelor calulatoare isi are originea in electrotehnica si telecomunicatii. De aceea,
calculatorul

reprezinta

doar

dispozitivul

pe

care

sunt

implementate

conceptele

teoretice.Informaticianul olandez Edsger Dijkstra afirma: In Informatica ai de-a face cu


calculatorul, cum ai in astronomie cu telescopul.
Termenul de informatica provine din alaturarea cuvintelor informatie si
matematica. Alte surse sustin ca provine din combinatia informatie si automatica.
Istoria stiintei calculatoarelor precede momentul aparitiei computerului digital. Inainte
de anul 1920, termenul de computer se referea ,in limba engleza, la un o persoana care
efectua calcule (un functionar). Primii cercetatori in ceea ce avea sa se numeasca stiinta
calculatoarelor, cum sunt Kurt Gdel, Alonzo Church si Alan Turing, au fost interesati de
problema computationala: ce informatii ar putea un functionar uman sa calculeze avand hartie
si creion, prin urmarirea pur si simplu a unei liste de instructiuni, atat timp cat este necesar,
fara sa fie nevoie ca el sa fie inteligent sau sa presupuna capacitati intuitive. Una din
motivatiile acestui proiect a fost dorinta de a proiecta si realiza masini computationale care
sa automatizeze munca, deseori plictisitoare si nu lipsita de erori, a unui computer uman.
In perioada anilor 1940, cand masinile computationale au cunoscut o evolutie
accelerata, termenul de computer si-a modificat semnificatia, referindu-se de acum mai
degraba la masini, decat la predecesorii sai umani.

Informatica se divide in urmatoarele domenii fundamentale:

informatica practica
3

Grafuri neorientate

informatica teoretica

tehnica
Pe langa cele trei domenii mai exista si inteligenta artificiala considerata o

interdisciplina de sine statatoare.


Informatica teoretica se ocupa cu studiul teoriei limbajelor formale, respectiv
automatica, teoria computationala si complexitatii,criptologie, logica,teoria grafurilor
s.a.m.d punand bazele pentru construirea compilatoarelor pentru limbajele de programare si
pentru formalizarea problemelor din matematica. Ea este, prin urmare, coloana vertebrala a
informaticii.
In matematica si informatica, teoria grafurilor studiaza proprietatile grafurilor.

Grafurile:
Definitie: Numim graf o pereche ordonata de multimi, notata G=(X,U), unde X este o
multime finita si nevida de elemente numite noduri sau varfuri, iar U este o multime de
perechi (ordonate sau neordonate) de elemente din X numite muchii (daca sunt perechi
neordonate) sau arce (daca sunt perechi ordonate). In primul caz, graful se numeste neorientat,
altfel acesta este orientat.

Asadar un graf poate fi reprezentat sub forma unei figuri geometrice alcatuite din
puncte (care corespund varfurilor) si din linii drepte sau curbe care unesc aceste puncte (care
corespund muchiilor sau arcelor).

Grafurile au o importanta imensa in informatica, de exemplu:

in unele problemele de sortare si cautare elementele multimii pe care se face sortarea


sau cautarea se pot reprezenta prin noduri intr-un graf;
4

Grafuri neorientate

schema logica a unui program se poate reprezenta printr-un graf orientat in care o
instructiune sau un bloc de instructiuni este reprezentat printr-un nod, iar muchiile
directionate reprezinta calea de executie;

in programarea orientata pe obiecte, ierarhia obiectelor (claselor) unui program poate


fi reprezentata printr-un graf in care fiecare nod reprezinta o clasa, iar muchiile
reprezinta relatii intre acestea (derivari, agregari).

2. Componente conexe:
Fie G=(V, E) un graf neorientat, unde V are n elemente (n noduri) si E are m elemente
(m muchii).
Definitie: G1=(V1, E1) este o componenta conexa daca:

pentru orice pereche x,y de noduri din V1 exista un lant de la x la y (implicit si de la y


la x)

nu exista alt subgraf al lui G, G 2=(V2, E2) care sa indeplineasca prima conditie si care
sa-l contina pe G1

Observatie: subgraful 1, 2, 3, 4 nu este componenta conexa ( chiar daca pentru orice pereche
x,y de noduri exista un lant de la x la y) deoarece exista subgraful 1, 2, 3, 4, 5 care il contine
si indeplineste aceeasi conditie.
Definitie: Un graf G=(V, E) este conex daca pentru orice pereche x,y de noduri din V exista
un lant de la x la y (implicit si de la y la x).
Observatii:
5

Grafuri neorientate

Un graf este conex daca admite o singura componenta conexa.

Graful anterior nu este conex pentru ca admite doua componente conexe. Graful
urmator este conex:

3. Tipuri de grafuri:
a) Grafuri Hamiltoniene
Definitie: Se numeste ciclu hamiltonian un ciclu elementar care contine toate varfurile
grafului.
Definitie: Un graf se numeste hamiltonian daca are cel putin un ciclu hamiltonian.
Teorema: Fie G=(X,U) un graf.Daca gradul fiecarui varf este >=n/2 atunci graful este
hamiltonian.
Observatie: Conditia din teorema este necesara,dar nu si suficienta.
Aplicatie: Ciclurile hamiltoniene sunt legate de problema comis-voiajorului care
pleaca dintr-un oras si trebuie sa treaca o singura data prin celelalte orase si sa se intoarca de
unde a plecat.
b) Grafuri euleriene
Definitie: Un ciclu se numeste eulerian daca trece o singura data prin toate muchiile.
Observatie: Un graf se numeste eulerian daca are un ciclu eulerian.
Teorema: Un graf fara varfuri izolate se numeste eulerian daca si numai daca este
conex si gradul fiecarui varf este par.
Observatie: Dintre grafurile complete sunt euleriene cele cu numar impar de varfuri.
c) Graf partial si subgraf

Grafuri neorientate

Definitie: Fie graful G=(X,U).Un graf partial al lui G,este un graf G1=(X,V) ,cu
VU(inclus).Altfel spus ,un graf partial se obtine pastrand toate varfurile si eliminand niste
muchii.
Definitie: Fie graful G=(X,U).Un subgraf al lui G,este un graf S=(Y,T),unde YX si
TV,iar T va contine numai acele muchii care au ambele extremitati in Y.Altfel spus,un
subgraf S al lui G se obtine din G eliminand niste varfuri si odata cu acestea acele muchii care
au cel putin o extremitate in submultimea eliminata.

d) Graf complet si graf bipartit


Definitie: Se numeste graf complet cu n varfuri,notat K indice n (Kn),un graf G=(X,U) cu
proprietatea ca oricare doua varfuri sunt adiacente,adica oricare cuplu x,y X,esista muchia
[x,y] U.
Teorema: Un graf complet cu n varfuri are n(n-1)/2 muchii.
Definitie: Se numeste graf bipartit ,un graf G=(X,U) cu proprietatea ca exista doua multimi
distincte A si B incluse in X,astefel incat:
AB=multime vida,A+B=X.(+ este reunit);
toate muchiile grafului au o extremitate in A si cealalta in B.
Definitie: Se numeste graf bipartit complet ,un graf bipartit cu proprietatea ca pentru orice
varf x din A si orice varf y din B , exista muchia [x,y].(A+B=X).

Grafuri neorientate

4. Parcurgerea grafurilor:
Parcurgerea grafurilor se realizeaza cu scopul vizitarii varfurilor acestora.Fiecare varf
se va vizita o singura data,cu scopul prelucrarii informatiei.
Parcurgerea grafurilor poate fi:

in latime
in adancime

a) Parcurgerea in latime (BF-Breath First)


La explorarea in latime, dupa vizitarea nodului initial, se exploreaza toate nodurile
adiacente lui, se trece apoi la primul nod adiacent si se exploreaza toate nodurile adiacente
acestuia si neparcurse inca, s.a.m.d. Fiecare nod se parcurge cel mult odata (daca graful nu
este conex nu se vor putea parcurge toate nodurile)

Grafuri neorientate

Algoritmul de parcurgere in latime:


Se va folosi o coada in care se inscriu nodurile in forma in care sunt parcurse: nodul
initial varf (de la care se porneste), apoi nodurile a,b,, adiacente lui varf, apoi cele adiacente
lui a, cele adiacente lui b, ,s.a.m.d.
Coada este folosita astfel:

Se pune primul nod in coada;

Se afla toate varfurile adiacente cu primul nod si se introduc dupa primul nod

Se ia urmatorul nod si i se afla nodurile adiacente

Procesul se repeta pana cand se ajunge la sfarsitul cozii

Graful se va memora utilizand matricea de adiacenta a[10][10]


Pentru memorarea succesiunii nodurilor parcurse se va folosi un vector c[20] care va
functiona ca o coada
Pentru a nu parcurge un nod de doua ori se va folosi un vector boolean viz[20] care va
retine :

viz[k]=0 daca nodul k nu a fost vizitat inca

viz[k]=1 daca nodul k a fost vizitat

Doua variabile : prim si ultim vor retine doua pozitii din vectorul c si anume :

prim este indicele componentei pentru care se parcurg vecinii (indexul


componentelor marcate cu rosu in sirurile parcurse anterior ). Prin urmare
Varf=c[prim], este elementul pentru care se determina vecinii (nodurile
adiacente)

Grafuri neorientate

ultim este pozitia in vector pe care se va face o noua inserare in vectorul c


(evident, de fiecare data cand se realizeaza o noua inserare se mareste vectorul)

Vecinii nodului varf se cauta pe linia acestui varf : daca a[varf][k]=1


inseamna ca nodurile varf si k sunt adiacente. Pentru ca nodul k sa fie adaugat
in coada trebuie ca nodul sa nu fi fost vizitat : viz[k]=0

#include<fstream.h>
#include<conio.h>
int a[10][10],c[20],viz[10];
int n,m,prim,ultim,varf;
void bf_iterativ() //parcurgerea in latime
{int k;
while(prim<=ultim)
{varf=c[prim];
for(k=1;k<=n;k++)
if(a[varf][k]==1&&viz[k]==0) //il adaug pe k in coada daca este vecin pt. varf si nu a fost
vizitat
{ultim++;
c[ultim]=k;
viz[k]=1;}
prim++;
}
}
10

Grafuri neorientate

void main()
{clrscr();
int x,y;
fstream f; //memorare graf in matrice de adiacenta
f.open(muchii.txt,ios::in);
f>>n>>m;
for(int i=1;i<=m;i++)
{f>>x>>y;
a[x][y]=a[y][x]=1;
}
cout<<matricea de adiac <<endl; // afisare matrice de adiacenta
for( i=1;i<=n;i++)
{for(int j=1;j<=n;j++)
cout<<a[i][j]<< ;
cout<<endl;
}
int nd;
prim=ultim=1;
cout<<nodul de inceput=;
cin>>nd; // nodul de la care se porneste parcurgerea

11

Grafuri neorientate

viz[nd]=1;
c[prim]=nd;
bf_iterativ();
for(i=1;i<=ultim;i++) //afisarea cozii
cout<<c[i]<< ;
getch();
}

Varianta recursiva de parcurgere se obtine modificand functia de parcurgere iterativa


adaugand conditia necesara autoapelului:
void bf_recursiv() //parcurgerea in latime
{int k;
if(prim<=ultim)
{varf=c[prim];
for(k=1;k<=n;k++)
if(a[varf][k]==1&&viz[k]==0) //il adaug pe k in coada daca este vecin pt. varf si nu a fost
vizitat
{ultim++;
c[ultim]=k;
viz[k]=1;}
prim++;

12

Grafuri neorientate

bf_recursiv();
}
}
Parcurgerea in latime a grafurilor memorate prin liste este similara cu diferenta
cavecinii unui nod adaugat in coada se cauta in lista corespunzatoare lui :
#include<conio.h>
#include<fstream.h>
struct nod
{int nd;
nod *next;};
nod *L[20];
int viz[100]; //marchez cu 1 nodurile vizitate
int m,n;
int prim,ultim,C[100];
void bfi_lis()
{int varf,nr;
nod *p;
while(prim<=ultim)
{varf=C[prim];
p=L[varf]; // se parcurge lista elementelor din varful cozii
while(p)
13

Grafuri neorientate

{nr=p->nd;
if(viz[nr]==0) //numai daca nu a fost vizitat
{ultim++; //maresc coada
C[ultim]=nr; //il adaug in coada
viz[nr]=1;}; //il marchez ca fiind vizitat
p=p->next;
}
prim++; //avansez la urmatorul nod din coada}}
void afisare(int nr_nod)
{nod *p=L[nr_nod];
if(p==0)
cout<<nr_nod<< este izolat <<endl;
else
{cout<<lista vecinilor lui <<nr_nod<<endl;
nod *c=p;
while(c)
{cout<<c->nd<< ;
c=c->next;}
cout<<endl;}}
void main()

14

Grafuri neorientate

{fstream f;
int i,j;
nod *p,*q;
f.open(muchii.txt,ios::in);
clrscr();
f>>n>>m;
while(f>>i>>j)
{p=new nod;
p->nd=j;
p->next=L[i];
L[i]=p;
q=new nod;
q->nd=i;
q->next=L[j];
L[j]=q;
} f.close();
cout<<endl<<listele de adiacente ;
for(i=1;i<=n;i++)
afisare(i);
int ndr;

15

Grafuri neorientate

cout<<endl<<nodul de inceput ;
cin>>ndr;
viz[ndr]=1;
prim=ultim=1;
C[prim]=ndr;
cout<<endl<<parcurgere in latime <<endl;
bfi_lis();
for(i=1;i<=ultim;i++)
cout<<C[i]<< ;
getch();
}

b) Parcurgerea in adancime (DF-Depth First)


Parcurgerea unui graf in adancime se face prin utilizarea stivei (alocate implicit prin
subprograme recursive).
Pentru fiecare nod se parcurge primul dintre vecinii lui neparcursi inca
Dupa vizitarea nodului initial x1, se exploreaza primul nod adiacent lui fie acesta x 2 ,
se trece apoi la primul nod adiacent cu x2 si care nu a fost parcurs inca , s.a.m.d.
Fiecare nod se parcurge cel mult odata (daca graful nu este conex nu se vor putea parcurge
toate nodurile)
De exemplul pentru garful din figura de mai jos, se va proceda in felul urmator:

16

Grafuri neorientate

5. Conexitate
Definitie: Un graf se numeste conex daca intre oricare doua varfuri exista un lant.
Observatie: Pentru a verifica daca un graf este conex sau nu se realizeaza o parcurgere
pornind din varful 1 si daca numarul de varfuri vizitate este n atunci graful este conex.
Observatie: Daca graful nu este conex,atunci acesta este format din componente conexe.
Definitie: O componenta conexa este un subgraf conex maximal cu aceasta proprietate.
Definitie: O componenta conexa a unui graf G=(X,U) este un subgraf S=(Y,Z) cu proprietatea
ca nu exista un lant care sa uneasca un varf din Y cu un varf din X-Y.
Observatie: Fiecare varf izolat constituie o componenta conexa.

17

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