Documente Academic
Documente Profesional
Documente Cultură
ATESTAT PROFESIONAL
Prof.ndrumtor:
Sceanu Ion
Elev: Balcan Onisim
Profil:Matematic-Informatic
Colegiul Tehnic Mtsari
2015
1
GRAFURI NEORIENTATE
Prof.ndrumtor:
Sceanu Ion
Elev:
Balcan Onisim
Profil:Matematic-Informatic
Colegiul Tehnic Mtsari
2015
2
Cuprins
ARGUMENT........................................................................................................................................4
MEMORAREA GRAFURILOR..........................................................................................................5
GRAF PARIAL, SUBGRAF............................................................................................................10
PARCURGEREA GRAFURILOR NEORIENTATE..........................................................................11
LANURI...........................................................................................................................................17
GRAF CONEX...................................................................................................................................21
COMPONENTE CONEXE................................................................................................................21
CICLURI.............................................................................................................................................24
ARBORI..............................................................................................................................................26
BIBLIOGRAFIE.................................................................................................................................31
Argument
GRAFURI NEORIENTATE
4
2
3
Avem:
G=(V,E)
V= {1,2,3,4,5,6}
E= { (1,2), (1,3), (1,5),(2,3), (3,4),(4,5)}
Observaii:
Se noteaz cu n numarul de nodurin=6, iar cu m
numrul muchiilor m=6
Muchia (1,2) este aceeai cu (2,1) pentru ca avem un
graf neorientat.
Nu exist o muchie care unete un nod cu el insui.
Dou noduri pot fi unite prin cel mult o muchie.
Definiii:
1. n graful g=(V,E), nodurile distincte vi ,vj G sunt adiacente dac exist
muchia (vi ,vj ) E. Vom spune c muchia (vi ,vj ) E este incident la
nodurile vi i vj . n exemplul nostru nodurile 1 i 5 sunt adiacente dar nodurile
2 i 5 nu sunt adiacente. Muchia (4,5) este incident la nodurile 4 i 5.
2. ntr-un graf neorientat, prin gradul unui nod v se nelege numrul muchiilor
incidente cu nodul v i se noteaz cu d(v). Un nod cu gradul 0 se numete nod
izolat, iar unul cu gradul 1 se numete nod terminal. Exemplul nostru :
d(2)=2, d(1)=3, d(6)=0 (nod izolat).
3. O relaie util:
d1+d2+,....,+ dn =2*m, adic suma gradelor nodurilor grafului = 2* numrul
muchiilor;
MEMORAREA GRAFURILOR
5
A6,6=
011010
101000
110100
001010
100100
000000
Observaii:
Elementele de pe diagonala principal sunt 0 ( pentru c am definit
un graf la care nu exist muchii de la un nod la el insui)
Matricea de adiacen este simetric ai,j = aj,i i,j { 1,2,..,n}
Suma elementelor de pe linia i reprezint gradul nodului i, adic
d(i)
Suma tuturor elementelor matricei de adiacen = suma gradelor
tuturor nodurilor, adic dublul numrului de muchii (2m)
b) Crearea matricei prin citirea muchiilor grafului: Datele se citesc dintrun fiier care are pe primul rnd numrul de noduri, iar pe fiecare din
urmtoarele cte o muchie. Se folosete funcia urmtoare:
void CitireN (char nume_fi[20], int a[50][ 50], int &n)
{
Fiierul ptr graful nostru:
int i,j;
6
fstream f(nume_fi,ios :: in);
12
f>>n;
13
while (f>>i>>j)
15
a[i][j]=a[j][i]=1;
23
6
34
45
f.close();
}
Programul urmtor citete muchiile grafului i afieaz matricea de adiacen.
# include <iostream.h>
# include<conio.h>
int a[50][50], n;
void CitireN (char nume_fi[20], int a[50][ 50], int &n)
{
int i,j;
fstream f(nume_fi,ios :: in);
f>>n;
while (f>>i>>j)
a[i][j]=a[j][i]=1;
f.close();
}
void main( )
{
CitireN (graf.txt,a,n);
For (int i=1; i<=n;i++)
{
for (int j=1; j<=n;j++)
cout<<a[i][j]<< ;
cout<<endl;
}
getch();
}
2. Memorarea grafului prin liste de adiacen
a. Listele de adiacen reprezint o alt form de memorare a grafului, n
care pentru fiecare nod se indic lista nodurilor adiacente cu el.
b. Pentru exemplul nostru, vom avea listele:
c.
1 2,3,5
2 1,3
31,2,4
4 3,5
51,4
6
Se utilizeaza un
vector cu n
componente, pe
Start
1
T[0]
T[1]
11
12
10
10
11
12
Stop am dat de 0
Start[i]=k;
K++;
T[0][k]=I;
T[1][k]=Start[j];
Start[j]=k;
}
f.close();
}
Date de intrare
graf1.txt
6
1 2
1 3
1 5
2 3
3 4
4 5
f.close();
}
Date de iesire
void main( )
{
citire_muchii( graf1.txt, t, start,n);
for ( i=1;i<=n;i++)
{
cout<<noduri adiacente cu <<i<<endl;
1 2,3,5
2 1,3
31,2,4
4 3,5
51,4
6 -
man=start[i];
while ( man)
{
cout<<t[0] [man] << ;
man=t[1][man];
}
cout<<endl;
}
getch();
}
3. Memorarea grafurilor prin lista muchiilor
Se utilizeaz un vector cu m componente, unde m este numrul muchiilor. Fiecare
component va reine cele dou noduri la care muchia respectiv este incident i , n
anumite cazuri alte informaii referitoare la muchia respectiv.
Struct muchie
{
int x,y;
};
muchie v[50];
GRAF COMPLET
Definiie: Un graf complet este un graf neorientat n care oricare dou noduri sunt
adiacente. El se noteaz cu Kn, unde n este numrul de noduri ale grafului.
RELAII UTILE
1. ntr-un graf complet gradul oricrui nod este n-1.
2. ntr-un graf complet avem relaia m= n(n-1) / 2 , unde m este numarul de
muchii, iar n numarul de noduri.
3. Avem 2n(n-1)/2 grafuri neorientate cu n noduri.
10
Definiie:Un graf parial al unui graf neorientat dat G=(V,E) este un graf G1= (V, E1),
unde E1 E.
Un graf parial al unui graf dat, este el nsui sau se obine din G prin eliminarea unor
muchii.
1
2
3
2
3
G=(V,E)
Definiie: Un subgraf al un ui graf neorientat G(V,E) este un graf G1=(V1, E1), unde
V1 V. E1 E iar muchiile din E2 sunt toate muchiile din E care sunt incidente numai
cu nodurile din mulimea V1.
Un subgraf al unui graf este el nsui sau se obine din G prin suprimarea anumitor
noduri i a tuturor muchiilor incidente cu acestea.
1
2
3
5
3
G=(V,E)
11
12
void main( )
{
citire_muchii(graf.txt, t, start, n);
bf(6);
getch( );
}
Programul de parcurgere BF (lime) a unui graf memorat prin matricea de
adiacen
#include <conio.h>
#include<iostream.h>
int n, coada[50], s[50], i_c=1, sf_c=1, A[50][50], i;
void CitireN (char nume_fi[20], int a[50][ 50], int &n)
{
int i,j;
fstream f(nume_fi,ios :: in);
f>>n;
while (f>>i>>j)
a[i][j]=a[j][i]=1;
f.close();
}
void bf (int nod)
{
coada[i_c]=nod;
s[nod]=1;
while (i_c<=sf_c)
{
i=1;
while (i<=n)
{
if (A[coada[i_c]][i]= =1 && s[i]= =0 )
{
sf_c++;
coada[sf_c]=i;
s[i]=1;
}
i++;
}
cout<<coada[i_c]<<endl;
i_c++;
14
}
}
void main( )
{
CitireN( graf.txt, A, n);
Bf(1);
getch();
}
Parcurgerea n adncime DF- Depth First
- Parcurgerea n adncime se face de la un nod i care se consider vizitat.
- Dup vizitarea unui nod, se viziteaz primul dintre nodurile adiacente, nevizitate
nc, apoi urmtorul nod adiacent, pn cnd au fost vizitate toate nodurile
adiacente cu el.
-
- Parcurgerea continu n acest mod pn cnd au fost vizitate toate nodurile
accesibile.
Programul de parcurgere DF (adncime) a unui graf memorat prin liste de adiacen
#include <conio.h>
#include<iostream.h>
int s[50], n, T[2][50], Start[50] ;
Void Citire_LA (char Nume_fis[20], int T[2][50], int Start[50], int& n)
{
int i, j, k=0 ;
fstream f(Nume_fis,ios ::in) ;
f>>n;
while (f>>i>>j)
{
k++ ;
T[0][k]=j;
T[1][k]=Start[i];
Start[i]=k;
K++;
T[0][k]=i;
T[1][k]=Start[j];
Start[j]=k;
}
15
f.close();
}
void df (int nod)
{
int p;
cout<< nod << ;
p=Start [nod];
s [nod]=1;
while (p)
{
if ( s [ T[0] [p] ]= =0)
df (T [0][p] );
p= T[1] [p];
}
}
void main( )
{
Citire_LA(graf.txt, T, Start, n);
df(1);
getch( );
}
Programul de parcurgere DF (adncime) a unui graf memorat prin matricea de
adiacen
#include <conio.h>
#include<iostream.h>
int s[50], n, A[50][50] ;
void CitireN (char nume_fi[20], int a[50][ 50], int &n)
{
int i,j;
fstream f(nume_fi,ios :: in);
f>>n;
while (f>>i>>j)
a[i][j]=a[j][i]=1;
f.close();
}
16
LANURI
Definiie:
Pentru graful neorintat G=( V,E), un lan L= [v1,v2,....,vp] este o succesiune de noduri
cu proprie-tatea a oricare dou noduri vecine sunt adiacente, adic (v1,v2) E, (v2,v3)
E, ....(vp-i,vp) E. Un lan poate fi definit ca o succesiune de muchii (v1,v2) E,
(v2,v3) E, ....(vp-i,vp) E.
Vrfurile v1 , vp se numesc extremitile lanului
17
APLICAIE
Fiind dat un graf i dou noduri ale sale a i b, s se scrie un program care
decide dac ntre ele exist un lan sau nu, iar n caz c acest lan exist, se cere
s se afieze lanul.
Not: intre a si b exist lan doar dac putem parcurge lanul din a i ajungem n b.
Ne vom folosi de un vector T care are forma
j,
T[j]=
0, dac i nu a fost selectat
Programul afieaz drumul, pornind de la matricea de adiacen a grafului.
#include <conio.h>
#include<iostream.h>
int s[50], A [50] [50], n, T[50] , a, b ;
void CitireN (char nume_fi[20], int a[50][ 50], int &n)
{
int i,j;
fstream f(nume_fi,ios :: in);
f>>n;
while (f>>i>>j)
a[i][j]=a[j][i]=1;
18
f.close();
}
void refac( int nod)
{
if (nod!=0)
{
refac (T[nod]);
cout<<nod<< ;
}
}
void df_r (int nod)
{
int k;
s [nod]=1;
for (k=1; k<=n; k++)
if ( A[nod] [k] = =1 && s[k]= = 0)
{
T[k]=nod;
df_r(k);
}
}
void main( )
{
CitireN (graf.txt, A, n);
cout<<a=;
cin>>a;
cout<<b=;
cin>>b;
df_r(a);
if (T[b] != 0)
refac (b);
getch( );
}
Programul afieaz lanul de lungime minim aflat ntre nodurile a i b
( parcurgere n lime DF )
#include <conio.h>
#include<iostream.h>
19
}
void main( )
{
CitireN (graf.txt, A, n);
cout<<a=; cin>>a;
cout<<b=; cin>>b;
df_r(a);
if (T[b] != 0)
refac (b);
getch( );
}
GRAF CONEX
Definiie:
Un graf neorientat G=(V, E) este conex, dac pentru orice pereche de noduri x, y V,
exist un lan n care extremitatea iniial este x i extremitatea final este y.
Un graf cu un singur nod este conex.
Graf CONEX
21
COMPONENTE CONEXE
Definiie:
Fir G=(V, E) un graf neorientat i G1= ( V1,E1) un subgraf al su. Atunci G1= ( V1,E1)
este o component conex a grafului G=(V, E) dac sunt ndeplinte condiiile:
Oricare ar fi x, y V1, exist un lan de la x la y;
Nu exist un alt subgraf al lui G, G2= ( V2,E2) cu V1 V2 care ndeplinete
condiia a).
Un graf cu n noduri poate avea un nr. de componente conexe cuprins ntre 1 i n.
Exemple:
1
2
4
APLICAIE:
Fiind dat un graf neorientat, se cere s se afieze nodurile fiecrei componente
conexe.
NOT: parcurgem grafulde cte ori il parcurgem attea componente conexe
avem.
Fiierul
text ptr
graful nostru:
#include <conio.h>
#include<iostream.h>
int s[50], A [50] [50], n, i;
22
6
12
13
15
23
34
45
23
CICLURI
Definiie;
Un lan L care conine numai muchii distincte i pentru care nodul iniial coincide
cu nodul final se numete ciclu. Dac cu excepia ultimului nod, care coincide cu
primul, lanul este elementar, atunci ciclul este elementar ( adic, cu excepia
ultimului nod, care coincide cu primul, conine noduri distincte.
APLICAIE:
Fiind dat un graf conex, G=(V,E), s se scrie un program care decide dac graful
conine cel puin un ciclu.
NOT: Graful conine cel puin un ciclu dac, n timpul parcurgerii DF, algoritmul va
ajunge n situaia de a vizita un nod de dou ori.
#include <conio.h>
#include<iostream.h>
int s[50], A [50] [50], n, gasit;
void CitireN (char nume_fi[20], int a[50][ 50], int &n)
{
int i,j;
fstream f(nume_fi,ios :: in);
24
f>>n;
while (f>>i>>j)
a[i][j]=a[j][i]=1;
f.close();
}
void df (int nod)
{
int k;
s [nod]=1;
for (k=1; k<=n; k++)
if ( A[nod] [k] = =1 )
{
A [k][nod]=0;
if (s[k]= = 0)
df (k);
else
gasit=1;
}
}
void main( )
{
CitireN (graf.txt, A, n);
df (1);
if (gasit)
cout<< da;
else
cout<< NU;
getch( );
}
Pentru a verifica matematic dac exist cel puin un ciclu se face verificarea, m>n1. Dac este verificat nseamn ca exist cel puin un ciclu.
Dac m=n-1 nu exist cicluri
Dac m<n-1 graful nu este conex, ceea ce ar contrazice cerina.
25
ARBORI
Definiie:
Se numete arbore un graf neorientat care este conex i nu conine cicluri.
Exemplu un arbore cu 5 noduri.
1
4
3
Ex.: este conex pentru ca exista un lant intre orice doua varfuri x si y din V si nu are
cicluri.
TEOREM 1:
Fie G un graf neorientat cu n noduri. G este arbore dac i numai dac are n-1
muchii i nu conine cicluri.
Obs 1 : Orice arbore cu n varfuri are n-1 muchii.
Obs 2 : Orice arbore cu n>=2 varfuri contine cel putin 2 varfuri terminale.
TEOREMA2 :
Fie G=(V,M) un graf neorientat . Urmtoarele afirmaii sunt adevrate:
-G este arbore
-G este un graf conex ,minimal in raport cu aceasta proprietate(daca se elimina o
muchie oarecare din G se obtine un graf neconex)
-G este fara cicluri ,maximal in raport cu aceasta proprietate (daca se adauga o muchie
,se va obtine cel putin un ciclu in graf)
Obs. In cazul arborilor in loc de varfuri si muchii se folosesc cu precadere termenii de
noduri si arce.
APLICAIE:
Se citete un graf. S se scrie un program care verific dac este arbore.
#include <conio.h>
#include<iostream.h>
26
1
2
5 si 6
5
N1
1- rdcina arborelui
Frunze : 3 4 5 7 8
Descendenii direci ai lui 2 :
N2
Descendeni lui 2: 5 6 7 8
H=3
N3
7
N4
Reprezentarea arborilor :
T=(t[1],t[2],t[n])
1
2
ARBORE PARIAL:
Se obine dintr-un graf prin eliminarea unui numr de muchii, pstrndu-se un
numr minim de muchii astfel inct graful rmas s fie conex i fr cicluri.
Exemplu:
1
29
Arbore parial
Program pentru determinarea unui arbore parial pornind de la un graf conex G =(V,
E).
#include <conio.h>
#include<iostream.h>
int s[50], A [50] [50], n ;
void CitireN (char nume_fi[20], int a[50][ 50], int &n)
{
int i,j;
fstream f(nume_fi,ios :: in);
f>>n;
while (f>>i>>j)
a[i][j]=a[j][i]=1;
f.close();
}
void df_r (int nod)
{
int k;
s [nod]=1;
for (k=1; k<=n; k++)
if ( A[nod] [k] = =1 && s[k]= = 0 )
{
cout<<nod<< << k<< endl;
df_r(k);
}
}
void main( )
{
CitireN (graf.txt, A, n);
df_r (1);
getch();
}
30
Graf.txt
6
12
13
15
23
34
45
BIBLIOGRAFIE
https://www.scribd.com/doc/225055268/Grafuri-neorientate
https://grafurineorientate.wordpress.com/
http://infoscience.3x.ro/c++/Grafuri%20neorientate.htm
31