Documente Academic
Documente Profesional
Documente Cultură
Roman
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
Mai 2011
Tem proiect :
Programare orientat pe obiect.
Grafuri neorientate.
2
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
Cuprins
Cuprins........................................................................................................................................ 3
Argument......................................................................................................................................4
1. 5
Programare orientat pe obiect (noiuni introductive)..........................................
2. Grafuri neorientate ......................................................................................... 9
2.1 Noiuni introductive............................................................................................9
2.2 12
Modaliti de reprezentare.....................................................................................
4. Clasa graf.........................................................................................................28
4.1 graf.h................................................................................................................ 29
4.2 graf.cpp............................................................................................................ 30
3
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
5. 50
Bibliografie...........................................................................................................
Argument
nc de la apariia limbajelor de programare s-a ncercat ca acestea s descrie cat mai bine
realitatea. Programarea Orientata pe Obiecte (POO) este o modalitate avansat de programare care
se apropie foarte mult de acest scop. Cuvantul cheie e obiectul (clasa).
Am ales graful ca tem pentru realizarea proiectului deoarece consider c grafurile au o
importan deosebit fiind utilizai n domenii precum: cibernetic, matematic, cercetri
operaionale n vederea optimizrii diferitelor activiti economice, chimie (pentru descrierea
structurii cristalelor), reelele de transport de toate tipurile (pentru optimizarea traseelor), circuite
electrice (pentru simularea funcionri corecte), inteligena artificiala i nu n ultimul rnd n
domeniul analizei aplicaiilor software.
4
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
(noiuni introductive)
Clase i obiecte
5
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
Definitia 1
Clasa, ntr-un anumit limbaj de programare, reprezin definirea unui tip de obiecte
abstracte sau concrete, adic descrierea proprietilor, a datelor i a metodelor, a prelucrrilor,
posibile asupra datelor. Clasa este, de fapt, o noiune abstracta, care defineste un anumit tip de
obiecte, sau, altfel spus, o clas reprezin mulimea posibila a mai multor obiecte de acelasi tip.
Definitia 2
Obiect, reprezin o multime de date care descrie un anumit obiect concret sau
abstract, numite i proprieti, impreuna cu procedurile, funciile, de prelucrare a cestora, numite
metode.
Crearea unui obiect presupune specificarea clasei din care face parte, astfel
idendtificndu-se proprietile obiectului i modul n care acestea pot fi folosite i prelucrate
Observaie:
Crearea sau declararea unui obiect este similar cu crearea sau declararea unor variabile.
Declararea unei variabile se face, dup cum se stie, prin specificarea identificatorului acesteia,
precedat de tipul variabilei iar declararea unui obiect presupune precizarea identificatorului
acestuia, precedat de clasa din care face parte, clasa care n mod implicit determin proprietile i
metodele obiectului definit.
n fiierul nume_clasa.h:
class [nume_clasa]
{
6
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
specificator_acces1;
date_i_funcii1;
specificator_acces2;
date_i_funcii2;
..
specificator_accesn;
date_i_funciin;
}[obiect1] [,obiect2] [,obiectm];
In fiierul nume_clasa.cpp:
unde:
- specificator_accesi (i=1,n) este o eticheta care poate fi unul dintre cuvinele cheie:
public, private sau protected.
Spre deosebire de o structura, ai carei membri sunt toti accesibili programului, o clasa
poate avea membri pe care programul ii poate accesa direct (public), utilizand operatorul punct (.)
i alti membri, denumiti privati (private), pe care programul nu-i poate accesa direct. Unica
accesare a datelor i metodelor private (private) se face numai prin intermediul metodelor publice.
Dup cum se va vedea, o clasa poate deriva dintr-o clasa de baza, anterior definita, concept
cunoscut sub numele de mostenire. Un membru protejat (protected) are un statut intermediar intre
membri publici i privati. Pentru clasa de baza, obiectele acesteia pot accesa membri protejati, ca i
cum ar fi publici, iar obiectele claselor derivate nu pot accesa un membru declarat protected n
clasa de baza, decat prin intermediul unor funcii de interfata declarate publice.
7
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
Observaii:
8
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
2. Grafuri neorientate
2.1 Noiuni introductive
Definiie Se numete graf neorientat o pereche ordonat de mulimi G=(X,U), unde X este o
mulime finit i nevid de elemente numit mulimea vrfurilor (nodurilor), iar U este o mulime
de perechi neordonate de elemente din X numit mulimea muchiilor.
Not. G=(X,U) - graf neorientat
u=[x,y]U se numete muchie a grafului G=(X,U)
Exemplu: graful din Figura 1 1
2 3
G=(X,U)
X={1, 2, 3, 4, 5} Figura 1.
U={[1,5], [2,5], [2,4], [4,5]}
5 4
x,y se numesc extremiti ale muchiei u
Obs: [x,y]=[y,x] deoarece nu conteaz orientarea muchiei
Definiie Vrfurile x i y se numesc adiacente n G dac sunt extremiti ale aceleiai muchii.
Exemplu de vrfuri adiacente: 1-5, 2-5, 2-4 i 4-5
Definiie Spunem c dou muchii sunt incidente dac au o extremitate comun.
Exemplu: Muchiile [1,5] i [2,5] sunt incidente.
Definiie Un graf parial al grafului G=(X,U) este un graf G 1=(X,V) cu proprietatea c VU (este
graful nsui sau se obine din graful iniial prin eliminarea unor muchii). Se mai spune c graful
parial G1 este indus de mulimea de muchii V.
1
Exemplu: graful din figura 2, graf partial pentru figura 1 2 3
9
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
Definiie Un subgraf al unui graf neorientat G=(X,U) este un graf H=(Y,V) astfel nct YX i V
conine toate muchiile din U care au ambele extremiti n Y (poate fi graful iniial sau se obine din
acesta prin eliminarea unor vrfuri i a muchiilor incidente cu acestea). Spunem c subgraful H este
indus de mulimea de vrfuri Y. 1
d(5)=3
Figura 4.
d(1)=1 (vrf terminal)
5 4
d(3)=0 (vrf izolat)
Definiie Un graf se zice regulat, dac toate vrfurile sale au acelai grad.
Exemplu: graful din figura 5 2
d(1)=d(2)=d(3)=1 Figura 5.
1
3
Prop. Dac un graf G=(X,U) are n vrfuri i m muchii, iar X={x1, x2, , xn} atunci
d(xi)=2m, i=1,n. (suma gradelor vrfurilor unui graf este 2m)
Definiie Ordinul unui graf este numrul nodurilor sale.
Definiie Se numete graf complet cu n vrfuri un graf care are proprietatea c oricare dou noduri
diferite sunt adiacente.
1 2
Obs. 1. Un graf complet are n(n-1)/2 muchii.
2. d(i)=n-1 i={1,2,3,4}
Figura 6.
Exemplu: graful din figura 6 3
4
.
Definiie Fie un graf G=(X,U) cu vrfurile X={x 1, x2,, xn}. Se numete lan n graful G
succesiunea de vrfuri
10
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
L=[ x1, x2,, xk] cu proprietatea c dou vrfuri consecutive din L sunt adiacente, adic
muchiile
[ x1, x2], [x2,x3] [xik-1,xik] sunt din U.
Definiie Vrfurile x1 i xk se numesc extremitile lanului.
Definiie Numrul de muchii al unui lan reprezint lungimea lanului.
Figura 7
Exemplu:
L1=[3,2,4,5,6,3,1] (de lungime 6)
L2=[1,2,3,1,]; (de lungime 3)
L3=[7,5,6,3,1,2]; (de lungime 5)
Definiie Un lan este elementar dac toate vrfurile sale sunt distincte. Altfel este neelementar.
Definiie Un lan este simplu dac are toate muchiile distincte. n caz contrar se zice compus.
Obs. Un lan compus este neelementar.
Exemplu: pentru graful din Figura 11:
L1, L2 sunt lanuri neelementare
L3 este lan elementar, simplu;
Definiie Se numete ciclu n G un lan L pentru care x 1=xk i toate muchiile [x1, x2], [x2,x3] [xk-
1,xk] sunt diferite dou cte dou.
Definiie Se numete ciclu elementar un ciclu care are proprietatea c oricare dou vrfuri ale sale
su excepia primului i ultimului sunt diferite dou cte dou. Altfel se zice neelementar.
Exemplu: pentru graful din Figura 11:
C1=[1,2,4,5,6,3,1] este un ciclu elementar
C2=[3,7,5,6,3,1,2,4,5,6,3] este un ciclu neelementar
Definiie Lungimea unui ciclu este dat de numrul su de muchii.
Obs. Un ciclu are lungimea minim de trei muchii.
Definiie Fiecrei muchii a unui graf neorientat i se poate asocia o valoare real pozitiv care
reprezint costul acelei muchii.
Definiie Un graf neorientat n care fiecrei muchii i s-a asociat o valoare se numete graf ponderat
sau graf valoric.
11
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
Definiie Fie un graf neorientat G=(X, U) i o funcie L: UR+, care asociaz fiecrei muchii
uU un numr real numit costul (ponderea) sa L(u). Costul unui graf reprezint suma costurilor
muchiilor sale.
3
Exemplu: n figura 8 este un graf ponderat 1
2
Figura 8. 6
1 8
Pentru a desemna un graf (exemplu: figura 9) exist mai multe tipuri
4 de reprezentare:
1. Reprezentare grafica:
5
2
3
Figura 9
1 4 6
.
2. Specificarea mulimilor:
G=(V,U)
V={1,2,3,4,5,6}
U={[1,2], [2,3], [2,5], [5,6]}
3. Matricea de adiacen (si a costurilor)
Matricea de adiacen asociat acestui graf este o matrice ptratic A de dimensiune N cu
proprietatea c:
1, dac exist muchia [i, j] cu ij
a[i , j] =
0, altfel
12
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
G.v2: 2 3 5 6
Obs: n cazul grafurilor ponderate, structurii muchie I se mai adauga inca un camp cost
reprezentand costul muchiei (G[i].cost = costul muchiei [G[i].v1, G[i].v2])
13
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
3.1Citirea grafurilor
Grafurile pot fi citite sub diferite mijloace n funcie modul de reprezentare. Pentru a se
putea lucra cu grafuri, de obicei acestea se memoreaza ca matrice de adiacen, matrice a costurilor
sau ca vector de muchii.
3.2Afisarea grafurilor
La fel ca i citirea, afisarea grafurilor variaza n funcie de modul de reprezentare pe care il
dorim.
3.3Parcurgerea grafurilor
Parcurgerea unui graf presupune examinarea sistematic a vrfurilor grafului, cu scopul
prelucrrii informaiilor asociate vrfurilor.
Exist dou metode fundamentale de parcurgere a grafurilor:
1. Parcurgerea n adncime (DFS Depth First Search)
2. Parcurgerea n lime (BFS Breadth First Search)
a. Parcurgerea n adncime
Parcurgerea n adncime se caracterizeaz prin faptul c se merge n adncime ori de
cte ori este posibil.
~Parcurgerea ncepe cu vrful iniial, denumit vrful de start, care este i vizitat.
~Se viziteaz apoi primul vecin nevizitat al vrfului de start. Vrful y este considerat vecin
al vrfului x dac exist muchia [x,y].
~Se viziteaz n continuare primul vecin nevizitat al primului vecin al vrfului de start, i
aa mai departe, mergnd n adncime, pn cnd ajungem ntr-un vrf care nu mai are vecini
nevizitai. Cnd ajungem ntr-un astfel de vrf, revenim la vrful su printe (vrful din care acest
nod a fost vizitat). Dac acest nod mai are vecini nevizitai, alegem primul vecin nevizitat al su i
continum parcurgerea n acelai mod. Dac nici acest vrf nu mai are vecini nevizitai, revenim n
vrful su printe i continum n acelai mod, pn cnd toate vrfurile accesibile din vrful de
start sunt vizitate.
b. Parcurgerea n lime
14
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
~Parcurgerea n lime ncepe cu vrful iniial, denumit i vrful de start. Se viziteaz mai
nti vrful de start.
~Se viziteaz n ordine toi vecinii nevizitai ai vrfului de start.
~Apoi se viziteaz n ordine toi vecinii nevizitai ai vecinilor vrfului de start i aa mai
departe, pn la epuizarea tuturor vrfurilor accesibile din vrful de start.
Observaii
1. Parcurgerea n lime are o proprietate remarcabil: fiecare vrf este vizitat pe cel mai
scurt lan/drum, ncepnd din vrful de start.
2. Complexitatea timp a algoritmilor de parcurgere n adncime i n lime a unui graf
depinde de modalitatea de reprezentare a acestuia. n cazul reprezentrii prin liste de adiacen,
complexitatea este O(n+m). n cazul reprezentrii prin matrice de adiacen este (O(n*n)).
Parcurgerea n adancime
Parcurgerea n latime
Figura 10
15
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
Se verifica daca o succesine de numere (de obicei un vector) poate reprezenta nodurile
unui graf astfel incat acestea sa formeze:
- lan
- lan elementar
- ciclu
- ciclu elementar
-
3.5 Graf complementar
Definitie: Fie G=(X,U).Se numete graf complementar al grafului G graful G'=(X,U') cu
proprietatea ca dou vrfuri sunt adiacente n G' daca ele nu sunt grupuri adiacente n G.
Exemplu:
Fie un graf neorientat G = ( X,U ) cu
X = {1, 2,3,4,5}
si
U = {{1,2},{1,3},{1,4},{2,5},{4,5}} .
Cum U = 5 i numrul maxim de muchii este 10 rezult c graful
complementar are 5 muchii i astfel avem
V = CU = {{1,5},{2,3},{2,4},{3,4},{3,5}},
Obtinandu-se graful
CG = ( X,CU ) .
Grafurile din acest exemplu au urmtoarele imagini:
Figura 11
16
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
Figura 12
17
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
7
1
1 4
18 1
6 5 9 Figura 15
1 1
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
C1=[1,2,7,5,4,8,9,4,3,7,6,1]
C2=[7,2,1,6,7,3,4,9,8,4,5,7]
sunt cicluri euleriene
Teorem. Un graf G=(X,U) fra vrfuri izolate este eulerian dac i numai dac este conex
i gradele tuturor vrfurilor sunt numere pare.
Figura 16
19
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
viz:
1 2 3 4 5 6
n acest caz nodul 1 cum este nod de plecare se marcheaz n viz cu valoarea 0.
viz: 0
1 2 3 4 5 6
Pasul urmtor const n iniializarea restului valorilor din viz cu valori foarte mari.
viz: 0
1 2 3 4 5 6
Se construiete o coad cu numele c.
Pentru c s-a ales nodul 1 ca nod de plecare se noteaz n coad.
c: 1
Se alege nodul adiacent , n acest caz 5.
Se marchez n viz pe poziia 5 cu 1 pentru a evidenia costul.
viz: 0 1
1 2 3 4 5 6
Urmtorul nod adiacent al lui 1 care este 3; astfel se marchez n viz pe poziia 3 cu 4 i se
adaug n coad nodul 3.
c:1,5,3
viz: 0 4 1
1 2 3 4 5 6
Se ia n continuare urmtorul nod adiacent al lui 1, care este 2 i se marcheaz n viz pe
poziia 2 cu 5, iar n coad se aduag 2.
c:1,5,3,2
viz: 0 5 4 1
1 2 3 4 5 6
Urmtorul nod adiacent al lui 1 este 6 i astfel se marcheaz n viz pe poziia 6 cu 6, iar n
coad se adaug nodul 6.
c:1,5,3,2,6
viz: 0 5 4 1 6
1 2 3 4 5 6
Pentru c nodul 1 nu mai are adiaceni se trece la nodul urmtor, 5 i se marcheaz n coad
cu rou pentru a evidenia.
c:1,5,3,2,6
Se ia primul adiacent al lui 5,1.
20
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
Pentru c n vectorul viz costul pn la nodul 5 este 1,iar costul de la 5 la nodul 1 este 1,n
vector nu se va face nici o modificare deoarece valoarea costului obinut prin nsumarea
lor nu este o valoare mai mic decat n viz.
Urmtorul nod adiacent al lui 5 este 4.
Costul pn la nodul 5 este 1,iar de la 5 la 4 este 2.n vectoul viz se trece pe poziia 4 3
doarece acesta este costul obinut prin nsumare. Astfel se adaug i n coad nodul 4.
c:1,5,3,2,6,4
viz:0 5 4 3 1 6
1 2 3 4 5 6
Urmtorul nod adiacent al lui 5. ns nu sunt modificri n viz deoarece costul lui 5 pn la 1
este 1 i de la 5 la 6 este 9 i astfel, prin nsumare costul de la 5 la 6 devine 10 i este mai
mare decat era iniial.
Nodul urmtor din coad, 3.Se evideniaz cu rou n coad.
c:5,3,2,6,4
Primul adiacent al lui 3.Acesta fiind 1, nu exist modificri.
Urmtorul adiacent al lui 3 este 2. ns nici de data aceasta nu sunt modificri deoarece prin
nsumare(4+7=11) noul cost ar fi mai mare decat cel iniial,5.
Urmtor adiacent al lui 3 este 4. Noul cost ar deveni 7 prin nsumare(4+3=7) i astfel nu
sunt modificri.
Pentru c nu mai sunt adiaceni ai lui 3 se trece la nodul urmtor,2 i se n eviden cu rou
n coad.
c:1,5,3,2,6,4
Primul adiacent al lui 1.Nu sunt modificri n acest caz.
Urmtorul adiacent al lui 2 este 3. Prin nsumare noul cost al lui 3 ar deveni 12 i astfel nu
sunt modificri.
Urmtorul adiacent al lui 2 fiind 4 se afl ct ar deveni noul cost al lui 4. Prin nsumare ar
deveni i deci nu sunt modificri.
Urmtorul adiacent al lui 2 6, cu noul cost 9, care este mai mare dect 6 i deci nici de data
aceasta nu sunt modificri.
Se trece la urmtorul nod din coad pentru c nu mai sunt adiaceni ai lui 2.
c:1,5,3,2,6,4
Modificri nu sunt pentru acest nod.
21
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
22
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
Figura 17
Iniial:
viz:
Costul=0
Se alege muchia [2,4]
viz:
Costul=0+1costul=1;
Se alege muchia [5,6]
viz:
Costul=1+1costul=2
Se alege muchia [7,8]
viz:
Costul=2+1costul=3
Se alege muchia [2,6]
viz:
Costul=3+2costul=5
23
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
4
2 3 Figura 18
5 6
1 3
4
1
8
4
6 2 5
s:
1 2 3 4 5 6
viz:
1 2 3 4 5 6
t:
1 2 3 4 5 6
Pasul 1:
Se alege un nod x de start: 2
Se marcheaz vrful ca fiind vizitat (viz[2]=1)
Se completeaza valoarea n vectorul de tati
Se iniializeaz vectorul s astfel:
24
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
s[x]=0;
s[i]=x; ,i x
Dup executarea pasului 1:
s: 2 0 2 2 2 2
1 2 3 4 5 6
viz: 1
1 2 3 4 5 6
t: 0
1 2 3 4 5 6
Pasul 2:
Se allege cea mai mica muchie cu un capat selectat.
Se marcheaz capatul neselectat
Se actualizeaza vectorii viz, t i s.
Se reia pasul 2 de (n-2) ori.
Dup prima executie a pasului 2:
s: 2 0 2 5 2 5
1 2 3 4 5 6
viz: 1 1
1 2 3 4 5 6
t: 0 2
1 2 3 4 5 6
Dup a dou executie a pasului 2:
s: 2 0 6 5 2 5
1 2 3 4 5 6
viz: 1 1 1
1 2 3 4 5 6
t: 0 2 5
1 2 3 4 5 6
Dup a treia executie a pasului 2:
s: 2 0 6 5 2 5
1 2 3 4 5 6
viz: 1 1 1 1
1 2 3 4 5 6
t: 0 6 2 5
1 2 3 4 5 6
Dup a patra executie a pasului 2:
s: 2 0 6 5 2 5
1 2 3 4 5 6
25
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
viz: 1 1 1 1 1
1 2 3 4 5 6
t: 0 6 5 2 5
1 2 3 4 5 6
Dup a cincea executie a pasului 2:
s: 2 0 6 5 2 5
1 2 3 4 5 6
viz: 1 1 1 1 1 1
1 2 3 4 5 6
t: 2 0 6 5 2 5
1 2 3 4 5 6
Figura 19
26
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
Funciile operator constituie un tip special de funcii, care se pot utiliza pentru redefinirea
operatorilor de baza care apar n C++. O clasa se poate defini mpreuna cu un set de operatori
asociati, obtinuti prin suprancarcarea operatorilor existenti. n acest fel, se efectueaza operatii
specifice noului tip, la fel de simplu ca n cazul tipurilor standard.
Supradefinirea se realizeaza astfel:
tip_val_intoarsa operator op (lista_declar_parametri)
{
// . . . . corpul funciei
}
Supraincarcarea operatorului ,,+:
1. Graf +nr ( numar) adauga graficului nr noduri izolate
2. Graf + muchie adauga graficului muchia adunata, daca aceasta nu exist
Supraincarcarea operatorului ,,-:
1. Graf - nr scade graficului nodul nr, daca acesta exist. Totodata nodurile mai mari ca nr scad
cu o unitate pentru ca nodurile graficului sa fie consecutive
2. Graf - muchie scade graficului muchia adunata, daca aceasta exist
4. Clasa graf
Legenda:
n-numarul de noduri/vrfuri ale unui graf
m-numarul de muchii
ma-matricea de adiacen
mc-matricea costurilor
vm-vectorul de muchii (si cost)
viz-vectorul vizitat (margheaza muchiile care au fost deja utilizate n algoritm)
Observaii:
1. Pentru grafurile neponderate costul fiecarei muchii se considera 1
27
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
28
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
#include<iostream.h>
29
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
#include<fstream.h>
#include"graf.h"
#define inf 9999
int i, c[50], p=1, ca[50], cb[50], t[50], s[50], v[50], wr;
graf::graf()
{
n=0;
m=0;
}
graf::graf(unsigned x)
{
int i, j;
n=x;
m=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
ma[i][j]=0;
mc[i][j]=inf;
}
}
void graf::afisare_ma()
{
int i, j;
cout<<"\n Matricea de adiacenta:\n";
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
cout<<ma[i][j]<<" ";
cout<<'\n';
}
}
void graf::afisare_viz()
{
for(i=1;i<=n;i++)
cout<<viz[i]<<" ";
}
void graf::afisare_mc()
{
int i, j;
cout<<"\n Matricea costurilor:\n";
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
if(mc[i][j]==inf)
cout<<"0 ";
else
cout<<mc[i][j]<<" ";
cout<<'\n';
}
}
30
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
void graf::afisare()
{
int i, j;
cout<<"\n Numarul de noduri: "<<n<<"\n Numarul de muchii: "<<m;
cout<<"\n Matricea de adiacenta:\n";
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
cout<<ma[i][j]<<" ";
cout<<'\n';
}
cout<<"\n Matricea costurilor:\n";
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
if(mc[i][j]==inf)
cout<<"0 ";
else
cout<<mc[i][j]<<" ";
cout<<'\n';
}
cout<<"\n Vectorul de muchii si costuri:\n";
cout<<"x: ";
for(i=1;i<=m;i++)
cout<<vm[i].x<<" ";
cout<<"\ny: ";
for(i=1;i<=m;i++)
cout<<vm[i].y<<" ";
cout<<"\ncost: ";
for(i=1;i<=m;i++)
cout<<vm[i].cost<<" ";
cout<<'\n';
}
void graf::afisare_muchii()
{
int i, j;
cout<<"\n Muchii si costuri: \n";
for(i=1;i<=m;i++)
cout<<"("<<vm[i].x<<","<<vm[i].y<<") "<<"de cost "<<vm[i].cost<<'\n';
}
void graf::afisare_vm()
{
int i, j;
cout<<"\n Vectorul de muchii si costuri:\n";
cout<<"x: ";
for(i=1;i<=m;i++)
cout<<vm[i].x<<" ";
cout<<"\ny: ";
for(i=1;i<=m;i++)
cout<<vm[i].y<<" ";
cout<<"\ncost: ";
31
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
for(i=1;i<=m;i++)
cout<<vm[i].cost<<" ";
}
void graf::citire_f_n_ma(char *c)
{
int i, j;
m=0;
ifstream f(c);
f>>n;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
f>>ma[i][j];
ma[j][i]=ma[i][j];
if(ma[i][j]==0)
{
mc[i][j]=inf;
mc[j][i]=inf;
}
else
{
mc[i][j]=1;
mc[j][i]=1;
if(i<j)
{
m++;
vm[m].x=i;
vm[m].y=j;
vm[m].cost=1;
}
}
}
}
void graf::citire_f_n_m_muchii(char *c)
{
int i, j;
int x, y;
ifstream f(c);
f>>n>>m;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
ma[i][j]=0;
ma[j][i]=0;
mc[i][j]=inf;
mc[j][i]=inf;
}
for(i=1;i<=m;i++)
{
f>>x>>y;
ma[x][y]=1;
32
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
ma[y][x]=1;
mc[x][y]=1;
mc[y][x]=1;
vm[i].x=x;
vm[i].y=y;
vm[i].cost=1;
}
}
void graf::citire_f_n_mc(char *c)
{
int i, j;
ifstream f(c);
f>>n;
m=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
f>>mc[i][j];
if(mc[i][j]==0)
{
ma[i][j]=0;
ma[j][i]=0;
mc[i][j]=inf;
mc[j][i]=inf;
}
else
{
mc[j][i]=mc[i][j];
ma[i][j]=1;
ma[j][i]=1;
if(i<j)
{
m++;
vm[m].x=i;
vm[m].y=j;
vm[m].cost=mc[i][j];
}
}
}
}
void graf::citire_f_n_m_muchii_cost(char *c)
{
int i, j;
ifstream f(c);
f>>n>>m;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
ma[i][j]=0;
ma[j][i]=0;
mc[i][j]=inf;
33
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
mc[j][i]=inf;
}
for(i=1;i<=m;i++)
{
f>>vm[i].x>>vm[i].y>>vm[i].cost;
ma[vm[i].x][vm[i].y]=1;
ma[vm[i].y][vm[i].x]=1;
mc[vm[i].x][vm[i].y]=vm[i].cost;
mc[vm[i].y][vm[i].x]=vm[i].cost;
}
}
void graf::citire_t_n_ma()
{
int i, j;
m=0;
cout<<"\n Numarul de noduri: ";
cin>>n;
cout<<"\n Introduceti matricea de adiacenta.\n";
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
cin>>ma[i][j];
if(ma[i][j]==0)
mc[i][j]=inf;
else
{
mc[i][j]=1;
if(i<j)
{
m++;
vm[m].x=i;
vm[m].y=j;
vm[m].cost=1;
}
}
}
}
void graf::citire_t_n_m_muchii()
{
int i, j;
int x, y;
cout<<"\ Nnumarul de noduri: ";
cin>>n;
cout<<"\ Nnumarul de muchii: ";
cin>>m;
for(i=1;i<=n;i++)
for(j=i;j<=n;j++)
{
ma[i][j]=0;
ma[j][i]=0;
mc[i][j]=inf;
34
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
mc[j][i]=inf;
}
cout<<" Tastati "<<m<<" perechi de cate doua numere reprezentand capetele muchiilor: \n";
for(i=1;i<=m;i++)
{
cin>>x>>y;
ma[x][y]=1;
ma[y][x]=1;
mc[x][y]=1;
mc[y][x]=1;
vm[i].x=x;
vm[i].y=y;
vm[i].cost=1;
}
}
void graf::citire_t_n_mc()
{
int i, j;
cout<<"\n Numarul de noduri: ";
cin>>n;
m=0;
cout<<"\n Tastati matricea costurilor.\n";
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
cin>>mc[i][j];
if(mc[i][j]==0)
{
ma[i][j]=0;
mc[i][j]=inf;
}
else
{
ma[i][j]=1;
if(i<j)
{
m++;
vm[m].x=i;
vm[m].y=j;
vm[m].cost=mc[i][j];
}
}
}
}
void graf::citire_t_n_m_muchii_cost()
{
int i, j;
cout<<"\n Numarul de noduri: ";
cin>>n;
cout<<"\n Numarul de muchii: ";
cin>>m;
35
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
for(i=1;i<=n;i++)
for(j=i;j<=n;j++)
{
ma[i][j]=0;
ma[j][i]=0;
mc[i][j]=inf;
mc[j][i]=inf;
}
cout<<"\n Tastati "<<m<<" triplete de numere reprezentand capetele muchiilor si respectiv costul
lor. \n";
for(i=1;i<=m;i++)
{
cin>>vm[i].x>>vm[i].y>>vm[i].cost;
ma[vm[i].x][vm[i].y]=1;
ma[vm[i].y][vm[i].x]=1;
mc[vm[i].x][vm[i].y]=vm[i].cost;
mc[vm[i].y][vm[i].x]=vm[i].cost;
}
}
int graf::adiacenta(int x, int y)
{
return ma[x][y];
}
void graf::lista_adiacanta(int x)
{
int i, j;
if(x>n)
cout<<"\n Nu exista nodul "<<x<<" deci nu are adiacenti";
else
{
cout<<"\n Lista adiacentilor nodului "<<x<<": ";
for(i=1;i<=n;i++)
if(ma[x][i]==1)
cout<<i<<" ";
}
cout<<'\n';
}
int graf::grad(int x)
{
int i, j;
int gr=0;
for(i=1;i<=n;i++)
gr+=ma[x][i];
return gr;
}
void graf::set_m()
{
int i, j;
m=0;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
36
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
m+=ma[i][j];
}
void graf::set_viz(int nr)
{
int i;
for(i=1;i<=n;i++)
viz[i]=nr;
}
void graf::set_m(int x)
{
m=x;
}
void graf::set_vm()
{
int i, j;
m=0;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
if(mc[i][j]!=inf)
{
m++;
vm[m].x=i;
vm[m].y=j;
vm[m].cost=mc[i][j];
}
}
void graf::set_n(int x)
{
n=x;
}
void graf::set_mc()
{
int i, j;
cout<<"\n";
for(i=1;i<=n;i++)
for(j=i;j<=n;j++)
if(ma[i][j]==0)
{
mc[i][j]=inf;
mc[j][i]=inf;
}
else
{
mc[i][j]=1;
mc[j][i]=1;
}
}
void graf::set_ma()
{
int i, j;
for(i=1;i<=n;i++)
37
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
for(j=i;j<=n;j++)
if(mc[i][j]==inf)
{
ma[i][j]=0;
ma[j][i]=0;
}
else
{
ma[i][j]=1;
ma[j][i]=1;
}
}
void graf::set_i_j_ma(int i, int j, int x)
{
ma[i][j]=x;
ma[j][i]=x;
if(x==0)
{
mc[j][i]=inf;
mc[i][j]=inf;
}
else
{
mc[j][i]=1;
mc[i][j]=1;
m++;
vm[m].x=i;
vm[m].y=j;
vm[m].cost=1;
}
}
void graf::set_i_j_mc(int i, int j, int x)
{
if(x==0)
{
ma[i][j]=0;
ma[j][i]=0;
mc[j][i]=inf;
mc[i][j]=inf;
}
else
{
m++;
mc[i][j]=x;
mc[j][i]=x;
ma[j][i]=1;
ma[i][j]=1;
vm[m].x=i;
vm[m].y=j;
vm[m].cost=x;
}
38
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
}
void graf::set_i_vm(muchii aux)
{
m++;
vm[m]=aux;
ma[aux.x][aux.y]=1;
ma[aux.y][aux.x]=1;
mc[aux.x][aux.y]=aux.cost;
mc[aux.y][aux.x]=aux.cost;
}
int graf::get_n()
{
return n;
}
int graf::get_m()
{
return m;
}
muchii graf::get_i_vm(int i)
{
return vm[i];
}
int graf::get_i_j_ma(int i, int j)
{
return ma[i][j];
}
int graf::get_i_j_mc(int i, int j)
{
return mc[i][j];
}
void graf::get_muchie_i(int nr,int& i,int& j,int& c)
{
i=vm[nr].x;
j=vm[nr].y;
c=vm[nr].cost;
}
void graf::ordonare_vm()
{
int i, j;
int p=1;
muchii aux;
while(p<m)
{
if(vm[p].cost>vm[p+1].cost)
{
aux=vm[p];
vm[p]=vm[p+1];
vm[p+1]=aux;
p--;
}
else
39
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
p++;
if(p==0)
p++;
}
}
int graf::lant(int v[], int x)
{
int i, j;
for(i=1;i<x;i++)
if(ma[v[i]][v[i+1]]==0)
return 0;
return 1;
}
int graf::lant_elementar(int v[], int x)
{
int i, j;
if(this->lant(v,x)==0)
return 0;
for(i=1;i<x;i++)
for(j=i+1;j<=x;j++)
if(v[i]==v[j])
return 0;
return 1;
}
int graf::ciclu(int v[], int x)
{
int i, j;
if(v[1]!=v[x])
return 0;
if(this->lant(v,x)==0)
return 0;
for(i=1;i<x-1;i++)
for(j=i+1;j<x;j++)
if((v[i]==v[j]&&v[i+1]==v[j+1])||(v[i+1]==v[j]&&v[i]==v[j+1]))
return 0;
return 1;
}
int graf::ciclu_elementar(int v[], int x)
{
int i, j;
if(v[1]!=v[x]||ma[v[x-1]][v[x]]==0||x>n+1)
return 0;
return this->lant_elementar(v,x-1);
}
int graf::complementar(graf g)
{
int i, j;
if(n!=g.get_n())
return 2;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
40
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
if(ma[i][j]+g.get_i_j_ma(i,j)!=1)
return 0;
return 1;
}
void graf::bf(int x, int k)
{
int i, j, p=1, u=1, c[50];
//this->set_viz(0);
c[1]=x;
viz[x]=k;
while(p<=u)
{
x=c[p++];
for(i=1;i<=n;i++)
if(ma[x][i]==1&&viz[i]==0)
{
c[++u]=i;
viz[i]=k;
}
}
}
int graf::conex()
{
int i, j, c[50], p=1, u=1, x=1;
this->set_viz(0);
c[1]=x;
viz[x]=1;
while(p<=u)
{
x=c[p++];
for(i=1;i<=n;i++)
if(ma[x][i]==1&&viz[i]==0)
{
c[++u]=i;
viz[i]=1;
}
}
if(u==n)
return 1;
return 0;
}
int graf::eulerian()
{
int nr, ok=0;
if(this->conex()==0)
cout<<"\n Graful nu este eulerian pentru ca nu este conex.";
for(i=1;i<=n;i++)
{
nr=this->grad(i);
if(nr%2!=0)
{
41
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
if(ok==0)
cout<<"\n Graful nu este eulerian. Nodurile care nu au gradul par sunt:
";
cout<<i<<" ";
ok=1;
}
}
if(ok==0)
cout<<"\n Graful este eulerian.";
return 1;
}
int graf::hamiltonian()
{
int i;
if(this->conex()==0)
return 0;
else
for(i=1;i<=n;i++)
if(this->grad(i)<n/2)
return 0;
return 1;
}
void graf::componente_conexe()
{
int k, i, j;
k=0;
this->set_viz(0);
for(i=1;i<=n;i++)
if(viz[i]==0)
{
k++;
this->bf(i,k);
}
if(k==1)
{
cout<<'\n'<<" O singura componenta conexa: ";
for(i=1;i<=n;i++)
cout<<i<<" ";
}
else
{
cout<<"\n "<<k<<" componente conexe.\n";
for(i=1;i<=k;i++)
{
cout<<" Componenta "<<i<<": ";
for(j=1;j<=n;j++)
if(viz[j]==i)
cout<<j<<" ";
cout<<'\n';
}
42
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
}
}
void graf::df_auxiliar(int x)
{
int wr;
cout<<x<<" ";
v[x]=1;
for(wr=1;wr<=n;wr++)
if(ma[x][wr]==1&&v[wr]==0)
this->df_auxiliar(wr);
}
void graf::df(int x)
{
int i, j;
this->set_viz(0);
this->df_auxiliar(x);
}
void graf::prim(int x)
{
int i, j, p, min,k, c=0;
this->set_viz(0);
viz[x]=1;
t[x]=0;
for(i=1;i<=n;i++)
s[i]=x;
s[x]=0;
for(k=1;k<=n-1;k++)
{
min=inf;
for(i=1;i<=n;i++)
if(viz[i]==0&&mc[i][s[i]]<min)
{
min=mc[i][s[i]];
p=i;
}
t[p]=s[p];
viz[p]=1;
c=c+mc[p][s[p]];
for(i=1;i<=n;i++)
if(!viz[i]&&mc[i][s[i]]>mc[i][p])
s[i]=p;
}
cout<<"\n Costul arborelui de cost minim "<<c<<'\n';
cout<<" Vectorul de tati: ";
for(i=1;i<=n;i++)
cout<<t[i]<<" ";
cout<<'\n';
}
void graf::kruskal()
{
int i=1, j, k, c=0;
43
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
this->set_viz(0);
this->ordonare_vm();
cout<<"\n Kruskal: \n";
cout<<" Muchii alese: \n";
for(k=1;k<=n-1;k++)
{
while(viz[vm[i].x]==viz[vm[i].y]&&viz[vm[i].x]!=0)
i++;
c+=vm[i].cost;
cout<<"("<<vm[i].x<<","<<vm[i].y<<")"<<"de cost "<<vm[i].cost<<'\n';
if(viz[vm[i].x]+viz[vm[i].y]==0)
viz[vm[i].x]=viz[vm[i].y]=vm[i].x;
else
if(viz[vm[i].x]*viz[vm[i].y]==0)
viz[vm[i].x]=viz[vm[i].y]=viz[vm[i].x]+viz[vm[i].y];
else
{
for(j=1;j<=n;j++)
if(viz[j]==viz[vm[i].x]&&j!=vm[i].x)
viz[j]=viz[vm[i].y];
viz[vm[i].x]=viz[vm[i].y];
}
i++;
}
cout<<" Costul arborelui Kruskal: "<<c;
}
void graf::bellman_ford(int x)
{
int pr=1, u=1, i, j, p[51];
this->set_viz(inf);
viz[x]=0;
c[1]=x;
while(pr<=u)
{
x=c[pr];
pr++;
for(i=1;i<=n;i++)
if(mc[x][i]!=0)
if(viz[x]+mc[x][i]<viz[i])
{
viz[i]=viz[x]+mc[x][i];
p[i]=x;
u++;
c[u]=i;
}
}
p[c[1]]=0;
cout<<"\n viz: ";//vizul in acest caz are salvate pe pozitia i, costul minim de a ajunge de la x la
nodul i
for(i=1;i<=n;i++)
cout<<viz[i]<<" ";
44
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
cout<<"\n\n p: ";
for(i=1;i<=n;i++)
cout<<p[i]<<" ";
}
int graf::graf_partial(graf G1)
{
int i, j;
if(n!=G1.get_n())
return 0;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
if(ma[i][j]==0&&G1.get_i_j_ma(i,j)==1)
return 0;
return 1;
}
45
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
G1.set_i_j_ma(i, j, ma[i][j]);
back(1, G2,G1);
if(suma==0)
return 0;
return 1;
}
int graf::complet()
{
int i, j;
for(i=1;i<n;i++)
for(j=i+1;j<=n;j++)
if(ma[i][j]==0)
return 0;
return 1;
}
int graf::bipartit()
{
this->set_viz(0);
int pa=0, pb=0, ua=0, ub=0, ok=1, i, j, k, x;
for(i=1;i<=n&&ok==1;i++)
if(viz[i]==0)
{
ca[++ua]=i;
viz[i]=1;
if(ua==1)
pa=1;
while((pa<=ua||pb<=ub)&&ok==1)
{
while(pa<=ua&&ok==1)
{
x=ca[pa];
for(j=1;j<=n&&ok==1;j++)
if(ma[x][j]==1&&viz[j]==0)
{
cb[++ub]=j;
if(ub==1)
pb=1;
for(k=1;k<ub&&ok==1;k++)
if(ma[cb[ub]][cb[k]]==1)
ok=0;
viz[j]=1;
}
pa++;
}
while(pb<=ub&&ok==1)
{
x=cb[pb];
for(j=1;j<=n&&ok==1;j++)
if(ma[x][j]==1&&viz[j]==0)
{
ca[++ua]=j;
46
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
if(ua==1)
pa=1;
for(k=1;k<ua&&ok==1;k++)
if(ma[ca[ua]][ca[k]]==1)
ok=0;
viz[j]=1;
}
pb++;
}
}
}
return ok;
}
graf operator+(graf G1, int nr)
{
int i, j, nnr, mnr=0;
graf G2;
nnr=G1.get_n();
G2.set_n(nnr+nr);
G2.set_m(0);
for(i=1;i<=nnr;i++)
for(j=i;j<=nnr;j++)
if(G1.get_i_j_mc(i,j)!=inf)
G2.set_i_j_mc(i,j,G1.get_i_j_mc(i,j));
else
G2.set_i_j_mc(i,j,0);
for(i=nnr+1;i<=nnr+nr;i++)
for(j=1;j<=nnr+nr;j++)
G2.set_i_j_mc(i,j,0);
return G2;
}
graf operator+(graf G1, muchii aux)
{
int i, j, ma1, mc1, nnr, mnr=0;
graf G2;
muchii aux1;
G2.set_m(0);
nnr=G1.get_n();
G2.set_n(nnr);
for(i=1;i<=nnr;i++)
for(j=i;j<=nnr;j++)
if(G1.get_i_j_mc(i,j)!=inf)
G2.set_i_j_mc(i,j,G1.get_i_j_mc(i,j));
else
G2.set_i_j_mc(i,j,0);
G2.set_i_vm(aux);
return G2;
}
graf operator-(graf G1, int nr)
{
int i, j, nnr;
47
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
graf G2;
nnr=G1.get_n();
G2.set_n(nnr-1);
for(i=1;i<=nr-1;i++)
for(j=i;j<=nr-1;j++)
if(G1.get_i_j_mc(i,j)!=inf)
G2.set_i_j_mc(i,j,G1.get_i_j_mc(i,j));
else
G2.set_i_j_mc(i,j,0);
//G2.afisare();
for(i=1;i<nr;i++)
for(j=nr;j<nnr;j++)
if(G1.get_i_j_mc(i,j+1)!=inf)
G2.set_i_j_mc(i,j,G1.get_i_j_mc(i,j+1));
else
G2.set_i_j_mc(i,j,0);
for(i=nr;i<nnr;i++)
for(j=i;j<nnr;j++)
if(G1.get_i_j_mc(i+1,j+1)!=inf)
G2.set_i_j_mc(i,j,G1.get_i_j_mc(i+1,j+1));
else
G2.set_i_j_mc(i,j,0);
return G2;
}
graf operator-(graf G1, muchii aux)
{
graf G2;
int nnr, mnr, i, j, s, d, f;
nnr=G1.get_n();
G2.set_m(0);
G2.set_n(nnr);
mnr=G1.get_m();
for(i=1;i<=nnr;i++)
for(j=i;j<=nnr;j++)
{
G2.set_i_j_mc(i,j,0);
}
for(i=1;i<=mnr-1;i++)
{
if((G1.get_i_vm(i).x==aux.x&&G1.get_i_vm(i).y==aux.y&&G1.get_i_vm(i).cost==aux.cost)||
(G1.get_i_vm(i).x==aux.y&&G1.get_i_vm(i).y==aux.x&&G1.get_i_vm(i).cost==aux.cost))
G2.set_i_vm(G1.get_i_vm(i+1));
else
G2.set_i_vm(G1.get_i_vm(i));
}
return G2;
}
48
D.E.C.: Programare orientat pe obiect. Grafuri neorientate.
5. Bibliografie
http://facultate.regielive.ro
http://www.graf.go.ro/index1.html
http://ro.wikipedia.org/wiki/Graf
http://ro.wikipedia.org/wiki/Programare_orientat%C4%83_pe_obiecte
http://www.aut.upt.ro/~dberian/Labs/POO.pdf
http://ro.wikipedia.org/wiki/Algoritmul_lui_Kruskal
http://ro.wikipedia.org/wiki/Algoritmul_lui_Prim
http://grafurineorientate.wikispaces.com/
49