Você está na página 1de 26

Estruturas de Informao - Grafos-Terminologia

__________________________________________________________________________________

GRAFOS
Consideramos informalmente, grafo como um conjunto no vazio de pontos V
(vrtices, ns, nodos) podendo ou no haver ligaes entre eles atravs de linhas
(lados, ramos, arcos)
G= (V,E) , V conjunto dos vrtices
E conjunto dos ramos
A cada ramo do grafo podemos associar um par de vrtices do grafo.
x
E , x>(u, v) tal que u e v V , dizemos que x liga os vrtices u e v que
so designados por vrtices adjacentes.
Aqui estudaremos representaes de grafos e algoritmos para os manipular
eficientemente.

TERMINOLOGIA
Ramo Orientado se a linha que une dois vrtices tem sentido, um vrtice origem e um
vrtice destino.
Grafo Orientado ou Digrafo se todos os ramos dos grafo so orientados.
Ex:
mapa da cidade das ruas de sentido nico
Grafo no Orientado se todos os ramos so no orientados
Ex:
mapa da cidade das ruas com 2 sentidos
Grafo Misto se tem ramos orientados e no orientados.
Na representao de grafos usaremos setas para indicar os sentidos dos ramos
orientados.
1
3

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
1

Estruturas de Informao - Grafos-Terminologia


__________________________________________________________________________________

Neste exemplo os vrtices 1 e 2 so origem e os vrtices 2 e 3 so destino


Ramo Incidente num vrtice v, qualquer ramo para o qual v vrtice destino. No
caso de ramo no orientado incidente nos dois vrtices que o ramo liga.
Anel um ramo de um grafo que liga um vrtice a si prprio
Ramos Paralelos so ramos que ligam os mesmos ns
Multigrafo um grafo que contem ramos paralelos, caso contrrio ser Grafo
Simples
Multiplicidade (peso) de um ramo valor que indica o nmero de ramos, com o
mesmo sentido, que ligam 2 ns. Pode generalizar-se este conceito de peso e associarse a cada ramo um valor inteiro que representar um atributo do ramo. Por exemplo,
no caso de representao de um mapa das rua de uma cidade, poder-se-ia considerar
em cada ramo um nmero (peso) que poderia ser a densidade de trfego.
Vrtice Isolado um vrtice que no origem nem destino de nenhum ramo.
Grafo Nulo um grafo constitudo s por vrtices isolados.

Grau de Sada de um vrtice v (grafo orientado), o nmero de ramos de que v


vrtice origem.
Grau de Entrada de um vrtice v (grafo orientado), o nmero de ramos de que v
vrtice destino.
Grau de um vrtice v num grafo orientado, o grau de entrada
desse vrtice.

o grau de sada

Grau de um vrtice v num grafo no orientado, o nmero de ramos incidentes a v.


Caminho de um vrtice vi para um vrtice vj a sucesso de vrtices, vi, vk, vm,...
vj tais que: (vi,vk), (vk,vm),...( ,vj) so ramos do grafo.
Circuito, um caminho em que o vrtice inicial coincide com o final.
Caminho Simples ser um caminho formado por ramos todos distintos
Caminho Elementar caminho formado por nodos todos distintos.
Comprimento de um caminho o nmero de ramos que o formam
__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
2

Estruturas de Informao - Grafos-Terminologia


__________________________________________________________________________________

Ciclo um caminho elementar em que coincidem o vrtice inicial e final. Um ciclo


um circuito mas um circuito pode no ser um ciclo.
Grafo Acclico um grafo sem ciclos.
Grafo Simtrico um grafo orientado no qual sejam quais forem os vrtices vi e vj, se
(vi,vj) for ramo do grafo, tambm (vj,vi) o e.
Grafo Conexo um grafo em que quaisquer que sejam os vrtices vi e vj existe pelo
menos um caminho (sequncia de ns adjacentes) entre vi e vj.
Grafo Completo um grafo em que quaisquer que sejam os vrtives vi e vj tal que,
vivj, existe um ramo (vi,vj) ou um ramo (vj,vi).
Vizinhana de um vrtice v o conjunto de vrtices adjacentes de v
Ordem de um grafo o nmero de vrtices que o grafo contem.
Tamanho de um grafo o nmero de ramos que o grafo contem..

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
3

Estruturas de Informao - Grafos-Matriz de Adjacncias


__________________________________________________________________________________

REPRESENTAO DE GRAFOS
1. Matriz de Adjacncias
Usar uma matriz para representar computacionalmente um grafo fcil e permite
executar algumas das operaes sobre matrizes que vo ser usadas para obter
caminhos, ciclos e outras caractersticas dos grafos.
Seja G=(V,E) um digrafo em que V={v1,v2,....vn} e em que os ns esto ordenados de
v1 a vn.
A matriz quadrada M (n x n) cujos elementos so mij em que:
mij=1 se (vi,vj) E ou seja se existe ligao entre i e j
mij=0 nos outros casos, no existe ligao entre i e j.
chamada a matriz de adjacncias do grafo G.
Exemplo:
V1

V4

V2

V3

A matriz de adjacncias correspondente a este digrafo ser a seguinte:

M=

v1
v2
v3
v4

v1
0
1
0

v2
1
1
1
1

v3
0
0
0
0

v4
1
0
1
0

As linhas correspondem aos vrtices origem e as colunas aos vrtices destino.


Podemos estender esta definio aos grafos pesados em que substituimos os valores 1s
pelos pesos dos ramos respectivos.
No caso de um grafo nulo, s constitudo por vrtices, no tem ramos, a matriz de
adjacncias a matriz nula, com todos os valores a zero.
Vejamos agora o que representam as potncias da matriz de adjacncias.
J sabemos que na matriz de adjacncias o valor 1 em mij, corresponde ligao entre i
ej.
Consideraremos cada elemento da matriz M2 como sendo m2ij, em que:
__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
4

Estruturas de Informao - Grafos-Matriz de Adjacncias


__________________________________________________________________________________

m2ij = m ik m kj em que k varia de 1 a n.

(exp. 1)

Assim para qualquer valor de k, m2ij s ser 1 se m ik for 1 e se m kj tambm for 1, ou


seja se houver ligao entre os vrtices i,k e ainda entre k,j (isto , existir um caminho
entre i e j de comprimento 2 pois passa de i para k e de k para j). Logo como cada
elemento da matriz M2 um somatrio, o valor de cada elemento representar o
nmero de caminhos de comprimento 2 entre os diferentes ns i e j.

M 2=

v1
v2
v3
v4

v1
1
0
1
1

v2
1
1
2
0

v3
0
0
0
0

v4
0
1
1
0

Fazendo um raciocnio anlogo concluiramos que cada elemento de M3 ( matriz


produto de M por M2) representaria o nmero de caminhos existentes entre cada
vrtice i para j, de comprimento 3 e assim sucessivamente poderamos ter M4,M5, ...
No nosso exemplo, termos:

M3 =

M 4=

v1
v2
v3
v4

v1
1
1
2
0

v2
1
1
2
1

v3
0
0
0
0

v4
1
0
1
1

v1
v2
v3
v4

v1
1
1
2
1

v2
2
1
3
1

v3
0
0
0
0

v4
1
1
2
0

Se somssemos as matrizes potncia de M iramos obter a matriz B


B = M + M2 + M3 + ... + Mn

(exp 2)

em que o elemento de B , na linha i, coluna j, representaria o nmero de caminhos


entre i e j de comprimento menor ou igual a n.
No nosso exemplo seria ento

B =

v1
v2

v1
3
3

v2
5
3

v3
0
0

v4
3
2

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
5

Estruturas de Informao - Grafos-Matriz de Adjacncias


__________________________________________________________________________________

v3
v4

6
2

8
3

0
0

5
1

Por vezes estamos interessamos em saber se existe ou no caminho entre dois ns e


no o nmero de caminhos existentes. Nesse caso podemos substituir as operaes
algbricas sobre as matrizes por operaes lgicas.(A soma por "ou" e o produto por
"e")
A expresso 1 converter-se-ia em :
m(2) ij = V m ik m kj em que k varia de 1 a n.
e neste caso a matriz M(2) dar-nos- se existe ou no caminho de comprimento 2 entre
cada par de vrtices.

M (2)=

M (3)=

M (4)=

v1
v2
v3
v4

v1
1
0
1
1

v2
1
1
1
0

v3
0
0
0
0

v4
0
1
1
0

v1
v2
v3
v4

v1
1
1
1
0

v2
1
1
1
1

v3
0
0
0
0

v4
1
0
1
1

v1
v2
v3
v4

v1
1
1
1
1

v2
1
1
1
1

v3
0
0
0
0

v4
1
1
1
0

A expresso 2 converter-se-ia em:


P = M v M(2 ) v M(3 ) v ... v M(n )
B conhecida por matriz dos caminhos, em que cada elemento desta matriz ou
zero ou um, significando respectivamente se no existe ou se existe caminho de
comprimento menor ou igual a n, entre cada par de vrtices. No caso do exemplo que
temos vindo a considerar, a matriz dos caminhos seria dada por:

P=

v1
v2
v3
v4

v1
1
1
1
1

v2
1
1
1
1

v3
0
0
0
0

v4
1
1
1
1

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
6

Estruturas de Informao - Grafos-Matriz de Adjacncias


__________________________________________________________________________________

Um mtodo para obter a matriz dos caminhos de um digrafo simples o conhecido


algoritmo de Warshall, que se traduz pelo encaixamento de 3 ciclos conforme se
descreve a seguir:
Algoritmo de Warshall
Inicio
Para k=1 at n
Para i=1 at n
Para j=1 at n
P[i,j]=P[i,j] v P[i,k] P[k,j]
Fpara
Fpara
Fpara
Fim algoritmo

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
7

Estruturas de Informao - Grafos-Matriz de Adjacncias


__________________________________________________________________________________

MATRIZ DE ADJACNCIAS -- DIGRAFOS PESADOS


DEFINIO EM C++
Consideramos como classe base para a representao de grafos atravs de matriz de
adjacncias a classe matadjpdig, isto , a classe correspondente a digrafos pesados. A
partir desta podemos derivar as classes para digrafos no pesados, para grafos no
dirigidos pesados e no pesados .
Consideramos a matriz como sendo de elementos do tipo T, que ser a classe
representativa dos ramos do digrafo. Quando no existe ligao entre 2 vtices
colocamos um objecto que designamos por noramo ( no caso de T ser int geralmente
noramo igual a zero). Para alm da matriz e de noramo so ainda atributos da classe
o nmero de vrtices (nvert) e o nmero de ramos (nramos) que o grafo tem.
template<class T>
class matadjpdig
{
private:
T ** mat;
int nvert;
int nramos;
T noramo;
public:
matadjpdig();
matadjpdig(int nv,T nor);
matadjpdig(const matadjpdig & m);
~matadjpdig();
matadjpdig<T> & operator=(const matadjpdig &m);
bool existeRamo(int i,int j) const;
int numRamos()
{
return nramos; }
int numVert()
{
return nvert; }
matadjpdig<T> & adiciona(int i,int j,const T & peso);
matadjpdig<T> & elimina(int i,int j);
int grausaida(int i) const;
int grauentrada(int i) const;
void matrizCaminhos();
};
IMPLEMENTACAO DOS METODOS DA CLASSE
CONSTRUTORES
template<class T>
matadjpdig<T>::matadjpdig()
{
mat=NULL;
}

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
8

Estruturas de Informao - Grafos-Matriz de Adjacncias


__________________________________________________________________________________

template<class T>
matadjpdig<T>::matadjpdig(int nv,T nor)
{
nvert=nv;
nramos=0;
noramo=nor;
fazerMatriz(mat,nvert,nvert);
// Inicializa o grafo
for(int i=0;i<nv;i++)
for(int j=0;j<nv;j++)
mat[i][j]=nor;
}
template<class T>
matadjpdig<T>::matadjpdig (const matadjpdig & g)
{
fazerMatriz(mat,g.nvert,g.nvert);
for(int i=0;i<g.nvert;i++)
for(int j=0;j<g.nvert;j++)
mat[i][j]=g.mat[i][j];
nvert=g.nvert;
noramo=g.noramo;
nramos=g.nramos;
}
MTODOS PARA ADICIONAR E ELIMINAR RAMOS
template<class T>
matadjpdig<T> & matadjpdig<T>::adiciona(int i,int j,const T & peso)
{
// Verifica se ja existe ligacao
if(i>=0 && j>=0 && i<nvert && j<nvert && i!=j && mat[i][j]==noramo)
{
mat[i][j]=peso;
//So aumenta o nmero de ramos se o ramo tiver peso
if(peso!=noramo)
nramos++;
}
return *this;
}
template<class T>
matadjpdig<T> & matadjpdig<T>::elimina(int i,int j)
{
// Verifica se ja existe ligacao
if(i>=0 && j>=0 && i<nvert && j<nvert && mat[i][j]!=noramo)
{
mat[i][j]=noramo;
nramos--;
}
return *this;
__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
9

Estruturas de Informao - Grafos-Matriz de Adjacncias


__________________________________________________________________________________

}
template<class T>
bool matadjpdig<T>::existeRamo(int i,int j) const
{
if(i<0||j<0||i>nvert||j>nvert||mat[i-1][j-1]==noramo)
return false;
return true;
}
DESTRUTOR
template<class T>
matadjpdig<T>::~matadjpdig()
{
destroiMatriz(mat,nvert);
}
FUNES AUXILIARES NO MEMBRO
template<class T>
void fazerMatriz(T ** &m,int lin,int col)
{
// Cria ponteiros para as linhas
m=new T *[lin];
//Aloca memoria para cada linha
for(int i=0;i<lin;i++)
m[i]=new T[col];
}
template<class T>
void destroiMatriz(T ** &m,int lin)
{
//Liberta memoria linha a linha da matriz
for(int i=0;i<lin;i++)
delete [] m[i];
//Liberta os ponteiros das linhas
delete [] m;
m=NULL;
}
OPERADOR DE ATRIBUIO
template<class T>
matadjpdig<T> & matadjpdig<T>::operator=(const matadjpdig &m)
{
if(this==&m)
return *this;
destroiMatriz(mat,nvert);
fazerMatriz(mat,m.nvert,m.nvert);
__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
10

Estruturas de Informao - Grafos-Matriz de Adjacncias


__________________________________________________________________________________

for(int i=0;i<nvert;i++)
for(int j=0;j<nvert;j++)
mat[i][j]=m[i][j];
nvert=m.nvert;
nramos=m.nramos
noramo=m.noramo;
return *this;
}
GRAUS DE UM VRTICE
template<class T>
int matadjpdig<T>::grausaida(int i) const
{
if (i>=0 && i<nvert)
{
// conta o nmero de ramos cuja origem o n i
int soma=0;
for(int j=0;j<nvert;j++)
if (mat[i][j]!=noramo)
soma++;
}
return soma;
}
template<class T>
int matadjpdig<T>::grauentrada(int i) const
{
if (i>=0 && i<nvert)
{
// conta o nmero de ramos cujo destino o n i
int soma=0;
for(int j=0;j<nvert;j++)
if (mat[j][i]!=noramo)
soma++;
}
return soma;
}
MATRIZ DOS CAMINHOS
template<class T>
void matadjpdig<T>::matrizCaminhos()
{
int i,j,k;
for(k=0;k<nvert;k++)
for(i=0;i<nvert;i++)
for(j=0;j<nvert;j++)
mat[i][j]=mat[i][j] || (mat[i][k] && mat[k][j]);
}

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
11

Estruturas de Informao - Grafos-Matriz de Adjacncias


__________________________________________________________________________________

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
12

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________

REPRESENTAO DE GRAFOS
2. Lista de Adjacncias
A forma de representar um grafo depende da natureza dos dados e das operaes que
vo ser realizadas sobre esses dados. A escolha da representao ainda afectada por
outros factores tais como o nmero de ns, a mdia do nmero de ramos que partem
de um n, a frequncia das operaes de insero e eliminao de ns e ramos,...
A representao anteriormente estudada, matriz de adjacncias, no muito favorvel
no caso de termos muitos vrtices mas poucos ramos, h um desperdcio de espao.
Outra forma que temos de fazer a representao computacional de um grafo atravs
de lista de adjacncias, isto consideramos um vector com tantos elementos quantos
os vrtices do grafo, ser um vector de vrtices, e de cada elemento do vector haver
um apontador para uma lista dos ramos que se ligam aos vrtices adjacentes.
Teremos um vector (ou ainda mais dinmico, uma lista) de vrtices e de cada
representao do vrtice haver uma lista de ramos que partem dele. Claro que em
grafos no dirigidos haver duplicao , isto , se existe um ramo entre o vrtice x e y
portanto com origem em x e destino em y, faz parte da lista dos adjacentes de x,
existir tambm como ramo com origem em y e destino em x ou seja na lista dos
adjacentes de y.
Vejamos grficamente como consideraramos o seguinte grafo:

2
5

A representao do grafo anterior atravs de lista de adjacncias ter a seguinte


configurao:

VRTICES ORIGEM

VRTICES DESTINO -RAMOS


(lista de adjacncias)

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
13

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________
grafo[ ]

ap

info

3
4

prox

Qualquer atributo referente aos ramos (por exemplo,distncia entre vrtices,....) teria
representao na lista de adjacncias.
Do mesmo modo que estudamos processos para visitar os ns de uma rvore , vamos
agora ver maneiras de percorrer um grafo.
Visita em Largura (Breadth First Search)
O algoritmo consiste no seguinte : a partir de um dado n origem, ver quais os
adjacentes e caso ainda no tenham sido visitados colocam-se numa fila auxiliar. O
prximo n origem o que est no inicio da fila, retirado desta e so inseridos na fila
os ns adjacentes daquele que eliminou caso no tenham sido visitados. Para verificar
se foram ou no visitados basta considerar um vector auxiliar com tantos elementos
quantos os vrtices do grafo, inicialmente todos com o valor 0. medida que vo
sendo visitados altera-se o valor no vector para um , ou para o nmero de ordem da
visita ,ou ....
Algoritmo
Inicio
Para i=1 at nvertices
vectoraux[i]=0
Fpara
Para i=1 at nvertices
(este ciclo garante que se passe por todos os vrtices do grafo)
Se vectoraux[i]==0
Ento inicia_fila;
(mtodo da estrutura Fila)
insere-fila(i); (mtodo da estrutura Fila)
BFS(i) (permite atingir os vrtices com caminho a partir do vrtice i)
Fse
Fpara
BFS(i)
Inicio
vectoraux[i]=1
Enquanto fila no vazia
vert=retira-fila()
__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
14

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________

ap=grafo[vert]
( apontador para a lista de ns adjacentes)
Enquanto ap =/= Nulo
outrovert=ap->info
Se vectoraux[outrovert]==0
Entao vectoraux[outrovert]=1
insere_fila(outrovert)
Fse
ap=ap->prox
(avana na lista de ns adjacentes)
Fenquanto
Fenquanto
Fim BFS
Fim algoritmo
Visita em Profundidade (Depth First Search)
A estratgia da visita em profundidade a seguinte: a partir de um n origem avanase para um n adjacente do primeiro, caso no tenha sido visitado, e a partir deste
ltimo, que passa a ser origem , para o seu adjacente no visitado e a partir deste par o
seu adjacente e..... percorrendo um caminho. Quando no puder avanar mais, regressa
ao ltimo considerado (backtraking) que ainda tem adjacentes no visitados, e avana
para o prximo adjacente e assim sucessivamente.
Algoritmo
Inicio
Para i=1 at nvertices
vectoraux[i]=0
Fpara
Para i=1 at nvertices
(este ciclo garante que se passe por todos os vrtices do grafo)
Se vectoraux[i]==0
Ento DFS(i) (permite desenvolver caminhos a partir do vrtice i)
Fse
Fpara
DFS(i)
vectoraux[i]=1
ap=grafo[i]
Enquanto ap=/= Nulo
outrovert=ap->info
Se vectoraux[outovert]==0
Entao DFS (outrovert)(chamada recursiva da funao)
Fse
ap=ap->prox
Fenquanto
Fim DFS
Fim Algoritmo
Esta funo recursiva poderia ser substituda por uma iterativa desde que se
considerasse uma stack auxiliar onde seriam guardados os apontadores para os vrtices
que faziam parte do caminho que se ia percorrendo. Fica como exerccio.
__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
15

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________

Caminho mais curto -- Algoritmo de Dijkstra


O objectivo determinar o caminho, a partir de um vrtice origem atingir um vrtice
destino, tal que o custo seja mnimo. O custo depende daquilo que o grafo representa,
pode ser distncia mnima, pode ser preo, ....
Claro que um processo seria, analisar todos os caminhos entre a origem e o destino e
determinar o mnimo, seria exaustivo, no era necessrio nenhuma estratgia especial
mas seria com certeza dispendioso em tempo.
O algoritmo de Dijkstra um algoritmo sistemtico que permite por vezes, atingir o
vrtice destino sem ser preciso analisar todas as hipteses.
Consiste no seguinte : a partir do vrtice origem verificam-se todos os ns adjacentes a
este (visita em largura) e toma-se nota do custo desde a origem at cada um deles,
regista-se quem o n pai (origem) e escolhe-se aquele que apresenta menor custo. Os
ns que puderam ser alcanados ficam num estado de espera, isto , j foi possvel
atingi-los mas at ao momento tinham custos superiores a outro que apresentava entre
todos um custo mnimo. A partir deste ltimo,nova origem, volta-se ento a procurar
todos os lhe esto adjacentes somar o custo desde a origem inicial. Se por acaso
atingirmos um vrtice que anteriormente tnhamos tido possibilidade de atingir,
verificamos se o custo actual maior ou menor do que o acumulado que ele apresenta.
Se for menor ento teremos que substituir o custo pelo novo valor (o menor) e o pai
passa a ser o vrtice nova origem. De todos os vrtices em aberto, isto todos os que
at ao momento j teria sido possvel atingir escolhe-se o que apresenta menor custo e
tudo se repete. Quando o vrtice que apresentar menor custo for o destino, ento
encontramos garantidamente o caminho de menor custo que ser dado, pela ordem
inversa, pelo pai do vrtice destino, pelo pai do pai do vrtice destino, pelo pai do pai
do pai do vrtice destino,.... at atingirmos um n sem pai (origem inicial).
Para implementao de tal algoritmo necessitamos de vrias estruturas auxiliares ,
vamos considerar os vectores seguintes:
vset[ ] d o estado actual de cada vrtice. Os estados possveis so trs. Inicialmente
todos os vrtices tm o valor 3, significando que ainda no foram atingidos ou
visitados. O valor 2 significa que j houve possibilidade de encontrar caminho at l
mas no apresentaram o menor custo. O valor 1 quando se atinge o n com o menor
custo de todos em aberto at ao momento. Quando um n seleccionado como sendo
o que apresenta menor custo retirado da lista de comparaes futuras.
pai[ ] o valor de cada elemento deste vector representa o pai do vrtice
correspondente ao ndice.
custo[ ] o valor de cada elemento deste vector representa o custo acumulado desde a
origem at ao vrtice correspondente ao ndice.
vlink[ ] este vector encadeia os vrtices que esto em aberto para se determinar qual
deles apresenta custo mnimo.
Exemplo:
__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
16

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________
6

2
3

1
4

3
1

seguinte
vlink[ ]

4
1

Graficamente o grafo acima juntamente com as


estruturas auxiliares poder ser representado do
modo:
custo[] pai[] vset[] grafo[]

v. destino custo

Vamos supor que pretendemos determinar o custo mnimo entre o vrtice 1 e o vrtice
4.
Os valor de vset ser 3 para todos os ndices excepto para o vset[1] que ter o valor
1.
Os custos ser inicialmente tudo a 0.
Do vrtice 1 as possibilidades so seguir para o vrtice 2 com custo 6 e faremos ento:
vset[2]=2
pai[2]=1
custo[2]=6
vlink[0]=2
o outro vrtice adjacente do 1 o vrtice 3 com custo 1 e portanto faremos:
vset[3]=2
pai[3]=1
custo[3]=1
vlink[0]=3 colocamos o vrtice 3 na cabea da lista dos vrtices possveis
vlink[3]=2
Escolhe-se o custo mnimo entre custo[3] e custo[2].O mnimo ser custo[3],
corresponde ao vrtice 3, logo repetiremos tudo tomando como origem o vrtice 3.
Faremos: vset[3]=1 e retiramos o vrtice 3 da lista dos possiveis vrtices, (vlink[0]=2 e
vlink[3]=0), vamos ver o que se passa a partir de 3.
Os vrtices adjacentes so o 4, logo
vset[4]=2
pai[4]=3
custo[4]=5
vlink[0]=4
vlink [4]=2
e ainda o vrtice 5, passando as estruturas auxiliares aos seguintes valores:
__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
17

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________

vset[5]=2
pai[5]=3
custo[5]=2
vlink[0]=5
vlink[5]=4
determinaremos agora qual o custo mnimo entre os ndices da lista vlink.So eles:
custo[5],custo[4],custo[2]
destes valores o menor custo[5], logo vrtice 5 ser retirado da lista e o seu estado
ser 1
vset[5]=1
vlink[0]=4
A partir de 5 os ns adjacentes so o n 4, mas o n 4 j faz parte dos que j foram
atingidos ( vset[4]=2), atravs do vrtice 3(pai[4]=3) e o custo que ele apresentava era
de 5 (custo[4]=5), mas agora conseguimos chegar ao vrtice 4 com um custo menor,
(custo at 5 +custo de 5 a 4 = 3) atravs do n 5, logo teremos que substituir o custo e
o pai de 4
custo[4]=3
pai[4]=5, no precisamos de alterar mais nada uma vez que o vrtice 4 j pertencia
lista dos atingiveis e o seu estado j estava com o valor 2.
O custo mnimo a determinar ser agora entre custo at ao vrtice 4 (vale 3) e o custo
at ao vrtice 2 (vale 6), so os nicos vrtices da lista vlink.
O mnimo o correspondente ao vrtice 4, mas este vrtice o destino pretendido
logo conseguimos atingi-lo pelo caminho de custo mnimo. O pai de 4 o vrtice 5, o
pai do 5 vrtice 3 e o pai de 3 o vrtice 1(origem).
Assim, nunca chegamos a explorar o que se passava a partir do vrtice 2, j que o
caminho at 2 nunca apresentou um custo mnimo.
A seguir apresenta-se um algoritmo que traduz o que foi explicado neste exemplo em
que a representao do grafo feita atravs de lista de adjacncias, na sua verso
menos dinmica isto , considerando um vector de apontadores para a lista de vrtices
adjacentes.
Algoritmo Dijsktra
Inicio
Ler_grafo
Ler (inicio), Ler (destino)
origem=inicio
iniciar(inicio)
Enquanto origem =/= destino
visita_lista(origem)
Se vlink[0]==0
Ento No existe caminho
Seno origem=mnimo()

esta funo mnimo devolve o vrtice que


apresenta desde inicial custo acumulado

mnimo

Fse
Fenquanto
escreve_caminho(inicio,destino)
Fim
Vejamos agora os algoritmos correspondentes a cada uma das funes invocadas.
__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
18

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________

iniciar(inicio)
vset[inicio]=1
vlink[0]=0
Para i=1 at n
Se i=/=inicio
Ento vset[i]=3
vlink[i]=0
custo[i]=0
Fse
Fpara
Fim iniciar
visita_lista( origem)
apdest=grafo[origem]
Enquanto apdest=/= Nulo
vdest=apdest->info
Se ( vset[vdest]=2 e (apdest->custo + custo[origem] <custo[vdest])
Ento // atinge-se o vertice por um caminho com menor custo, logo
// substitui-se o pai e o custo pelos novos valores

pai[vdest]=origem
Custo[vdest]=apdest->custo + custo[origem]
Fse
Se (vset[vdest]=3)
//n ainda no atingido
Ento vset[vdest]=2
vlink[vdest]=vlink[0]
vlink[0]=vdest
pai[vdest]=origem
custo[vdest]=apdest->custo + custo[origem]
Fse
apdest=apdest->prox
Fenquanto
Fim visita_lista
minimo( )
x=vlink[0]
min=custo[x]
varmin=x
z=0
anterior=z
Enqunto x=/=0
Se min>custo[x]
Ento min=custo[x]
anterior=z
varmin=x
Fse
z=x
x=vlink[x]
Fenquanto
__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
19

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________

vlink[anterior]=vlink[varmin]
vlink[varmin]=0
vset[varmin]=1
Devolve varmin
Fim mnimo
escreve_caminho(inicio,destino )
Enquanto destino =/=inicio
escreve "ramo" destino "-" pai[destino] // escreve os ramos do fim para o inicio
destino=pai[destino]
Fenquanto
Fim escreve_caminho

A representao de grafos com lista de adjacncias mas mais dinmica pode ver-se a
seguir, em que o vector de apontadores substitudo por uma lista ligada de vrtices e
cada vrtice ter um campo que apontar para uma lista ligada de adjacentes.
Seja o grafo seguinte:
10

conteudo

numvert

apramo

graf

33

apv rconteudo apr

10

apvertice
2

33

Utilizando esta representao faremos seguidamente a definio em C++, em que


contedo apontador para a classe template TV e rcontedo apontador para a classe
template TR
Assim precisamos de definir a classe vrtice, a classe ramo e a classe grafo, esta ltima
designamos por grafolistadj.

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
20

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________

Classe dos vrtices do grafo


template<class TV, class TR>
class vertice
{
friend class grafolistadj<TV, TR>;
private:
int numvert;
TV *conteudo;
vertice<TV,TR> * apvertice;
ramo<TV,TR> * apramo;
public:
vertice();
vertice(const TV & cont,int nv);
~vertice();
};
template<class TV,class TR>
vertice<TV,TR>::vertice()
{
numvert=0;
apvertice=apramo=NULL;
}
template<class TV,class TR>
vertice<TV,TR>::vertice(const TV & cont,int nv)
{
conteudo=new TV(cont);
numvert=nv;
apvertice=NULL;
apramo=NULL;
}
template<class TV,class TR>
vertice<TV,TR>::~vertice()
{
delete conteudo;
}
Classe representativa dos ramos que ligam os vrtices do grafo
template<class TV,class TR>
class ramo
{
friend class grafolistadj<TV,TR>;
private:
TR * rconteudo;
__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
21

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________

vertice<TV,TR> * apv;
ramo<TV,TR> * apr;
public:
ramo();
ramo(const TR & rcont,vertice<TV,TR> * pv);
~ramo();
};
template<class TV,class TR>
ramo<TV,TR>::ramo()
{
apv=apr=NULL;
rconteudo=NULL;
}
template<class TV,class TR>
ramo<TV,TR>::ramo(const TR & rcont,vertice<TV,TR> *pv)
{
rconteudo=new TR(rcont);
apv=pv;
apr=NULL;
}
template<class TV,class TR>
ramo<TV,TR>::~ramo()
{
delete rconteudo;
}
Representao de grafo dirigido atraves de lista de adjacncias. Consideramos aqui s
os mtodos, para alm do construtor, que vo permitir construir um grafo
(juntar_vertice e juntar_ramo).Outros mtodos como determinar os caminhos entre
dois vrtices, determinar qual deles mnimo, visitar o grafo em profundidade ou em
largura sero realizados nas aulas prticas.
template<class TV,class TR>
class grafolistadj
{
private:
int nvertices;
int nramos;
vertice<TV,TR> *graf;
vertice<TV,TR> * encontrar_vertice(int v);
public:
grafolistadj();
void juntar_vertice(const TV & cont);
void juntar_ramo(const TR & rcont,int vorigem, int vdestino);
};

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
22

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________

template<class TV,class TR>


grafolistadj<TV,TR>::grafolistadj()
{
nvertices=0;
nramos=0;
graf=NULL;
}
template<class TV,class TR>
void grafolistadj<TV,TR>::juntar_vertice(const TV & cont)
{
vertice<TV,TR> * vert;
vert=graf ;
nvertices++;
graf=new vertice<TV,TR>(cont,nvertices);
graf->apvertice=vert;
}
template<class TV,class TR>
void grafolistadj<TV,TR>::juntar_ramo(const TR & rcont,int vorigem,int vdestino)
{
ramo<TV,TR> * tempramo=NULL;
vertice<TV,TR> * tempvertice,* tempdestino=NULL;
tempvertice=encontrar_vertice(vorigem);
tempramo=tempvertice->apramo;
tempdestino=encontrar_vertice(vdestino);
tempvertice->apramo=new ramo<TV,TR>(rcont,tempdestino);
tempvertice->apramo->apr=tempramo;
nramos++;
}
template<class TV,class TR>
vertice<TV,TR> * grafolistadj<TV,TR>:: encontrar_vertice(int v)
{
vertice<TV,TR> * ap=graf;
int enc=1;
while(ap!=NULL && enc)
{
if (ap->numvert == v)
enc=0;
else ap=ap->apvertice;
}
if (enc==1)
return NULL;
else return ap;
}

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
23

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________

Ordenao Topolgica
A ordenao topolgica uma ordenao dos vrtices num grafo acclico dirigido, de
tal forma que se existe um caminho do vrtice vi para o vrtice vj, na ordenao
aparecer o vrtice vj depois de vi.
Para melhor compreender como se passa esta ordenao, consideremos o grafo a
seguir, como representando a estrutura de pr-requisitos (precedncias) de um curso,
em que os vrtices representam disciplinas e qualquer lado (v,w) indica que a
disciplina v deve ser realizada antes de se inscrever na disciplina w.

V1

V2

V3

V5
V4

V6

V7

A ordenao topolgica dessas disciplinas no mais do que qualquer sequncia de


disciplinas que no viole as exigncias de pr-requisitos.
claro, que numa ordenao topolgica no possvel o grafo ter ciclos, porque dois
vrtices v e w do ciclo, se v precede w, tambm w precede v.
Convm referir que a ordenao no necessariamente nica. Na figura as ordenes
topolgicas so as seguintes:
V1, V2, V5, V4, V3, V7, V6
V1, V2, V5, V4, V7, V3, V6
Um algoritmo simples para encontrar uma ordem topolgica, consiste em encontrar
qualquer vrtice com grau de entrada zero. Podemos escrever esse vrtice e retir-lo
do grafo com os lados de que ele origem. Aplicamos a mesma estratgia ao resto do
grafo.
Para formalizar isto, calculamos os graus de entrada de todos os vrtices no grafo
(construmos um vector) e todos os vrtices com grau zero so colocados numa fila.
Enquanto a fila no estiver vazia, retira-se da fila um vrtice v, e a todos os vrtices
adjacentes a v ser decrementado o grau de entrada de 1 unidade. Se o grau de entrada
de um desses vrtices passa a zero, o vrtice colocado na fila.
A ordem topolgica ser aquela em que os vrtices so retirados da fila.
Abaixo encontra-se um algoritmo para determinar uma ordem topolgica num grafo
representado por lista de adjacncias, atendendo definio feita para a classe template
grafolistadj<TV,TR>
Ordenaao Topolgica
INICIO
Conta=1
__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
24

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________

FazerVector(ge,nvertices)
//iniciar vector
Para i=0 at nvertices-1
Ge[i]=0
Fim Para
calcular_graus_entrada(ge) //mtodo descrito a seguir
//colocar na fila vertices com graus de entrada zero
Para i=0 at nvertices-1
Se (ge[i]==0)
Ento insere_fila(i)
Fim Se
Fim Para
//ordem topolgica
Enquanto (fila no vazia)
retira_fila(v)
escreveVertice: v
conta++
ap=encontrar_vertice(v) // mtodo da classe grafolistadj
ap1=ap->apramo
//actualizar graus de entrada dos vrtices adjacentes a v
Enquanto(ap1)
v1=ap1->apv->numvert
ge[v1]- Se (ge[v1]==0)
Ento insere _fila(v1)
Fim Se
ap1=ap1->apr
Fim Enquanto
Fim Enquanto
Se (conta<=nvertices)
Ento escreve Erro existe ciclo
Fim Se
FIM
Descreve-se a seguir o algoritmo do mtodo calcular_graus_entrada (ge)
calcular_graus_entrada (ge)
INICIO
ap=graf;
Enquanto(ap)
ap1=ap->apramo
Enquanto(ap1)
v=ap1->apv->numvert
ge[v] + +
ap1=ap1->apr
Fim Enquanto
ap=ap->apvertice
Fim Enquanto
FIM

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
25

Estruturas de Informao - Grafos-Lista de Adjacncias


__________________________________________________________________________________

APLICAES
So usados grafos para modelar uma infinidade de problemas do mundo real, tudo o
tem subjacente conectividade de informao, como seja o caso de mapas (em sistemas
de informao geogrfica), transportes (redes virias e areas), em engenharia
electrotcnica (distribuio electrica, circuitos elctricos), redes de computadores,
redes telefnicas,...
Uma outra aplicao interessante diz respeito ao escalonamento de tarefas num
projecto, conhecido pelo mtodo PERT ou CPM.
Num projecto, como por exemplo, a construo de uma barragem, estamos
interessados em determinar o caminho crtico, que uma ferramenta importante em
muitas situaes. O caminho crtico de um vrtice fonte (grau de entrada=0) para um
vrtice poo (grau de sada=0), um caminho tal que se uma actividade nesse caminho
for atrasada de um total t, ento todo o projecto ser atrasado de t. A representao
de actividades ser feita pelos ramos (dirigidos e pesados)do grafo. Os ramos ligam
vrtices representando o tempo de incio e o de finalizao da actividade. O peso de
cada ramo corresponder durao prevista para a actividade que o ramo representa.
Algoritmos para implementao deste mtdo podero ser consultados em diversos
livros nomeadamente em "An Introduction to Data Structures With Applications" de
Jean Paul Tremblay e Paul G.Sorenson da McGraw Hill International Editions.
Outra aplicao importante no algoritmo "mark-sweep" do mecanismo de Garbage
Collection, usado na gesto de memria do Java. Esta aplicao encontra-se descrita
em "Data Structures and Algorithms in Java" de Michael T. Goodrich e Roberto
Tamassia da John Wiley & Sons, Inc.

__________________________________________________________________________________
Departamento de Eng Informtica do ISEP
26