Você está na página 1de 26

Projeto de Algoritmos Cap.

7 Algoritmos em Grafos

Motivao
Muitas aplicaes em computao
necessitam considerar conjunto de conexes
entre pares de objetos:
Existe um caminho para ir de um objeto a
outro seguindo as conexes?

Algoritmos em Grafos

Qual a menor distncia entre um objeto


e outro objeto?
Quantos outros objetos podem ser
alcanados a partir de um determinado
objeto?
Existe um tipo abstrato chamado grafo que
usado para modelar tais situaes.

ltima alterao: 26 de Abril de 2004

Transparncias

elaboradas por Charles Ornelas Almeida e Nivio Ziviani

Projeto de Algoritmos Cap.7 Algoritmos em Grafos

Aplicaes
Alguns exemplos de problemas prticos que
podem ser resolvidos atravs de uma
modelagem em grafos:
Ajudar mquinas de busca a localizar
informao relevante na Web.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Conceitos Bsicos
Grafo: conjunto de vrtices e arestas.
Vrtice: objeto simples que pode ter nome e
outros atributos.
Aresta: conexo entre dois vrtices.
3

Descobrir os melhores casamentos entre


posies disponveis em empresas e
pessoas que aplicaram para as posies
de interesse.
Descobrir qual o roteiro mais curto para
visitar as principais cidades de uma regio
turstica.

aresta
1

vrtice

Notao: G = (V, A)
G: grafo
V: conjunto de vrtices
A: conjunto de arestas

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Grafos Direcionados

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Grafos No Direcionados

Um grafo direcionado G um par (V, A), onde


V um conjunto finito de vrtices e A uma
relao binria em V .

Um grafo no direcionado G um par (V, A),


onde o conjunto de arestas A constitudo de
pares de vrtices no ordenados.

Uma aresta (u, v) sai do vrtice u e entra


no vrtice v. O vrtice v adjacente ao
vrtice u.

As arestas (u, v) e (v, u) so consideradas


como uma nica aresta. A relao de
adjacncia simtrica.

Podem existir arestas de um vrtice para


ele mesmo, chamadas de self-loops.

Self-loops no so permitidos.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Caminho entre Vrtices

Grau de um Vrtice
Em grafos no direcionados:
O grau de um vrtice o nmero de
arestas que incidem nele.
Um vrice de grau zero dito isolado ou
no conectado.
0

Um caminho de comprimento k de um
vrtice x a um vrtice y em um grafo
G = (V, A) uma seqncia de vrtices
(v0 , v1 , v2 , . . . , vk ) tal que x = v0 e y = vk , e
(vi1 , vi ) A para i = 1, 2, . . . , k.
O comprimento de um caminho o nmero
de arestas nele, isto , o caminho contm os
vrtices v0 , v1 , v2 , . . . , vk e as arestas
(v0 , v1 ), (v1 , v2 ), . . . , (vk1 , vk ).
Se existir um caminho c de x a y ento y
alcanvel a partir de x via c.

Em grafos direcionados
O grau de um vrtice o nmero de
arestas que saem dele (out-degree) mais
o nmero de arestas que chegam nele
(in-degree).
Ex.: O vrtice 2 tem
in-degree 2, out-degree
2 e grau 4.

Ex.: O vrtice 1 tem


grau 2 e o vrtice 3
isolado.

Um caminho simples se todos os vrtices


do caminho so distintos.
Ex.: O caminho (0, 1, 2, 3) simples e tem
comprimento 3. O caminho (1, 3, 0, 3) no
simples.
0

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Ciclos

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Ciclos

Em um grafo direcionado:

Em um grafo no direcionado:

Um caminho (v0 , v1 , . . . , vk ) forma um ciclo


se v0 = vk e o caminho contm pelo
menos uma aresta.

Um caminho (v0 , v1 , . . . , vk ) forma um ciclo


se v0 = vk e o caminho contm pelo
menos trs arestas.

O ciclo simples se os vrtices


v1 , v2 , . . . , vk so distintos.

O ciclo simples se os vrtices


v1 , v2 , . . . , vk so distintos.

O self-loop um ciclo de tamanho 1.

Ex.: O caminho (0, 1, 2, 0) um ciclo.

Dois caminhos (v0 , v1 , . . . , vk ) e


(v00 , v10 , . . . , vk0 ) formam o mesmo ciclo se
existir um inteiro j tal que vi0 = v(i+j) mod k
para i = 0, 1, . . . , k 1.

Ex.: O caminho (0, 1, 2, 3, 0) forma um ciclo. O


caminho(0, 1, 3, 0) forma o mesmo ciclo que os
caminhos (1, 3, 0, 1) e (3, 0, 1, 3).
0

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

10

Componentes Conectados
Um grafo no direcionado conectado se
cada par de vrtices est conectado por um
caminho.
Os componentes conectados so as pores
conectadas de um grafo.
Um grafo no direcionado conectado se ele
tem exatamente um componente conectado.
Ex.: Os componentes so: {0, 1, 2}, {4, 5} e {3}.
0

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

11

Componentes Fortemente Conectados


Um grafo direcionado G = (V, A)
fortemente conectado se cada dois vrtices
quaisquer so alcanveis a partir um do
outro.
Os componentes fortemente conectados
de um grafo direcionado so conjuntos de
vrtices sob a relao so mutuamente
alcanveis.
Um grafo direcionado fortemente
conectado tem apenas um componente
fortemente conectado.
Ex.: {0, 1, 2, 3}, {4} e {5} so os componentes
fortemente conectados, {4, 5} no o pois o
vrtice 5 no alcanvel a partir do vrtice 4.
0

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

12

Grafos Isomorfos

Um grafo G0 = (V 0 , A0 ) um subgrafo de
G = (V, A) se V 0 V e A0 A.

Dado um conjunto V 0 V , o subgrafo


induzido por V 0 o grafo G0 = (V 0 , A0 ), onde
A0 = {(u, v) A|u, v V 0 }.

Ex.: Subgrafo induzido pelo conjunto de vrtices


{1, 2, 4, 5}.

13

Subgrafos

G = (V, A) e G0 = (V 0 , A0 ) so isomorfos se
existir uma bijeo f : V V 0 tal que
(u, v) A se e somente se (f (u), f (v)) A0 .

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

14

Verso Direcionada de um Grafo No


Direcionado

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

15

Verso No Direcionada de um Grafo


Direcionado

A verso direcionada de um grafo no


direcionado G = (V, A) um grafo
direcionado G0 = (V 0 , A0 ) onde (u, v) A0 se e
somente se (u, v) A.

A verso no direcionada de um grafo


direcionado G = (V, A) um grafo no
direcionado G0 = (V 0 , A0 ) onde (u, v) A0 se e
somente se u 6= v e (u, v) A.

Cada aresta no direcionada (u, v) em G


substituda por duas arestas direcionadas
(u, v) e (v, u)

A verso no direcionada contm as arestas


de G sem a direo e sem os self-loops.

Em um grafo direcionado, um vizinho de um


vrtice u qualquer vrtice adjacente a u na
verso no direcionada de G.
0

Em um grafo no direcionado, u e v so
vizinhos se eles so adjacentes.
0

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

16

Outras Classificaes de Grafos

Um grafo completo um grafo no


direcionado no qual todos os pares de
vrtices so adjacentes.

Grafo bipartido: grafo no direcionado


G = (V, A) no qual V pode ser particionado
em dois conjuntos V1 e V2 tal que (u, v) A
implica que u V1 e v V2 ou u V2 e v V1
(todas as arestas ligam os dois conjuntos V1 e
V2 ).

Possui (|V |2 |V |)/2 = |V |(|V | 1)/2 arestas,


pois do total de |V |2 pares possveis de
vrtices devemos subtrair |V | self-loops e
dividir por 2 (cada aresta ligando dois vrtices
contada duas vezes).
O nmero total de grafos diferentes com |V |
vrtices 2|V |(|V |1)/2 (nmero de maneiras
diferentes de escolher um subconjunto a
partir de |V |(|V | 1)/2 possveis arestas).

Hipergrafo: grafo no direcionado em que


cada aresta conecta um nmero arbitrrio de
vrtices.

18

rvores

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2

O Tipo Abstratos de Dados Grafo

rvore livre: grafo no direcionado acclico e


conectado. comum dizer apenas que o
grafo uma rvore omitindo o livre.
Floresta: grafo no direcionado acclico,
podendo ou no ser conectado.
rvore geradora de um grafo conectado
G = (V, A): subgrafo que contm todos os
vrtices de G e forma uma rvore.
Floresta geradora de um grafo G = (V, A):
subgrafo que contm todos os vrtices de G e
forma uma floresta.

(a)

(b)

17

Grafos Completos

Grafo ponderado: possui pesos associados


s arestas.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Importante considerar os algoritmos em


grafos como tipos abstratos de dados.
Conjunto de operaes associado a uma
estrutura de dados.
Independncia de implementao para as
operaes.

19

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2

20

Operadores do TAD Grafo

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2

21

Operao Obter Lista de Adjacentes

1. FGVazio(Grafo): Cria um grafo vazio.

1. ListaAdjVazia(v, Grafo): retorna true se a lista


de adjacentes de v est vazia.

2. InsereAresta(V1,V2,Peso, Grafo): Insere uma


aresta no grafo.

2. PrimeiroListaAdj(v, Grafo): retorna o


endereo do primeiro vrtice na lista de
adjacentes de v.

3. ExisteAresta(V1,V2,Grafo): Verifica se existe


uma determinada aresta.

3. ProxAdj(v, Grafo, u, Peso, Aux, FimListaAdj):


retorna o vrtice u (apontado por Aux) da lista
de adjacentes de v, bem como o peso da
aresta (v, u). Ao retornar, Aux aponta para o
prximo vrtice da lista de adjacentes de v, e
FimListaAdj retorna true se o final da lista de
adjacentes foi encontrado.

4. Obtem a lista de vrtices adjacentes a um


determinado vrtice (tratada a seguir).
5. RetiraAresta(V1,V2,Peso, Grafo): Retira uma
aresta do grafo.
6. LiberaGrafo(Grafo): Liberar o espao
ocupado por um grafo.
7. ImprimeGrafo(Grafo): Imprime um grafo.
8. GrafoTransposto(Grafo,GrafoT): Obtm o
transposto de um grafo direcionado.
9. RetiraMin(A): Obtm a aresta de menor peso
de um grafo com peso nas arestas.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2

22

Implementao da Operao Obter


Lista de Adjacentes
comum encontrar um pseudo comando do
tipo:
for u ListaAdjacentes (v) do { faz algo com u }
O trecho de programa abaixo apresenta um
possvel refinamento do pseudo comando
acima.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1

Matriz de Adjacncia
A matriz de adjacncia de um grafo
G = (V, A) contendo n vrtices uma matriz
n n de bits, onde A[i, j] 1 (ou verdadeiro)
se e somente se existe um arco do vrtice i
para o vrtice j.
Para grafos ponderados A[i, j] contm o
rtulo ou peso associado com a aresta e,
neste caso, a matriz no de bits.

i f not ListaAdjVazia (v , Grafo)


then begin
Aux : = PrimeiroListaAdj (v , Grafo ) ;
FimListaAdj : = false ;
while not FimListaAdj
do ProxAdj(v , Grafo , u, Peso, Aux, FimListaAdj ) ;
end;

Se no existir uma aresta de i para j ento


necessrio utilizar um valor que no possa
ser usado como rtulo ou peso.

23

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1

24

Matriz de Adjacncia - Exemplo

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1

Matriz de Adjacncia - Anlise

Deve ser utilizada para grafos densos, onde


|A| prximo de |V |2 .

O tempo necessrio para acessar um


elemento independente de |V | ou |A|.

0 1 2 3 4 5
0
1
1
1
1 1
2
1 1
3 1
4
5

0 1 2 3 4 5
0
1 1
1 1
1
2 1 1
3
4
5

(a)

(b)

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1

Matriz de Adjacncia - Implementao


A insero de um novo vrtice ou retirada de
um vrtice j existente pode ser realizada
com custo constante.

muito til para algoritmos em que


necessitamos saber com rapidez se existe
uma aresta ligando dois vrtices.
A maior desvantagem que a matriz
necessita (|V |2 ) de espao. Ler ou examinar
a matriz tem complexidade de tempo O(|V |2 ).

26

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1

Matriz de Adjacncia - Implementao


procedure InsereAresta ( var V1, V2: TipoValorVertice ;
var Peso

: TipoPeso;

var Grafo : TipoGrafo ) ;


begin
Grafo.Mat[V1, V2] : = peso;

const MaxNumVertices = 100;

end;

MaxNumArestas = 4500;
type

function ExisteAresta ( Vertice1 , Vertice2 : TipoValorVertice ;

TipoValorVertice = 0..MaxNumVertices;
TipoPeso

= integer ;

TipoGrafo = record

var Grafo : TipoGrafo ) : boolean;


begin
ExisteAresta : = Grafo.Mat[ Vertice1 , Vertice2 ] > 0;

Mat: array [ TipoValorVertice , TipoValorVertice ]

end; { ExisteAresta }

of TipoPeso;
NumVertices: 0 . .MaxNumVertices;

{Operador para obter a l i s t a de adjacentes}

NumArestas : 0 . .MaxNumArestas;

function ListaAdjVazia ( var Vertice : TipoValorVertice ;

end;
Apontador = TipoValorVertice ;

var Grafo : TipoGrafo ) : boolean;


var Aux: Apontador ; ListaVazia : boolean;
begin

procedure FGVazio(var Grafo : TipoGrafo ) ;

ListaVazia : = true ; Aux := 0;

var i , j : integer ;

while (Aux < Grafo.NumVertices) and ListaVazia do

begin
for i := 0 to Grafo.NumVertices do
for j := 0 to Grafo.NumVertices do Grafo.mat[ i , j ] : = 0 ;
end;

25

i f Grafo.Mat[ Vertice , Aux] > 0


then ListaVazia : = false
else Aux : = Aux + 1;
ListaAdjVazia : = ListaVazia = true ;
end; { ListaAdjVazia }

27

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1

28

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1

Matriz de Adjacncia - Implementao

Matriz de Adjacncia - Implementao

{Operador para obter a l i s t a de adjacentes}

procedure RetiraAresta ( var V1, V2: TipoValorVertice ;

function PrimeiroListaAdj ( var Vertice : TipoValorVertice ;

var Peso

var Grafo : TipoGrafo ) : Apontador;

29

: TipoPeso;

var Grafo : TipoGrafo ) ;

var Aux: Apontador ; Listavazia : boolean;

begin

begin

i f Grafo.Mat[V1, V2] = 0

ListaVazia : = true ; Aux := 0;

then writeln ( Aresta nao existe )

while (Aux < Grafo.NumVertices) and ListaVazia do

else begin Peso : = Grafo.Mat[V1, V2] ; Grafo.Mat[V1, V2] : = 0 ;

i f Grafo.Mat[ Vertice , Aux] > 0

end;

then begin PrimeiroListaAdj : = Aux; ListaVazia : = false ;

end; { RetiraAresta }

end
else Aux : = Aux + 1;

procedure LiberaGrafo ( var Grafo : TipoGrafo ) ;

i f Aux = Grafo.NumVertices

begin { Nao faz nada no caso de matrizes de adjacencia }

then writeln ( Erro : Lista adjacencia vazia ( PrimeiroListaAdj ) ) ;

end; { LiberaGrafo }

end; { PrimeiroListaAdj }
procedure ImprimeGrafo ( var Grafo : TipoGrafo ) ;
{Operador para obter a l i s t a de adjacentes}

var i , j : integer ;

procedure ProxAdj ( var Vertice : TipoValorVertice ; var Grafo : TipoGrafo;

begin

var Adj : TipoValorVertice ; var Peso: TipoPeso;

write(

var Prox : Apontador ; var FimListaAdj : boolean) ;

for i := 0 to Grafo.NumVertices1 do write( i : 3 ) ; writeln ;

{ Retorna Adj apontado por Prox}

for i := 0 to Grafo.NumVertices1 do
begin

begin
Adj

write( i : 3 ) ;

:= Prox ; Peso : = Grafo.Mat[ Vertice , Prox ] ; Prox : = Prox + 1;

for j := 0 to Grafo.NumVertices1 do write(Grafo.mat[ i , j ] : 3 ) ;

while ( Prox < Grafo.NumVertices) and

writeln ;

(Grafo.Mat[ Vertice , Prox] = 0 ) do Prox : = Prox + 1;

end;

i f Prox = Grafo.NumVertices then FimListaAdj : = true ;

end; { ImprimeGrafo }

end; { ProxAdj }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2

30

Listas de Adjacncia usando


Apontadores
3

5
0

1
7

2 7

0
1
7

Os vrtices de uma lista de adjacncia so


em geral armazenados em uma ordem
arbitrria.

1 5
1 3

2 7

1 7

Um arranjo Adj de |V | listas, uma para cada


vrtice em V .
Para cada u V , Adj[u] contm todos os
vrtices adjacentes a u em G.

Possui uma complexidade de espao


O(|V | + |A|)
Indicada para grafos esparsos, onde |A|
muito menor do que |V |2 .

1 5
0 5

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2

Listas de adjacncia - Anlise

5
0

);

compacta e usualmente utilizada na maioria


das aplicaes.
A principal desvantagem que ela pode ter
tempo O(|V |) para determinar se existe uma
aresta entre o vrtice i e o vrtice j, pois
podem existir O(|V |) vrtices na lista de
adjacentes do vrtice i.

31

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2

32

Listas de Adjacncia usando


Apontadores - Implementao

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2

33

Listas de Adjacncia usando


Apontadores - Implementao

No uso de apontadores a lista constituda


de clulas, onde cada clula contm um item
da lista e um apontador para a clula
seguinte.

{ Entram aqui os operadores FLVazia, Vazia, Insere, Retira e Imprime do


TAD Lista de Apontadores}
procedure FGVazio(var Grafo : TipoGrafo ) ;
var i : integer ;
begin
for i := 0 to Grafo.NumVertices1 do FLVazia(Grafo. Adj [ i ] ) ;
end; { FGVazio }

const MaxNumVertices = 100;


MaxNumArestas = 4500;

procedure InsereAresta(var V1, V2: TipoValorVertice ; var Peso: TipoPeso;

type

var Grafo : TipoGrafo ) ;

TipoValorVertice = 0..MaxNumVertices;
TipoPeso

= integer ;

TipoItem

= record

var x : TipoItem ;
begin
x . Vertice : = V2; x .Peso : = Peso;

Vertice : TipoValorVertice ;
Peso

Insere (x , Grafo. Adj [V1] ) ;

: TipoPeso;

end; { InsereAresta }

end;
Apontador

= ^Celula ;

Celula

= record

function ExisteAresta ( Vertice1 , Vertice2 : TipoValorVertice ;


var Grafo : TipoGrafo ) : boolean;

Item : TipoItem ;
var Aux: Apontador;

Prox : Apontador;

EncontrouAresta : boolean;

end;
TipoLista

begin

= record

Aux : = Grafo. Adj [ Vertice1 ] . Primeiro^.Prox;

Primeiro : Apontador;

EncontrouAresta : = false ;

Ultimo : Apontador;

while (Aux <> n i l ) and ( EncontrouAresta = false ) do

end;

begin

TipoGrafo = record

i f Vertice2 = Aux^.Item . Vertice then EncontrouAresta : = true ;

Adj : array [ TipoValorVertice ] of TipoLista ;

Aux : = Aux^.Prox;

NumVertices : TipoValorVertice ;

end;

NumArestas: 0 . .MaxNumArestas;

ExisteAresta : = EncontrouAresta;

end;

end; { ExisteAresta }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2

34

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2

Listas de Adjacncia usando


Apontadores - Implementao

Listas de Adjacncia usando


Apontadores - Implementao

{Operador para obter a l i s t a de adjacentes}

procedure RetiraAresta ( var V1, V2: TipoValorVertice ;

function ListaAdjVazia ( var Vertice : TipoValorVertice ;

var Peso

var Grafo : TipoGrafo ) : boolean;


begin

: TipoPeso;

var Grafo : TipoGrafo ) ;


var AuxAnterior , Aux: Apontador;

ListaAdjVazia : = Grafo. Adj [ Vertice ] . Primeiro =


Grafo. Adj [ Vertice ] . Ultimo ;
end; { ListaAdjVazia }

EncontrouAresta : boolean;
x : TipoItem ;
begin
AuxAnterior : = Grafo. Adj [V1] . Primeiro ;

{Operador para obter a l i s t a de adjacentes}


function PrimeiroListaAdj ( var Vertice : TipoValorVertice ;
var Grafo : TipoGrafo ) : Apontador;
begin
PrimeiroListaAdj : = Grafo. Adj [ Vertice ] . Primeiro^.Prox;
end; { PrimeiroListaAdj }

Aux : = Grafo. Adj [V1] . Primeiro^.Prox;


EncontrouAresta : = false ;
while (Aux <> n i l ) and ( EncontrouAresta = false ) do
begin
i f V2 = Aux^.Item . Vertice
then begin
Retira (AuxAnterior , Grafo. Adj [V1] , x ) ;

{Operador para obter a l i s t a de adjacentes}


procedure ProxAdj ( var Vertice
var Grafo

: TipoValorVertice ;
: TipoValorVertice ;

var Peso

: TipoPeso;

var Prox

: Apontador;

var FimListaAdj : boolean) ;


{ Retorna Adj e Peso do Item apontado por Prox}
begin
Adj

:= Prox^.Item . Vertice ;
:= Prox^.Item .Peso;

Prox

:= Prox^.Prox;

i f Prox = n i l then FimListaAdj : = true ;


end; { ProxAdj }

EncontrouAresta : = true ;

: TipoGrafo;

var Adj

Peso

Grafo.NumArestas : = Grafo.NumArestas 1;
end;
AuxAnterior : = Aux; Aux : = Aux^.Prox;
end;
end; { RetiraAresta }

35

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2

36

Listas de Adjacncia usando


Apontadores - Implementao

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.3

37

Listas de Adjacncia usando Arranjos


3
5

procedure LiberaGrafo ( var Grafo : TipoGrafo ) ;

var AuxAnterior , Aux: Apontador;

begin

V
7

for i := 0 to Grafo.NumVertices1 do

begin

Cab

Prox

Peso

4
6
2
3
1
1
2

4
5
0
0
0
6
0

5
3
7

Cab

Prox

Peso

4
6
7
3
1
0
2
1

4
5
7
0
0
6
0
0

5
5
7
7

0
1
2
3
4
5
6

Aux : = Grafo. Adj [ i ] . Primeiro^.Prox;


dispose(Grafo. Adj [ i ] . Primeiro ) ; { Libera celula cabeca}
while Aux <> n i l do
begin AuxAnterior : = Aux; Aux : = Aux^.Prox ; dispose(AuxAnterior ) ;
end;

5
0

end;

end; { LiberaGrafo }

0
1
2
3
4
5
6
7

procedure ImprimeGrafo ( var Grafo : TipoGrafo ) ;

var i : integer ; Aux: Apontador;


begin
for i := 0 to Grafo.NumVertices1 do

Cab: endereos do ltimo item da lista de


adjacentes de cada vrtice (nas |V | primeiras
posies) e os vrtices propriamente ditos
(nas |A| ltimas posies)

begin
write( Vertice , i :2 , : ) ;
i f not Vazia(Grafo. Adj [ i ] )
then begin
Aux : = Grafo. Adj [ i ] . Primeiro^.Prox;
while Aux <> n i l do

Prox: endereo do prximo item da lista de


adjacentes.

begin
write(Aux^.Item . Vertice :3 , ( ,Aux^.Item .Peso, ) ) ;
Aux : = Aux^.Prox;

Peso: valor do peso de cada aresta do grafo


(nas ltimas |A| posies).

end;
end;
writeln ;
end;
end; { ImprimeGrafo }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.3

38

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.3

Listas de Adjacncia usando Arranjos


- Implementao

Listas de Adjacncia usando Arranjos


- Implementao

const MaxNumVertices = 100;

procedure InsereAresta ( var V1, V2: TipoValorVertice ;

MaxNumArestas = 4500;

var Peso

MaxTam

var Grafo : TipoGrafo ) ;

= MaxNumVertices+2MaxNumArestas;

: TipoPeso;

var Pos: integer ;

type
TipoValorVertice = 0..MaxNumVertices;

begin
Pos:= Grafo. ProxDisponivel ;

TipoPeso

= integer ;

TipoTam

= 0..MaxTam;

i f Grafo. ProxDisponivel = MaxTam


then writeln ( nao ha espaco disponivel para a aresta )

TipoGrafo = record
Cab

: array [TipoTam] of TipoTam;

Prox

: array [TipoTam] of TipoTam;

Peso

: array [TipoTam] of TipoTam;

else begin
Grafo. ProxDisponivel : = Grafo. ProxDisponivel + 1;
Grafo.Prox[Grafo.Cab[V1] ] : = Pos;
Grafo.Cab[Pos] : = V2;

ProxDisponivel : TipoTam;
NumVertices

: 0 . .MaxNumVertices;

NumArestas

: 0 . .MaxNumArestas;

end;
Apontador = TipoTam;

Grafo.Prox[Pos] : = 0 ;

Grafo.Cab[V1] : = Pos;
Grafo.Peso[Pos] : = Peso;

end;
end; { InsereAresta}
function ExisteAresta ( Vertice1 , Vertice2 : TipoValorVertice ;
var Grafo : TipoGrafo ) : boolean;

procedure FGVazio(var Grafo : TipoGrafo ) ;


var i : integer ;
begin
for i := 0 to Grafo.NumVertices do
begin

begin
Aux : = Grafo.Prox[ Vertice1 ] ; EncontrouAresta : = false ;
while (Aux < > 0) and ( EncontrouAresta = false ) do
begin

Grafo.Prox[ i ] : = 0 ; Grafo.Cab[ i ] : = i ;

i f Vertice2 = Grafo.Cab[Aux] then EncontrouAresta : = true ;

Grafo. ProxDisponivel : = Grafo.NumVertices;

Aux : = Grafo.Prox[Aux] ;

end;
end;

var Aux: Apontador ; EncontrouAresta : boolean;

end;
ExisteAresta : = EncontrouAresta;
end; { ExisteAresta }

39

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.3

40

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.3

Listas de Adjacncia usando Arranjos


- Implementao

Listas de Adjacncia usando Arranjos


- Implementao

{Operador para obter a l i s t a de adjacentes}

procedure RetiraAresta ( var V1, V2: TipoValorVertice ;

41

var Peso: TipoPeso ; var Grafo : TipoGrafo ) ;

function ListaAdjVazia (var Vertice : TipoValorVertice ;

var Aux, AuxAnterior : Apontador ; EncontrouAresta : boolean;

var Grafo : TipoGrafo ) : boolean;

begin

begin

AuxAnterior : = V1; Aux : = Grafo.Prox[V1] ;

ListaAdjVazia : = Grafo.Prox[ Vertice ] = 0;

EncontrouAresta : = false ;

end; { ListaAdjVazia }

while (Aux < > 0) and ( EncontrouAresta = false ) do


begin

{Operador para obter a l i s t a de adjacentes}

i f V2 = Grafo.Cab[Aux]

function PrimeiroListaAdj (var Vertice : TipoValorVertice ;

then EncontrouAresta : = true

var Grafo : TipoGrafo ) : Apontador;

else begin AuxAnterior : = Aux; Aux : = Grafo.Prox[Aux] ; end;

begin

end;

PrimeiroListaAdj : = Grafo.Prox[ Vertice ] ;

i f EncontrouAresta

end; { PrimeiroListaAdj }

then Grafo.Cab[Aux] : = MaxNumVertices+2MaxNumArestas


{Apenas marca como retirado }

{Operador para obter a l i s t a de adjacentes}


procedure ProxAdj ( var Vertice
var Grafo

else writeln ( Aresta nao existe ) ;

: TipoValorVertice ;

end; { RetiraAresta }

: TipoGrafo;

var Adj

: TipoValorVertice ;

var Peso

: TipoPeso;

var Prox

: Apontador;

procedure LiberaGrafo ( var Grafo : TipoGrafo ) ;


begin {Nada no caso de posicoes contiguas} end; { LiberaGrafo }

var FimListaAdj : boolean) ;

procedure ImprimeGrafo ( var Grafo : TipoGrafo ) ;

{ Retorna Adj apontado por Prox}

var i : integer ;

begin

begin

Adj

:= Grafo.Cab[Prox ] ; Peso : = Grafo.Peso[Prox ] ;

writeln (

Prox : = Grafo.Prox[Prox ] ;
i f Prox = 0 then FimListaAdj : = true ;

writeln ( i :2 ,Grafo.Cab[ i ]:4 ,Grafo.Prox[ i ] : 4 , Grafo.Peso[ i ] : 4 ) ;

end; { ProxAdj }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

Busca em Profundidade

Cab Prox Peso ) ;

for i := 0 to Grafo.NumVertices+2Grafo.NumArestas1 do
end; { ImprimeGrafo }

42

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

Busca em Profundidade

A busca em profundidade, do ingls


depth-first search), um algoritmo para
caminhar no grafo.

Para acompanhar o progresso do algoritmo


cada vrtice colorido de branco, cinza ou
preto.

A estratgia buscar o mais profundo no


grafo sempre que possvel.

Todos os vrtices so inicializados branco.

As arestas so exploradas a partir do vrtice


v mais recentemente descoberto que ainda
possui arestas no exploradas saindo dele.
Quando todas as arestas adjacentes a v
tiverem sido exploradas a busca anda para
trs para explorar vrtices que saem do
vrtice do qual v foi descoberto.
O algoritmo a base para muitos outros
algoritmos importantes, tais como verificao
de grafos acclicos, ordenao topolgica e
componentes fortemente conectados.

Quando um vrtice descoberto pela


primeira vez ele torna-se cinza, e tornado
preto quando sua lista de adjacentes tenha
sido completamente examinada.
d[v]: tempo de descoberta
t[v]: tempo de trmino do exame da lista de
adjacentes de v.
Estes registros so inteiros entre 1 e 2|V | pois
existe um evento de descoberta e um evento
de trmino para cada um dos |V | vrtices.

43

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

44

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

Busca em Profundidade Implementao

Busca em Profundidade Implementao

procedure BuscaEmProfundidade ( var Grafo : TipoGrafo ) ;

procedure VisitaDfs (u: TipoValorVertice ) ;

var Tempo

var FimListaAdj : boolean;

: TipoValorTempo;

: TipoValorVertice ;

Peso

: TipoPeso;

d, t

: array [ TipoValorVertice ] of TipoValorTempo;

Aux

: Apontador;

Cor

: array [ TipoValorVertice ] of TipoCor;

: TipoValorVertice ;

Antecessor : array [ TipoValorVertice ] of integer ;

begin

45

Cor[u] : = cinza ; Tempo : = Tempo + 1; d[u] : = Tempo;


{Entra aqui o procedimento VisitaDFS (a seguir)}

writeln ( Visita ,u:2 , Tempo descoberta : ,d[u]:2 , cinza ) ; readln;

begin

then begin

i f not ListaAdjVazia (u, Grafo)


Tempo := 0;

Aux : = PrimeiroListaAdj (u, Grafo ) ; FimListaAdj : = false ;

for x := 0 to Grafo.NumVertices1 do

while not FimListaAdj do

Antecessor[ x] := 1; end;

begin Cor[ x ] : = branco ;

begin

for x := 0 to Grafo.NumVertices1 do

ProxAdj(u, Grafo , v , Peso, Aux, FimListaAdj ) ;

i f Cor[ x ] = branco then VisitaDfs (x ) ;

i f Cor[ v ] = branco

end; { BuscaEmProfundidade }

then begin Antecessor[ v ] : = u ; VisitaDfs (v ) ; end;


end;
end;
Cor[u] : = preto ; Tempo : = Tempo + 1;

t [u] : = Tempo;

writeln ( Visita ,u:2 , Tempo termino : , t [u]:2 , preto ) ; readln;


end; { VisitaDfs }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

46

Busca em Profundidade - Exemplo


b( / )

b( / )

c(1/ )

b( / )

b( / )
b( / ) 2

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

Busca em Profundidade - Exemplo


c(1/ )
0

p(2/5)

p(1/6)

p(2/5)

b( / )
b( / ) 2

(a)

47

b( / )

b( / )

p(3/4) 2

(b)

p(3/4) 2

(g)

(f)

c(1/ )

c(2/ )

c(1/ )

c(2/ )

p(1/6)

p(2/5)

p(1/6)

p(2/5)

b( / )
b( / ) 2

b( / )
c(3/ ) 2

(c)

(d)
c(1/ )

c(2/ )

1
b( / )
p(3/4) 2

(e)

c(7/ )
p(3/4) 2

(h)

p(7/8)
p(3/4) 2

(i)

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

48

Busca em Profundidade - Anlise

Existem:
1. Arestas de rvore: so arestas de uma
rvore de busca em profundidade. A aresta
(u, v) uma aresta de rvore se v foi
descoberto pela primeira vez ao percorrer a
aresta (u, v).

O procedimento VisitaDfs chamado


exatamente uma vez para cada vrtice u V ,
desde que VisitaDfs chamado apenas para
vrtices brancos e a primeira ao pintar o
vrtice de cinza.

2. Arestas de retorno: conectam um vrtice u


com um antecessor v em uma rvore de
busca em profundidade (inclui self-loops).

Durante a execuo de VisitaDfs(u) o anel


principal executado |Adj[u]| vezes.

3. Arestas de avano: no pertencem rvore


de busca em profundidade mas conectam um
vrtice a um descendente que pertence
rvore de busca em profundidade.

Desde que uV |Adj[u]| = O(|A|), o tempo


total de execuo de VisitaDfs O(|A|).
P

Logo, a complexidade total da


BuscaEmProfundidade O(|V | + |A|).

Na busca em profundidade cada aresta pode


ser classificada pela cor do vrtice que
alcanado pela primeira vez:
Branco indica uma aresta de rvore.
Cinza indica uma aresta de retorno.
Preto indica uma aresta de avano quando
u descoberto antes de v ou uma aresta
de cruzamento caso contrrio.
2

2/9
arv

arv

ret

arv

1/10
arv

cruz

avan
3
4/5

cruz

4
7/8

cruz

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3.2

Teste para Verificar se Grafo Acclico

Classificao de arestas pode ser til para


derivar outros algoritmos.

3/6

4. Arestas de cruzamento: podem conectar


vrtices na mesma rvore de busca em
profundidade, ou em duas rvores diferentes.

50

Classificao de Arestas

5
11/12

49

Classificao de Arestas

Os dois anis da BuscaEmProfundidade tm


custo O(|V |) cada um, a menos da chamada
do procedimento VisitaDfs(u) no segundo
anel.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3.1

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3.1

A busca em profundidade pode ser usada


para verificar se um grafo acclico ou
contm um ou mais ciclos.
Se uma aresta de retorno encontrada
durante a busca em profundidade em G,
ento o grafo tem ciclo.
Um grafo direcionado G acclico se e
somente se a busca em profundidade em G
no apresentar arestas de retorno.

51

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

52

Busca em Largura

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

53

Busca em Largura

Expande a fronteira entre vrtices


descobertos e no descobertos
uniformemente atravs da largura da
fronteira.

Cada vrtice colorido de branco, cinza ou


preto.
Todos os vrtices so inicializados branco.
Quando um vrtice descoberto pela
primeira vez ele torna-se cinza.

O algoritmo descobre todos os vrtices a uma


distncia k do vrtice origem antes de
descobrir qualquer vrtice a uma distncia
k + 1.

Vrtices cinza e preto j foram descobertos,


mas so distinguidos para assegurar que a
busca ocorra em largura.

O grafo G(V, A) pode ser direcionado ou no


direcionado.

Se (u, v) A e o vrtice u preto, ento o


vrtice v tem que ser cinza ou preto.
Vrtices cinza podem ter alguns vrtices
adjacentes brancos, e eles representam a
fronteira entre vrtices descobertos e no
descobertos.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

54

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

Busca em Largura - Implementao

Busca em Largura - Implementao

{ Entram aqui os operadores FFVazia, Vazia, Enfileira e Desenfileira do}

procedure VisitaBfs (u: TipoValorVertice ) ;

{ TAD Filas com arranjos ou apontadores, dependendo da implementao}

var v : TipoValorVertice ; Aux: Apontador ; FimListaAdj : boolean;

{ da busca em largura usar arranjos ou apontadores, respectivamente}


procedure BuscaEmLargura ( var Grafo : TipoGrafo ) ;

Peso: TipoPeso ; Item : TipoItem ; Fila : TipoFila ;


begin

: TipoValorVertice ;

Cor[u] : = cinza ;

Dist

: array [ TipoValorVertice ] of integer ;

FFVazia ( Fila ) ;

Cor

: array [ TipoValorVertice ] of TipoCor;

var x

Antecessor : array [ TipoValorVertice ] of integer ;

Dist [u] : = 0 ;
Item . Vertice : = u;

Enfileira ( Item , Fila ) ;


write( Visita origem ,u:2 , cor : cinza F: ) ;
ImprimeFila ( Fila ) ; readln;

{Entra aqui o procedimento VisitaBfs (a seguir)}

while not FilaVazia ( Fila ) do


begin
Desenfileira ( Fila , Item ) ;

begin
for x := 0 to Grafo.NumVertices1 do

then begin

begin
Cor[ x ] : = branco ;

Dist [ x ] : = i n f i n i t o ;

u : = Item . vertice ;

i f not ListaAdjVazia (u, Grafo)


Aux : = PrimeiroListaAdj (u,Grafo ) ; FimListaAdj : = false ;

Antecessor[ x] := 1;

while FimListaAdj = false do

end;

begin

for x := 0 to Grafo.NumVertices1 do

ProxAdj(u, v , Peso, Aux, FimListaAdj ) ;

i f Cor[ x ] = branco then VisitaBfs (x ) ;

i f Cor[ v ] = branco

end; { BuscaEmLargura }

then begin
Cor[ v ] : = cinza ;

Dist [ v ] : = Dist [u] + 1;

Antecessor[ v ] : = u;
Item . Vertice : = v ;

Item .Peso : = Peso;

Enfileira ( Item , Fila ) ;


end;
end;
end;
Cor[u] : = preto ;
write( Visita , u:2 , Dist , Dist [u]:2 , cor : preto F: ) ;
ImprimeFila ( Fila ) ; readln;
end;
end; { VisitaBfs }

55

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

56

Busca em Largura - Exemplo

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

Busca em Largura - Exemplo

(b)

(a)

57

(e)

(f)

c(0)

b( )

b( )

p(0)

c(1)

b( )

p(0)

p(1)

b( )

p(0)

p(1)

c(0)

b( )

b( )

b( )

c(1)

b( )

b( )

p(1)

p(2)

b( )

p(1)

p(2)

b( )

F 0
0

F 1 3
1 1

(c)

(d)

F 4
0

(h)

(g)

p(0)

p(1)

b( )

p(0)

p(1)

b( )

p(0)

p(1)

p(0)

p(0)

p(1)

p(0)

c(1)

c(2)

b( )

p(1)

c(2)

b( )

p(1)

p(2)

c(1)

p(1)

p(2)

p(1)

F 3 2
1 2

F 2
2

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

Busca em Largura - Anlise (para


listas de adjacncia)
O custo de inicializao do primeiro anel em
BuscaEmLargura O(|V |) cada um.
O custo do segundo anel tambm O(|V |).
VisitaBfs: enfileirar e desenfileirar tm custo
O(1), logo, o custo total com a fila O(|V |).
Cada lista de adjacentes percorrida no
mximo uma vez, quando o vrtice
desenfileirado.
Desde que a soma de todas as listas de
adjacentes O(|A|), o tempo total gasto com
as listas de adjacentes O(|A|).
Complexidade total: O(|V | + |A|).

F 5
1

58

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

Caminhos Mais Curtos


A busca em largura obtm o caminho mais
curto de u at v.
O procedimento VisitaBfs contri uma rvore
de busca em largura que armazenada na
varivel Antecessor.
O programa abaixo imprime os vrtices do
caminho mais curto entre o vrtice origem e
outro vrtice qualquer do grafo, a partir do
vetor Antecessor obtido na busca em largura.
procedure ImprimeCaminho (Origem, v : TipovalorVertice ) ;
begin
i f Origem = v
then write(Origem:3)
else i f Antecessor[ v] = 1
then write( Nao existe caminho de ,Origem:3 , ate ,v:3)
else begin
Imprimecaminho(Origem, Antecessor[ v ] ) ;
write(v: 3 ) ;
end;
end; { ImprimeCaminho }

59

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.5

60

Ordenao Topolgica

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.5

Ordenao Topolgica

Ordenao linear de todos os vrtices, tal que


se G contm uma aresta (u, v) ento u
aparece antes de v.

Os grafos direcionados acclicos so usados


para indicar precedncias entre eventos.
Uma aresta direcionada (u, v) indica que a
atividade u tem que ser realizada antes da
atividade v.

Pode ser vista como uma ordenao de seus


vrtices ao longo de uma linha horizontal de
tal forma que todas as arestas esto
direcionadas da esquerda para a direita.
Pode ser feita usando a busca em
profundidade.

Ordenao Topolgica
Algoritmo para ordenar topologicamente um
grafo direcionado acclico G = (V, A):
1. Chama BuscaEmProfundidade(G) para
obter os tempos de trmino t[u] para cada
vrtice u.
2. Ao trmino de cada vrtice insira-o na
frente de uma lista linear encadeada.
3. Retorna a lista encadeada de vrtices.
A Custo O(|V | + |A|), uma vez que a busca
em profundidade tem complexidade de tempo
O(|V | + |A|) e o custo para inserir cada um
dos |V | vrtices na frente da lista linear
encadeada custa O(1).

1/18

16/17

4/5 3

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.5

61

62

19/20
9

2/15

7/12

3/14

6/13

8/11

9/10

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.5

Ordenao Topolgica Implementao


Basta inserir uma chamada para o
procedimento InsLista no procedimento
BuscaDfs, logo aps o momento em que o
tempo de trmino t[u] obtido e o vrtice
pintado de preto.
Ao final, basta retornar a lista obtida (ou
imprim-la.
procedure InsLista ( var Item : TipoItem ; var Lista : TipoLista ) ;
{ Insere antes do primeiro item da l i s t a }
var Aux: Apontador;
begin
Aux : = Lista . Primeiro^.Prox;
new( Lista . Primeiro^.Prox ) ;
Lista . Primeiro^.Prox^.Item : = Item ;
Lista . Primeiro^.Prox^.Prox : = Aux;
end; { Insere }

63

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

64

Componentes Fortemente Conectados

Usa o transposto de G, definido


GT = (V, AT ), onde AT = {(u, v) : (v, u) A},
isto , AT consiste das arestas de G com
suas direes invertidas.

Podemos particionar V em conjuntos Vi ,


1 i r, tal que vrtices u e v so
equivalentes se e somente se existe um
caminho de u a v e um caminho de v a u.
1

0,1,2

(a)

(b)

65

Componentes Fortemente Conectados


- Algoritmo

Um componente fortemente conectado de


G = (V, A) um conjunto maximal de vrtices
C V tal que para todo par de vrtices u e v
em C, u e v so mutuamente alcanveis

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

G e GT possuem os mesmos componentes


fortemente conectados, isto , u e v so
mutuamente alcanveis a partir de cada um
em G se e somente se u e v so mutuamente
alcanveis a partir de cada um em GT .

(c)

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

66

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

67

Componentes Fortemente Conectados


- Algoritmo

Componentes Fortemente Conectados


- Exemplo

1. Chama BuscaEmProfundidade(G) para obter


os tempos de trmino t[u] para cada vrtice u.

A parte (b) apresenta o resultado da busca


em profundidade sobre o grafo transposto
obtido, mostrando os tempos de trmino e a
classificao das arestas.

2. Obtem GT .
3. Chama BuscaEmProfundidade(GT ),
realizando a busca a partir do vrtice de
maior t[u] obtido na linha 1. Inicie uma nova
busca em profundidade a partir do vrtice de
maior t[u] dentre os vrtices restantes se
houver.
4. Retorne os vrtices de cada rvore da
floresta obtida como um componente
fortemente conectado separado.

A busca em profundidade em GT resulta na


floresta de rvores mostrada na parte (c).
1/8

2/7

1/6

0
cruz

3
4/5

2
3/6

(a)

ret
arv

cruz

arv cruz

1
arv

3
2
cruz
7/8
2/5

(b)

3/4

ret

2
arv
1

(c)

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

68

Componentes Fortemente Conectados


- Implementao

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

69

Componentes Fortemente Conectados


- Implementao

procedure GrafoTransposto ( var Grafo : TipoGrafo ; var GrafoT : TipoGrafo ) ;


var v , u : TipoValorVertice ;
Peso: TipoPeso;
Aux : Apontador;
begin

O Programa BuscaEmProfundidadeCfc utiliza


a funo MaxTT para obter o vrtice de maior
t[u] dentre os vrtices restantes u ainda no
visitados por VisitaDFS.

FGVazio(GrafoT) ;
GrafoT.NumVertices : = Grafo.NumVertices;
GrafoT.NumArestas

type

:= Grafo.NumArestas;

TipoTempoTermino = record

for v := 0 to Grafo.NumVertices1 do

t : array [ TipoValorVertice ] of TipoValorTempo;

i f not ListaAdjVazia (v , Grafo)

Restantes : array [ TipoValorVertice ] of boolean;

then begin

NumRestantes: TipoValorVertice ;

Aux : = PrimeiroListaAdj (v , Grafo ) ;

end;

FimListaAdj : = false ;

Function MaxTT ( var TT: TipoTempoTermino) : TipoValorVertice ;

while not FimListaAdj do

var i , Temp: integer ;

begin

begin

ProxAdj(v , Grafo , u, Peso, Aux, FimListaAdj ) ;

i :=0;

InsereAresta(u, v , Peso, GrafoT) ;

while not TT.Restantes[ i ] do i : = i + 1;

end;

Temp : = TT. t [ i ] ; MaxTT : = i ;

end;

for i := 0 to Grafo.NumVertices1 do

end; { GrafoTransposto }

i f TT.Restantes[ i ]
then i f Temp < TT. t [ i ]
then begin Temp : = TT. t [ i ] ; MaxTT : = i ; end;
end; { MaxTT }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

70

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

Componentes Fortemente Conectados


- Implementao

Componentes Fortemente Conectados


- Implementao

procedure BuscaEmProfundidadeCfc ( var Grafo : TipoGrafo;

procedure VisitaDfs (u: TipoValorVertice ) ;

var TT: TipoTempoTermino) ;


var

var FimListaAdj : boolean;


Peso

: TipoPeso;

Tempo

: TipoValorTempo;

Aux

: Apontador;

x , VRaiz

: TipoValorVertice ;

: TipoValorVertice ;

d, t

: array [ TipoValorVertice ] of TipoValorTempo;

Cor

: array [ TipoValorVertice ] of TipoCor;

Antecessor : array [ TipoValorVertice ] of integer ;


{Entra aqui o procedimento VisitaDFS (a seguir)}
begin

Cor[u] : = cinza ; Tempo : = Tempo + 1; d[u] : = Tempo;


TT.Restantes[u] : = false ; TT.NumRestantes : = TT.NumRestantes1;
writeln ( Visita ,u:2 , Tempo descoberta : ,d[u]:2 , cinza ) ; readln;
i f not ListaAdjVazia (u, Grafo)

Tempo := 0;

then begin

for x := 0 to Grafo.NumVertices1 do
begin Cor[ x ] : = branco ;

begin

Antecessor[ x] := 1; end;

TT.NumRestantes : = Grafo.NumVertices;
for x := 0 to Grafo.NumVertices1 do
TT.Restantes[ x ] : = true ;
while TT.NumRestantes > 0 do
begin

Aux : = PrimeiroListaAdj (u, Grafo ) ;


FimListaAdj : = false ;
while not FimListaAdj do
begin
ProxAdj(u, Grafo , v , Peso, Aux, FimListaAdj ) ;
i f Cor[ v ] = branco
then begin

VRaiz : = MaxTT (TT) ;

Antecessor[ v ] : = u;

writeln ( Raiz da proxima arvore : ,VRaiz: 2 ) ;

VisitaDfs (v ) ;

VisitaDfs (VRaiz) ;

end;

end;
end; { BuscaEmProfundidadeCfc }

end;
end;
Cor[u] : = preto ; Tempo : = Tempo + 1;

t [u] : = Tempo;

writeln ( Visita ,u:2 , Tempo termino : , t [u]:2 , preto ) ; readln;


end; { VisitaDfs }

71

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

72

Componentes Fortemente Conectados


- Anlise

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7

73

rvore Geradora Mnima - Aplicao


Projeto de redes de comunicaes
conectando n localidades.

Utiliza o algoritmo para busca em


profundidade duas vezes, uma em G e outra
em GT . Logo, a complexidade total
O(|V | + |A|).

Arranjo de n 1 conexes, conectando duas


localidades cada.
Objetivo: dentre as possibilidades de
conexes, achar a que usa menor quantidade
de cabos.
Modelagem:
G = (V, A): grafo conectado, no
direcionado.
V : conjunto de cidades.
A: conjunto de possveis conexes
p(u, v): peso da aresta (u, v) A, custo
total de cabo para conectar u a v.
Soluo: encontrar um subconjunto T A,
acclico, que conecta todos os vrtices de G e
P
cujo peso total p(T ) = (u,v)T p(u, v)
minimizado.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7

74

rvore Geradora Mnima (AGM)

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.1

AGM - Algoritmo Genrico

Como G0 = (V, T ) acclico e conecta todos


os vrtices, T forma uma rvore chamada
rvore geradora de G.
O problema de obter a rvore T conhecido
como rvore geradora mnima (AGM).
Ex.: rvore geradora mnima T cujo peso total
12. T no nica, pode-se substituir a aresta
(3, 5) pela aresta (2, 5) obtendo outra rvore
geradora de custo 12.

Uma estratgia gulosa permite obter a AGM


adicionando uma aresta de cada vez.
Invariante: Antes de cada iterao, S um
subconjunto de uma rvore geradora mnima.
A cada passo adicionamos a S uma aresta
(u, v) que no viola o invariante. (u, v)
chamada de uma aresta segura.
procedure GenericoAGM;
1 S := ;
2 while S no constitui uma rvore geradora mnima do

6
1

5
3

2
5
4

(a)

2
4

Encontre uma aresta (u, v) que segura para S ;

S := S + {(u, v)}

5 return S ;

4
4

(b)

Dentro do while, S tem que ser um


subconjunto prprio da AGM T , e assim tem
que existir uma aresta (u, v) T tal que
(u, v) 6 S e (u, v) seguro para S.

75

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.1

76

AGM - Definio de Corte

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.1

77

AGM - Teorema para reconhecer


arestas seguras

Um corte (V 0 , V V 0 ) de um grafo no
direcionado G = (V, A) uma partio de V .

Seja G = (V, A) um grafo conectado, no


direcionado, com pesos p sobre as arestas V .

Uma aresta (u, v) A cruza o corte


(V 0 , V V 0 ) se um de seus vrtices pertence
a V 0 e o outro vrtice pertence a V V 0 .

seja S um subconjunto de V que est includo


em alguma AGM para G.

Um corte respeita um conjunto S de arestas


se no existirem arestas em S que o cruzem.

Seja (V 0 , V V 0 ) um corte qualquer que


respeita S.

Uma aresta cruzando o corte que tenha custo


mnimo sobre todas as arestas cruzando o
corte uma aresta leve.

Seja (u, v) uma aresta leve cruzando


(V 0 , V V 0 ).
Satisfeitas essas condies, a aresta (u, v)
uma aresta segura para S.

p
0

p
V

V V

5
2

p
3

V V

2
4
b

6 4
5
3

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

AGM - Algoritmo de Prim


O algoritmo de Prim para obter uma AGM
pode ser derivado do algoritmo genrico.

78

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

Algoritmo de Prim - Exemplo


(a)

A cada passo, uma aresta leve adicionada


rvore S, conectando S a um vrtice de
GS = (V, S).
De acordo com o teorema anterior, quando o
algoritmo termina, as arestas em S formam
uma rvore geradora mnima.

(b)
0

O subconjunto S forma uma nica rvore, e a


aresta segura adicionada a S sempre uma
aresta de peso mnimo conectando a rvore a
um vrtice que no esteja na rvore.
A rvore comea por um vrtice qualquer (no
caso 0) e cresce at que gere todos os
vrtices em V .

79

0
0

5
1

2
4

(c)

2
1

(d)

0
0

0
2

2
1

2
1

3
2
1

2
1
6

(e)

(f)

2
1

2
1

2
1
4

2
1
5

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

80

Algoritmo de Prim - Implementao

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

Algoritmo de Prim - Implementao

{ Entram aqui os operadores de uma das implementaes para grafos}

function RetiraMin ( var A: Vetor ) : Item ;

{ bem como o operador Constroi do TAD HEAP }

begin

procedure AgmPrim ( var Grafo : TipoGrafo ; var Raiz : TipoValorVertice ) ;

if n < 1

var Antecessor : array [ TipoValorVertice ] of integer ;

then writeln ( Erro : heap vazio )

81

: array [ TipoValorVertice ] of TipoPeso;

else begin

Itensheap : array [ TipoValorVertice ] of boolean;

RetiraMin : = A[ 1 ] ;

Pos

: array [ TipoValorVertice ] of TipoValorVertice ;

A[ 1 ] : = A[n ] ;

: Vetor ;

n : = n 1;

u, v

: TipovalorVertice ;

Pos[A[n ] . chave] : = 1 ;

Refaz ( 1 , n, A) ;
end;

procedure Refaz (Esq, Dir : Indice ; var A : Vetor ) ;

end; { Retira }

label 999;
var i : Indice ;

j : integer ;

x : Item ;

procedure DiminuiChave ( i : Indice ; ChaveNova: TipoPeso ; var A: Vetor ) ;

begin

var x : Item ;

i : = Esq;

j := 2 i ;

x : = A[ i ] ;

begin

while j <= Dir do

i f ChaveNova > p[A[ i ] .Chave]

begin

then writeln ( Erro : ChaveNova maior que a chave atual )

i f j < Dir

else begin

then i f p[A[ j ] .Chave] > p[A[ j + 1].Chave] then j : = j + 1;

p[A[ i ] .Chave] : = ChaveNova;

i f p[ x .Chave] <= p[A[ j ] .Chave] then goto 999;

while ( i >1) and (p[A[ i div 2 ] .Chave] > p[A[ i ] .Chave] )

A[ i ] : = A[ j ] ;
i := j ;

Pos[A[ j ] .Chave] : = i ;

do begin

j := 2 i ;

x : = A[ i div 2 ] ;

end;

A[ i div 2 ] : = A[ i ] ;

999 : A[ i ] : = x ; Pos[ x .Chave] : = i ;

Pos[A[ i ] .Chave] : = i div 2;

A[ i ] : = x ; Pos[ x .Chave] : = i ;

end; { Refaz }

i : = i div 2;
end;
end;
end; { DiminuiChave }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

82

Algoritmo de Prim - Implementao


begin { AgmPrim }
for u := 0 to Grafo.NumVertices do
begin {Constroi o heap com todos os valores igual a I n f i n i t o }
Antecessor[u] := 1; p[u] : = I n f i n i t o ;

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

Algoritmo de Prim - Implementao


Para realizar de forma eficiente a seleo de
uma nova aresta, todos os vrtices que no
esto na AGM residem no heap A.

A[u+1].Chave : = u ; {Heap a ser construido }

O heap contm os vrtices, mas a condio


do heap mantida pelo peso da aresta
atravs do arranjo p[v] (heap indireto).

ItensHeap[u] : = true ; Pos[u] : = u+1;


end;
n : = Grafo.NumVertices;
p[Raiz ] : = 0 ;
Constroi(A) ;
while n >= 1 do {enquanto heap nao vazio}
begin
u : = RetiraMin(A) .Chave;
i f (u <> Raiz)
then write( Aresta de arvore : v [ ,u, ] v [ ,Antecessor[u] , ] ) ; readln;
ItensHeap[u] : = false ;
i f not ListaAdjVazia (u,Grafo)
then begin
Aux : = PrimeiroListaAdj (u,Grafo ) ;

FimListaAdj : = false ;

Pos[v] fornece a posio do vrtice v dentro


do heap A, para que o vrtice v possa ser
acessado a um custo O(1), necessrio para a
operao DiminuiChave.
Antecessor[v] armazena o antecessor de v na
rvore.

while not FimListaAdj do


begin
ProxAdj(u, Grafo , v , Peso, Aux, FimListaAdj ) ;
i f ItensHeap[ v ] and (Peso < p[ v ] )
then begin
Antecessor[ v ] : = u ; DiminuiChave(Pos[ v ] ,Peso,A) ;
end
end;
end;
end;
end; { AgmPrim }

Quando o algoritmo termina, A est vazia e a


AGM est de forma implcita como
S = {(v, Antecessor [v]) : v V {Raiz }}

83

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

84

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3

85

AGM - Algoritmo de Kruskal

Algoritmo de Prim - Anlise

Pode ser derivado do algoritmo genrico.

O corpo do anel while executado |V | vezes.

S uma floresta e a aresta segura adicionada


a S sempre uma aresta de menor peso que
conecta dois componentes distintos.

O procedimento Refaz tem custo O(log |V |).


Logo, o tempo total para executar a operao
retira o item com menor peso O(|V | log |V |).

Considera as arestas ordenadas pelo peso.

O while mais interno para percorrer a lista de


adjacentes O(|A|) (soma dos comprimentos
de todas as listas de adjacncia 2|A|).

(a)

(b)
0

6
1

5
3

1
2

2
5

O teste para verificar se o vrtice v pertence


ao heap A tem custo O(1).
Aps testar se v pertence ao heap A e o peso
da aresta (u, v) menor do que p[v], o
antecessor de v armazenado em
Antecessor e uma operao DiminuiChave
realizada sobre o heap A na posio Pos[v], a
qual tem custo O(log |V |).

(c)

Logo, o tempo total para executar o algoritmo


de Prim
O(|V log |V | + |A| log |V |) = O(|A| log |V |).

(e)

AGM - Algoritmo de Kruskal


Sejam C1 e C2 duas rvores conectadas por
(u, v):
Como (u, v) tem de ser uma aresta leve
conectando C1 com alguma outra rvore,
(u, v) uma aresta segura para C1 .
guloso porque, a cada passo, ele adiciona
floresta uma aresta de menor peso.
Obtm uma AGM adicionando uma aresta de
cada vez floresta e, a cada passo, usa a
aresta de menor peso que no forma ciclo.
Inicia com uma floresta de |V | rvores de um
vrtice: em |V | passos, une duas rvores at
que exista apenas uma rvore na floresta.

4
4

2
4

2
5

(f)
0

86

(d)
0

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3

6
4

2
5

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3

Algoritmo de Kruskal - Implementao


Usa fila de prioridades para obter arestas em
ordem crescente de pesos.
Testa se uma dada aresta adicionada ao
conjunto soluo S forma um ciclo.
Tratar conjuntos disjuntos: maneira
eficiente de verificar se uma dada aresta
forma um ciclo. Utiliza estruturas dinmicas.
Os elementos de um conjunto so
representados por um objeto. Operaes:
CriaConjunto(x): cria novo conjunto cujo
nico membro, x, seu representante.
Para que os conjuntos sejam disjuntos, x
no pode pertencer a outro conjunto.
Unio(x, y): une conjuntos dinmicos
contendo x (Cx ) e y (Cy ) em novo conjunto,
cujo representante pode ser x ou y. Como
os conjuntos na coleo devem ser
disjuntos, Cx e Cy so destrudos.
EncontreConjunto(x): retorna apontador
para o representante do conjunto (nico)
contendo x.

87

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3

88

89

AGM - Anlise do Algoritmo de Kruskal

Algoritmo de Kruskal - Implementao

A inicializao do conjunto S tem custo O(1).

Primeiro refinamento:

Ordenar arestas (linha 3) custa O(|A| log |A|).

procedure Kruskal ;
1.

S := ;

2.

for v := 0 to Grafo.NumVertices1 do CriaConjunto ( v ) ;

3.

Ordena as arestas de A pelo peso;

4.

for cada ( u, v ) de A tomadas em ordem ascendente de peso do

5.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3

A linha 2 realiza |V | operaes CriaConjunto.

i f EncontreConjunto (u) <> EncontreConjunto ( v)


then begin

6.

S := S + {(u, v)} ;

7.

Uniao ( u, v ) ;

O anel (linhas 4-7) realiza O(|A|) operaes


EncontreConjunto e Uniao, a um custo
O((|V | + |A|)(|V |)) onde (|V |) uma
funo que cresce lentamente ((|V |) < 4).
O limite inferior para construir uma estrutura
dinmica envolvendo m operaes
EncontreConjunto e Uniao e n operaes
CriaConjunto m(n).

end;
end;

A implementao das operaes Unio e


EncontraConjunto deve ser realizada de
forma eficiente.

Como G conectado temos que


|A| |V | 1, e assim as operaes sobre
conjuntos disjuntos custam O(|A|(|V |).

Esse problema conhecido na literatura


como Unio-EncontraConjunto.

Como (|V |) = O(log |A|) = O(log |V |), o


tempo total do algoritmo de Kruskal
O(|A| log |A|).
Como |A| < |V |2 , ento log |A| = O(log |V |), e
o custo do algoritmo de Kruskal tambm
O(|A| log |V |).

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

90

Caminhos Mais Curtos - Aplicao


Um motorista procura o caminho mais curto
entre Diamantina e Ouro Preto. Possui mapa
com as distncias entre cada par de
intersees adjacentes.
Modelagem:
G = (V, A): grafo direcionado ponderado,
mapa rodovirio.
V : intersees.
A: segmentos de estrada entre
intersees
p(u, v): peso de cada aresta, distncia
entre intersees.
Peso de um caminho: p(c) =

Pk

i=1

p(vi1 , vi )

Caminho mais curto:


(u, v) =

min p(c) : u ; v

se existir caminho de u a v
caso contrrio

Caminho mais curto do vrtice u ao vrtice


v: qualquer caminho c com peso
p(c) = (u, v).

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

Caminhos Mais Curtos


Caminhos mais curtos a partir de uma
origem: dado um grafo ponderado
G = (V, A), desejamos obter o caminho mais
curto a partir de um dado vrtice origem
s V at cada v V .
Muitos problemas podem ser resolvidos pelo
algoritmo para o problema origem nica:
Caminhos mais curtos com destino
nico: reduzido ao problema origem nica
invertendo a direo de cada aresta do
grafo.
Caminhos mais curtos entre um par de
vrtices: o algoritmo para origem nica
a melhor opo conhecida.
Caminhos mais curtos entre todos os
pares de vrtices: resolvido aplicando o
algoritmo origem nica |V | vezes, uma vez
para cada vrtice origem.

91

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

92

Caminhos Mais Curtos

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

93

rvore de caminhos mais curtos

A representao de caminhos mais curtos


pode ser realizada pela varivel Antecessor.

Uma rvore de caminhos mais curtos com


raiz em u V um subgrafo direcionado
G0 = (V 0 , A0 ), onde V 0 V e A0 A, tal que:

Para cada vrtice v V o Antecessor [v] um


outro vrtice u V ou nil (-1).

1. V 0 o conjunto de vrtices alcanveis a


partir de s G,

O algoritmo atribui a Antecessor os rtulos de


vrtices de uma cadeia de antecessores com
origem em v e que anda para trs ao longo de
um caminho mais curto at o vrtice origem s.

2. G0 forma uma rvore de raiz s,


3. para todos os vrtices v V 0 , o caminho
simples de s at v um caminho mais
curto de s at v em G.

Dado um vrtice v no qual Antecessor [v] 6= nil ,


o procedimento ImprimeCaminho pode
imprimir o caminho mais curto de s at v.
Os valores em Antecessor [v], em um passo
intermedirio, no indicam necessariamente
caminhos mais curtos.
Entretanto, ao final do processamento,
Antecessor contm uma rvore de caminhos
mais curtos definidos em termos dos pesos
de cada aresta de G, ao invs do nmero de
arestas.
Caminhos mais curtos no so
necessariamente nicos.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

Algoritmo de Dijkstra
Mantm um conjunto S de vrtices cujos
caminhos mais curtos at um vrtice origem
j so conhecidos.
Produz uma rvore de caminhos mais curtos
de um vrtice origem s para todos os vrtices
que so alcanveis a partir de s.
Utiliza a tcnica de relaxamento:
Para cada vrtice v V o atributo p[v]
um limite superior do peso de um caminho
mais curto do vrtice origem s at v.
O vetor p[v] contm uma estimativa de um
caminho mais curto.
O primeiro passo do algoritmo inicializar os
antecessores e as estimativas de caminhos
mais curtos:
Antecessor[v] = nil para todo vrtice
v V,
p[u] = 0, para o vrtice origem s, e
p[v] = para v V {s}.

94

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

Relaxamento
O relaxamento de uma aresta (u, v) consiste
em verificar se possvel melhorar o melhor
caminho at v obtido at o momento se
passarmos por u.
Se isto acontecer, p[v] e Antecessor[v] devem
ser atualizados.
i f p[ v] > p[u] + peso da aresta ( u, v)
then p[ v ] = p[u] + peso da aresta ( u, v)
Antecessor[ v ] : = u

95

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

96

Algoritmo de Dijkstra - 1o Refinamento

(a)

(b)

for v := 0 to Grafo.NumVertices1 do

2.

p[ v ] : = I n f i n i t o ;

3.

Antecessor[ v] := 1;

4.

97

Algoritmo de Dijkstra - Exemplo

procedure Dijkstra ( Grafo , Raiz ) ;


1.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

1
1

10

0
0

1
1

10

10
4

p[Raiz ] : = 0 ;

5.

Constroi heap no vetor A;

S := ;

7.

While heap > 1 do

5
2

8.

u : = RetiraMin(A) ;

S := S + u

10.

for v ListaAdjacentes [u ] do

i f p[ v] > p[u] + peso da aresta ( u, v)

12.

then p[ v ] = p[u] + peso da aresta ( u, v)

1
1

2
6

10
4

RetiraMin obtm o vrtice u com o caminho


mais curto estimado at o momento e
adiciona ao conjunto S.

10

Antecessor[ v ] : = u

A cada iterao do while, um vrtice u


extrado do heap e adicionado ao conjunto S,
mantendo assim o invariante.

6
3

Invariante: o nmero de elementos do heap


igual a V S no incio do anel while.

(c)

11.
13.

6
3

6
3

Iterao

d[0]

d[1]

d[2]

d[3]

d[4]

(a)

(b)

{0}

10

(c)

{0, 1}

10

No anel da linha 10, a operao de


relaxamento realizada sobre cada aresta
(u, v) adjacente ao vrtice u.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

98

Algoritmo de Dijkstra - Exemplo


(d)

(e)

0
0

1
1

3
1

5
2
5

10

9
4

10

Para realizar de forma eficiente a seleo de


uma nova aresta, todos os vrtices que no
esto na rvore de caminhos mais curtos
residem no heap A baseada no campo p.

6
4

3
1
2

(f)

Algoritmo de Dijkstra

0
0

6
2

Para cada vrtice v, p[v] o caminho mais


curto obtido at o momento, de v at o vrtice
raiz.

0
0

1
1

1
2

O heap mantm os vrtices, mas a condio


do heap mantida pelo caminho mais curto
estimado at o momento atravs do arranjo
p[v], o heap indireto.

6
4

5
5

10

6
2

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

Iterao

d[0]

d[1]

d[2]

d[3]

d[4]

(d)

{0, 1, 3}

(e)

{0, 1, 3, 2}

(f)

{0, 1, 3, 2, 4}

O arranjo Pos[v] fornece a posio do vrtice


v dentro do heap A, permitindo assim que o
vrtice v possa ser acessado a um custo O(1)
para a operao DiminuiChaveInd.

99

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

100

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

101

Algoritmo de Dijkstra - Implementao

Algoritmo de Dijkstra - Implementao

procedure Dijkstra ( var Grafo : TipoGrafo ; var Raiz : TipoValorVertice ) ;

..
.

var Antecessor : array [ TipoValorVertice ] of integer ;


P

: array [ TipoValorVertice ] of TipoPeso;

while n >= 1 do {enquanto heap nao vazio}

Itensheap : array [ TipoValorVertice ] of boolean;


Pos

: array [ TipoValorVertice ] of TipoValorVertice ;

: Vetor ;

u, v

: TipovalorVertice ;

begin
u : = RetiraMinInd(A) .Chave;
ItensHeap[u] : = false ;
i f not ListaAdjVazia (u,Grafo)
then begin

{ Entram aqui os operadores de uma das implementaes de grafos, bem


como o operador Constroi da implementao de filas de prioridades, assim
como os operadores RefazInd, RetiraMinInd e DiminuiChaveInd do Programa Constroi}

Aux : = PrimeiroListaAdj (u,Grafo ) ;

FimListaAdj : = false ;

while not FimListaAdj do


begin
ProxAdj(u, Grafo , v , Peso, Aux, FimListaAdj ) ;
i f p[ v] > p[u] + Peso

begin { Dijkstra }

then begin

for u := 0 to Grafo.NumVertices do
begin {Constroi o heap com todos os valores igual a I n f i n i t o }

p[ v ] : = p[u] + Peso;

Antecessor[u] := 1; p[u] : = I n f i n i t o ;

DiminuiChaveInd(Pos[ v ] ,p[ v ] ,A) ;

A[u+1].Chave : = u ; {Heap a ser construido }

write( Caminho: v [ ,v, ] v [ ,Antecessor[ v ] , ] ,


d[ ,p[ v ] , ] ) ; readln;

ItensHeap[u] : = true ; Pos[u] : = u+1;


end;

end;
end;

n : = Grafo.NumVertices ; {Tamanho do heap}

end;

p[Raiz ] : = 0 ;
end;

Constroi(A) ;

end; { Dijkstra }
..
.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

Porque o Algoritmo de Dijkstra


Funciona
O algoritmo usa uma estratgia gulosa:
sempre escolher o vrtice mais leve (ou o
mais perto) em V S para adicionar ao
conjunto soluo S,
O algorimo de Dijkstra sempre obtm os
caminhos mais curtos, pois cada vez que um
vrtice adicionado ao conjunto S temos que
p[u] = (Raiz, u).

Antecessor[ v ] : = u;

102

Você também pode gostar