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

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

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. 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.

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

aresta
1 4

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

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Grafos Direcionados
Um grafo direcionado G um par (V, A), onde V um conjunto nito de vrtices e A uma relao binria em V . Uma aresta (u, v ) sai do vrtice u e entra no vrtice v . O vrtice v adjacente ao vrtice u. Podem existir arestas de um vrtice para ele mesmo, chamadas de self-loops.
0 1 4

Grafos No Direcionados
Um grafo no direcionado G um par (V, A), onde o conjunto de arestas A constitudo de pares de vrtices no ordenados. As arestas (u, v ) e (v, u) so consideradas como uma nica aresta. A relao de adjacncia simtrica. Self-loops no so permitidos.
0 1 4

3 3 2 5

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

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. Ex.: O vrtice 1 tem grau 2 e o vrtice 3 isolado.
0 1 4

Caminho entre Vrtices


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. 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 3 2 5 3 2 5 1 4

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.
0 1 4

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

Ciclos
Em um grafo direcionado: Um caminho (v0 , v1 , . . . , vk ) forma um ciclo se v0 = vk e o caminho contm pelo menos uma aresta. O ciclo simples se os vrtices v1 , v2 , . . . , vk so distintos. O self-loop um ciclo de tamanho 1. Dois caminhos (v0 , v1 , . . . , vk ) e (v0 , v1 , . . . , vk ) formam o mesmo ciclo se existir um inteiro j tal que vi = 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 1 4

Ciclos
Em um grafo no direcionado: 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. Ex.: O caminho (0, 1, 2, 0) um ciclo.
0 1 4

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

10

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

11

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 1 4

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 1 4

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

12

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

13

Grafos Isomorfos
G = (V, A) e G = (V , A ) so isomorfos se existir uma bijeo f : V V tal que (u, v ) A se e somente se (f (u), f (v )) A .
0 4 5 1

Subgrafos
Um grafo G = (V , A ) um subgrafo de G = (V, A) se V V e A A. Dado um conjunto V V , o subgrafo induzido por V o grafo G = (V , A ), onde A = {(u, v ) A|u, v V }. Ex.: Subgrafo induzido pelo conjunto de vrtices {1, 2, 4, 5}.
2 0 1 4

7 3

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

14

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

15

Verso Direcionada de um Grafo No Direcionado


A verso direcionada de um grafo no direcionado G = (V, A) um grafo direcionado G = (V , A ) onde (u, v ) A se e somente se (u, v ) A. Cada aresta no direcionada (u, v ) em G substituda por duas arestas direcionadas (u, v ) e (v, u) Em um grafo direcionado, um vizinho de um vrtice u qualquer vrtice adjacente a u na verso no direcionada de G.
0 1 0 1

Verso No Direcionada de um Grafo Direcionado


A verso no direcionada de um grafo direcionado G = (V, A) um grafo no direcionado G = (V , A ) onde (u, v ) A se e somente se u = v e (u, v ) A. A verso no direcionada contm as arestas de G sem a direo e sem os self-loops. Em um grafo no direcionado, u e v so vizinhos se eles so adjacentes.
0 1 4 0 1 4

3 2 2

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

16

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

17

Outras Classicaes de Grafos


Grafo ponderado: possui pesos associados s arestas. 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 ). Hipergrafo: grafo no direcionado em que cada aresta conecta um nmero arbitrrio de vrtices.

Grafos Completos
Um grafo completo um grafo no direcionado no qual todos os pares de vrtices so adjacentes. 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).

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.1

18

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2

19

rvores
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 oresta.

O Tipo Abstratos de Dados Grafo


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.

(a)

(b)

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2

20

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2

21

Operadores do TAD Grafo


1. FGVazio(Grafo): Cria um grafo vazio. 2. InsereAresta(V1,V2,Peso, Grafo): Insere uma aresta no grafo. 3. ExisteAresta(V1,V2,Grafo): Verica se existe uma determinada aresta. 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.

Operao Obter Lista de Adjacentes


1. ListaAdjVazia(v, Grafo): retorna true se a lista de adjacentes de v est vazia. 2. PrimeiroListaAdj(v, Grafo): retorna o endereo do primeiro vrtice na lista de adjacentes de v . 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 nal da lista de adjacentes foi encontrado.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2

22

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1

23

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 renamento do pseudo comando acima.
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;

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. Se no existir uma aresta de i para j ento necessrio utilizar um valor que no possa ser usado como rtulo ou peso.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1

24

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1

25

Matriz de Adjacncia - Exemplo


0 1 4 0 1 4

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|. 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 ).

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

26

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.1

27

Matriz de Adjacncia - Implementao


A insero de um novo vrtice ou retirada de um vrtice j existente pode ser realizada com custo constante.
const MaxNumVertices = 100; MaxNumArestas = 4500; type TipoValorVertice = 0..MaxNumVertices; TipoPeso = integer ; Mat: array [ TipoValorVertice , TipoValorVertice ] of TipoPeso; NumVertices: 0 . .MaxNumVertices; NumArestas : 0 . .MaxNumArestas; end; Apontador = TipoValorVertice ; procedure FGVazio( var Grafo : TipoGrafo ) ; var i , j : integer ; begin for i := 0 to Grafo.NumVertices do for j := 0 to Grafo.NumVertices do Grafo.mat[ i , j ] : = 0 ; end;

Matriz de Adjacncia - Implementao


procedure InsereAresta ( var V1, V2: TipoValorVertice ; var Peso begin Grafo.Mat[V1, V2] : = peso; end; function ExisteAresta ( Vertice1 , Vertice2 : TipoValorVertice ; var Grafo : TipoGrafo ) : boolean ; begin ExisteAresta : = Grafo.Mat[ Vertice1 , Vertice2 ] > 0; end ; { ExisteAresta } { Operador para obter a l i s t a de adjacentes } function ListaAdjVazia ( var Vertice : TipoValorVertice ; var Grafo : TipoGrafo ) : boolean ; var Aux: Apontador ; ListaVazia : boolean ; begin ListaVazia : = true ; Aux := 0; while (Aux < Grafo.NumVertices) and ListaVazia do i f Grafo.Mat[ Vertice , Aux] > 0 then ListaVazia : = false else Aux : = Aux + 1; ListaAdjVazia : = ListaVazia = true ; end ; { ListaAdjVazia } : TipoPeso; var Grafo : TipoGrafo ) ;

TipoGrafo = record

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

29

Matriz de Adjacncia - Implementao


{ Operador para obter a l i s t a de adjacentes } function PrimeiroListaAdj ( var Vertice : TipoValorVertice ; var Grafo : TipoGrafo ) : Apontador; var Aux: Apontador ; Listavazia : boolean ; begin ListaVazia : = true ; Aux := 0; while (Aux < Grafo.NumVertices) and ListaVazia do i f Grafo.Mat[ Vertice , Aux] > 0 then begin PrimeiroListaAdj : = Aux; ListaVazia : = false ; end else Aux : = Aux + 1; i f Aux = Grafo.NumVertices then writeln ( Erro : Lista adjacencia vazia ( PrimeiroListaAdj ) ) ; end ; { PrimeiroListaAdj }

Matriz de Adjacncia - Implementao


procedure RetiraAresta ( var V1, V2: TipoValorVertice ; var Peso begin i f Grafo.Mat[V1, V2] = 0 then writeln ( Aresta nao existe ) else begin Peso : = Grafo.Mat[V1, V2] ; Grafo.Mat[V1, V2] : = 0 ; end; end ; { RetiraAresta } procedure LiberaGrafo ( var Grafo : TipoGrafo ) ; begin { Nao faz nada no caso de matrizes de adjacencia } end ; { LiberaGrafo } procedure ImprimeGrafo ( var Grafo : TipoGrafo ) ; : TipoPeso; var Grafo : TipoGrafo ) ;

{ Operador para obter a l i s t a de adjacentes } procedure ProxAdj ( var Vertice : TipoValorVertice ; var Grafo : TipoGrafo; var Adj : TipoValorVertice ; var Peso: TipoPeso; var Prox : Apontador ; var FimListaAdj : boolean ) ; { Retorna Adj apontado por Prox } begin Adj := Prox ; Peso : = Grafo.Mat[ Vertice , Prox ] ; Prox : = Prox + 1; (Grafo.Mat[ Vertice , Prox] = 0 ) do Prox : = Prox + 1; i f Prox = Grafo.NumVertices then FimListaAdj : = true ; end ; { ProxAdj } while ( Prox < Grafo.NumVertices) and

var i , j : integer ; begin write ( ); for i := 0 to Grafo.NumVertices1 do write ( i : 3 ) ; writeln ; for i := 0 to Grafo.NumVertices1 do begin write ( i : 3 ) ; for j := 0 to Grafo.NumVertices1 do write (Grafo.mat[ i , j ] : 3 ) ; writeln ; end; end ; { ImprimeGrafo }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2

30

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2

31

Listas de Adjacncia usando Apontadores


3 5 0 1 7 3 2 1 2 3 0 1 7 3 2 1 2 3 1 5 0 5 1 7 2 7 1 5 1 3 2 7

Listas de adjacncia - Anlise


Os vrtices de uma lista de adjacncia so em geral armazenados em uma ordem arbitrria. Possui uma complexidade de espao O(|V | + |A|) Indicada para grafos esparsos, onde |A| muito menor do que |V |2 . 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.

5 0

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.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2

32

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.
const MaxNumVertices = 100; MaxNumArestas = 4500; type TipoValorVertice = 0..MaxNumVertices; TipoPeso TipoItem = integer ; = record Vertice : TipoValorVertice ; Peso end; Apontador Celula = ^Celula ; = record Item : TipoItem ; Prox : Apontador; end; TipoLista = record Primeiro : Apontador; Ultimo : Apontador; end; TipoGrafo = record Adj : array [ TipoValorVertice ] of TipoLista ; NumVertices : TipoValorVertice ; NumArestas: 0 . .MaxNumArestas; end; : TipoPeso;

Listas de Adjacncia usando Apontadores - Implementao


{ 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 } procedure InsereAresta( var V1, V2: TipoValorVertice ; var Peso: TipoPeso; var Grafo : TipoGrafo ) ; var x : TipoItem ; begin x . Vertice : = V2; x .Peso : = Peso; Insere (x , Grafo. Adj [V1] ) ; end ; { InsereAresta } function ExisteAresta ( Vertice1 , Vertice2 : TipoValorVertice ; var Grafo : TipoGrafo ) : boolean ; var Aux: Apontador; EncontrouAresta : boolean ; begin Aux : = Grafo. Adj [ Vertice1 ] . Primeiro^.Prox; EncontrouAresta : = false ; while (Aux <> n i l ) and ( EncontrouAresta = false ) do begin i f Vertice2 = Aux^.Item . Vertice then EncontrouAresta : = true ; Aux : = Aux^.Prox; end; ExisteAresta : = EncontrouAresta; 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

35

Listas de Adjacncia usando Apontadores - Implementao


{ Operador para obter a l i s t a de adjacentes } function ListaAdjVazia ( var Vertice : TipoValorVertice ; var Grafo : TipoGrafo ) : boolean ; begin ListaAdjVazia : = Grafo. Adj [ Vertice ] . Primeiro = Grafo. Adj [ Vertice ] . Ultimo ; end ; { ListaAdjVazia } { 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 } { Operador para obter a l i s t a de adjacentes } procedure ProxAdj ( var Vertice var Grafo var Adj var Peso var Prox : TipoValorVertice ; : TipoGrafo; : TipoValorVertice ; : TipoPeso; : Apontador;

Listas de Adjacncia usando Apontadores - Implementao


procedure RetiraAresta ( var V1, V2: TipoValorVertice ; var Peso var AuxAnterior , Aux: Apontador; EncontrouAresta : boolean ; x : TipoItem ; begin AuxAnterior : = Grafo. Adj [V1] . Primeiro ; 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 ) ; Grafo.NumArestas : = Grafo.NumArestas 1; EncontrouAresta : = true ; end; AuxAnterior : = Aux; Aux : = Aux^.Prox; end; end ; { RetiraAresta } : TipoPeso; var Grafo : TipoGrafo ) ;

var FimListaAdj : boolean ) ; { Retorna Adj e Peso do Item apontado por Prox } begin Adj Peso Prox := Prox^.Item . Vertice ; := Prox^.Item .Peso; := Prox^.Prox;

i f Prox = n i l then FimListaAdj : = true ; end ; { ProxAdj }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.2

36

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.2.3

37

Listas de Adjacncia usando Apontadores - Implementao


procedure LiberaGrafo ( var Grafo : TipoGrafo ) ; var AuxAnterior , Aux: Apontador; begin for i := 0 to Grafo.NumVertices1 do begin 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; end; end ; { LiberaGrafo } procedure ImprimeGrafo ( var Grafo : TipoGrafo ) ; var i : integer ; Aux: Apontador; begin for i := 0 to Grafo.NumVertices1 do 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 begin write (Aux^.Item . Vertice :3 , ( ,Aux^.Item .Peso, ) ) ; Aux : = Aux^.Prox; end; end; writeln ; end; end ; { ImprimeGrafo }

Listas de Adjacncia usando Arranjos


3 5 0 1 7 3 2 A V 0 1 2 3 4 5 6

Cab
4 6 2 3 1 1 2

Prox
4 5 0 0 0 6 0

Peso

5 3 7

Cab
5 0 1 7 3 2 A V 0 1 2 3 4 5 6 7 4 6 7 3 1 0 2 1

Prox
4 5 7 0 0 6 0 0

Peso

5 5 7 7

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) Prox: endereo do prximo item da lista de adjacentes. Peso: valor do peso de cada aresta do grafo (nas ltimas |A| posies).

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

39

Listas de Adjacncia usando Arranjos - Implementao


const MaxNumVertices = 100; MaxNumArestas = 4500; MaxTam type TipoValorVertice = 0..MaxNumVertices; TipoPeso TipoTam = integer ; = 0..MaxTam; Cab Prox Peso NumVertices NumArestas end; Apontador = TipoTam; procedure FGVazio( var Grafo : TipoGrafo ) ; var i : integer ; begin for i := 0 to Grafo.NumVertices do begin Grafo.Prox[ i ] : = 0 ; Grafo.Cab[ i ] : = i ; Grafo. ProxDisponivel : = Grafo.NumVertices; end; end; : array [TipoTam] of TipoTam; : array [TipoTam] of TipoTam; : array [TipoTam] of TipoTam; : 0 . .MaxNumVertices; : 0 . .MaxNumArestas; = MaxNumVertices+2MaxNumArestas;

Listas de Adjacncia usando Arranjos - Implementao


procedure InsereAresta ( var V1, V2: TipoValorVertice ; var Peso var Pos: integer ; begin Pos:= Grafo. ProxDisponivel ; i f Grafo. ProxDisponivel = MaxTam then writeln ( nao ha espaco disponivel para a aresta ) else begin Grafo. ProxDisponivel : = Grafo. ProxDisponivel + 1; Grafo.Prox[Grafo.Cab[V1] ] : = Pos; Grafo.Cab[Pos] : = V2; Grafo.Prox[Pos] : = 0 ; end; end ; { InsereAresta} function ExisteAresta ( Vertice1 , Vertice2 : TipoValorVertice ; var Grafo : TipoGrafo ) : boolean ; var Aux: Apontador ; EncontrouAresta : boolean ; begin Aux : = Grafo.Prox[ Vertice1 ] ; EncontrouAresta : = false ; while (Aux < > 0) and ( EncontrouAresta = false ) do begin i f Vertice2 = Grafo.Cab[Aux] then EncontrouAresta : = true ; Aux : = Grafo.Prox[Aux] ; end; ExisteAresta : = EncontrouAresta; end ; { ExisteAresta } Grafo.Cab[V1] : = Pos; Grafo.Peso[Pos] : = Peso; : TipoPeso; var Grafo : TipoGrafo ) ;

TipoGrafo = record

ProxDisponivel : TipoTam;

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

41

Listas de Adjacncia usando Arranjos - Implementao


{ Operador para obter a l i s t a de adjacentes } function ListaAdjVazia ( var Vertice : TipoValorVertice ; var Grafo : TipoGrafo ) : boolean ; begin ListaAdjVazia : = Grafo.Prox[ Vertice ] = 0; end ; { ListaAdjVazia } { Operador para obter a l i s t a de adjacentes } function PrimeiroListaAdj ( var Vertice : TipoValorVertice ; var Grafo : TipoGrafo ) : Apontador; begin PrimeiroListaAdj : = Grafo.Prox[ Vertice ] ; end ; { PrimeiroListaAdj } { Operador para obter a l i s t a de adjacentes } procedure ProxAdj ( var Vertice var Grafo var Adj var Peso var Prox : TipoValorVertice ; : TipoGrafo; : TipoValorVertice ; : TipoPeso; : Apontador;

Listas de Adjacncia usando Arranjos - Implementao


procedure RetiraAresta ( var V1, V2: TipoValorVertice ; var Peso: TipoPeso ; var Grafo : TipoGrafo ) ; var Aux, AuxAnterior : Apontador ; EncontrouAresta : boolean ; begin AuxAnterior : = V1; Aux : = Grafo.Prox[V1] ; EncontrouAresta : = false ; while (Aux < > 0) and ( EncontrouAresta = false ) do begin i f V2 = Grafo.Cab[Aux] then EncontrouAresta : = true else begin AuxAnterior : = Aux; Aux : = Grafo.Prox[Aux] ; end; end; i f EncontrouAresta then Grafo.Cab[Aux] : = MaxNumVertices+2MaxNumArestas { Apenas marca como retirado } else writeln ( Aresta nao existe ) ; end ; { RetiraAresta } procedure LiberaGrafo ( var Grafo : TipoGrafo ) ; begin {Nada no caso de posicoes contiguas} end ; { LiberaGrafo } procedure ImprimeGrafo ( var Grafo : TipoGrafo ) ; var i : integer ; begin writeln ( Cab Prox Peso ) ;

var FimListaAdj : boolean ) ; { Retorna Adj apontado por Prox } begin Adj := Grafo.Cab[Prox ] ; Peso : = Grafo.Peso[Prox ] ; Prox : = Grafo.Prox[Prox ] ; i f Prox = 0 then FimListaAdj : = true ; end ; { ProxAdj }

for i := 0 to Grafo.NumVertices+2Grafo.NumArestas1 do writeln ( i :2 ,Grafo.Cab[ i ]:4 ,Grafo.Prox[ i ] : 4 , Grafo.Peso[ i ] : 4 ) ; end ; { ImprimeGrafo }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

42

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

43

Busca em Profundidade
A busca em profundidade, do ingls depth-rst search), um algoritmo para caminhar no grafo. A estratgia buscar o mais profundo no grafo sempre que possvel. 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 vericao de grafos acclicos, ordenao topolgica e componentes fortemente conectados.

Busca em Profundidade
Para acompanhar o progresso do algoritmo 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, 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.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

44

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

45

Busca em Profundidade Implementao


procedure BuscaEmProfundidade ( var Grafo : TipoGrafo ) ; var Tempo x d, t Cor : TipoValorTempo; : TipoValorVertice ; : array [ TipoValorVertice ] of TipoValorTempo; : array [ TipoValorVertice ] of TipoCor;

Busca em Profundidade Implementao


procedure VisitaDfs (u: TipoValorVertice ) ; var FimListaAdj : boolean ; Peso Aux v begin Cor[u] : = cinza ; Tempo : = Tempo + 1; d[u] : = Tempo; writeln ( Visita ,u:2 , Tempo descoberta : ,d[u]:2 , cinza ) ; readln ; i f not ListaAdjVazia (u, Grafo) then 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 Antecessor[ v ] : = u ; VisitaDfs (v ) ; end; end; end; Cor[u] : = preto ; Tempo : = Tempo + 1; end ; { VisitaDfs } t [u] : = Tempo; writeln ( Visita ,u:2 , Tempo termino : , t [u]:2 , preto ) ; readln ; : TipoPeso; : Apontador; : TipoValorVertice ;

Antecessor : array [ TipoValorVertice ] of integer ; { Entra aqui o procedimento VisitaDFS (a seguir) } begin Tempo := 0; for x := 0 to Grafo.NumVertices1 do begin Cor[ x ] : = branco ; Antecessor[ x] := 1; end; for x := 0 to Grafo.NumVertices1 do i f Cor[ x ] = branco then VisitaDfs (x ) ; end ; { BuscaEmProfundidade }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

46

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

47

Busca em Profundidade - Exemplo


b( / ) 0 b( / ) 1 b( / ) b( / ) 2 3 b( / ) 2 c(1/ ) 0 b( / ) 1 b( / ) 3

Busca em Profundidade - Exemplo


c(1/ ) 0 p(2/5) 1 b( / ) p(3/4) 2 3 p(3/4) 2 p(1/6) 0 p(2/5) 1 b( / ) 3

(a)
c(1/ ) 0 c(2/ ) 1 b( / ) b( / ) 2 3 c(1/ ) 0

(b)
c(2/ ) 1 b( / ) c(3/ ) 2 3 p(1/6) 0

(f)
p(2/5) 1 c(7/ ) p(3/4) 2 3 p(1/6) 0

(g)
p(2/5) 1 p(7/8) p(3/4) 2 3

(c)
c(1/ ) 0 c(2/ ) 1

(d)

(h)

(i)

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

(e)

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3

48

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3.1

49

Busca em Profundidade - Anlise


Os dois anis da BuscaEmProfundidade tm custo O(|V |) cada um, a menos da chamada do procedimento VisitaDfs(u) no segundo anel. 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. Durante a execuo de VisitaDfs(u) o anel principal executado |Adj [u]| vezes. Desde que uV |Adj [u]| = O(|A|), o tempo total de execuo de VisitaDfs O(|A|). Logo, a complexidade total da BuscaEmProfundidade O(|V | + |A|).

Classicao de Arestas
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 ). 2. Arestas de retorno: conectam um vrtice u com um antecessor v em uma rvore de busca em profundidade (inclui self-loops). 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. 4. Arestas de cruzamento: podem conectar vrtices na mesma rvore de busca em profundidade, ou em duas rvores diferentes.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3.1

50

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.3.2

51

Classicao de Arestas
Classicao de arestas pode ser til para derivar outros algoritmos. Na busca em profundidade cada aresta pode ser classicada 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.
3/6 2 arv 3 4/5 arv ret cruz 4 7/8 2/9 1 arv avan cruz 5 11/12 arv 1/10 0 cruz

Teste para Vericar se Grafo Acclico


A busca em profundidade pode ser usada para vericar 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.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

52

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. O algoritmo descobre todos os vrtices a uma distncia k do vrtice origem antes de descobrir qualquer vrtice a uma distncia k + 1. O grafo G(V, A) pode ser direcionado ou no direcionado.

Busca em Largura
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. Vrtices cinza e preto j foram descobertos, mas so distinguidos para assegurar que a busca ocorra em largura. 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

55

Busca em Largura - Implementao


{ Entram aqui os operadores FFVazia, Vazia, Enleira e Desenleira do } { TAD Filas com arranjos ou apontadores, dependendo da implementao } { da busca em largura usar arranjos ou apontadores, respectivamente } procedure BuscaEmLargura ( var Grafo : TipoGrafo ) ; var x Dist Cor : TipoValorVertice ; : array [ TipoValorVertice ] of integer ; : array [ TipoValorVertice ] of TipoCor;

Busca em Largura - Implementao


procedure VisitaBfs (u: TipoValorVertice ) ; var v : TipoValorVertice ; Aux: Apontador ; FimListaAdj : boolean ; Peso: TipoPeso ; Item : TipoItem ; Fila : TipoFila ; begin Cor[u] : = cinza ; FFVazia ( Fila ) ; Dist [u] : = 0 ; Item . Vertice : = u;

Enfileira ( Item , Fila ) ; write ( Visita origem ,u:2 , cor : cinza F: ) ; ImprimeFila ( Fila ) ; readln ; while not FilaVazia ( Fila ) do begin Desenfileira ( Fila , Item ) ; then begin u : = Item . vertice ; i f not ListaAdjVazia (u, Grafo) Aux : = PrimeiroListaAdj (u,Grafo ) ; FimListaAdj : = false ; while FimListaAdj = false do begin ProxAdj(u, v , Peso, Aux, FimListaAdj ) ; i f Cor[ v ] = branco then begin Cor[ v ] : = cinza ; Item . Vertice : = v ; end; end; end; Cor[u] : = preto ; write ( Visita , u:2 , Dist , Dist [u]:2 , cor : preto F: ) ; ImprimeFila ( Fila ) ; readln ; end; end ; { VisitaBfs } Dist [ v ] : = Dist [u] + 1; Item .Peso : = Peso; Antecessor[ v ] : = u; Enfileira ( Item , Fila ) ;

Antecessor : array [ TipoValorVertice ] of integer ; { Entra aqui o procedimento VisitaBfs (a seguir) } begin for x := 0 to Grafo.NumVertices1 do begin Cor[ x ] : = branco ; end; for x := 0 to Grafo.NumVertices1 do i f Cor[ x ] = branco then VisitaBfs (x ) ; end ; { BuscaEmLargura } Dist [ x ] : = i n f i n i t o ; Antecessor[ x] := 1;

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

56

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

57

Busca em Largura - Exemplo


(a)
c(0) 0 b( ) 1 b( ) 4 p(0) 0

Busca em Largura - Exemplo


(e)
b( ) 4 p(0) 0 p(1) 1 b( ) 4 p(0) 0

(b)
c(1) 1

(f)
p(1) 1 c(0) 4

3 b( )

2 b( ) F 0 0

5 b( )

3 c(1)

2 b( ) F 1 3 1 1

5 b( )

3 p(1)

2 p(2) F

5 b( )

3 p(1)

2 p(2) F 4 0

5 b( )

(c)
p(0) 0 p(1) 1 b( ) 4 p(0) 0

(d)
p(1) 1 b( ) 4 p(0) 0

(g)
p(1) 1 p(0) 4 p(0) 0

(h)
p(1) 1 p(0) 4

3 c(1)

2 c(2) F 3 2 1 2

5 b( )

3 p(1)

2 c(2) F 2 2

5 b( )

3 p(1)

2 p(2) F 5 1

5 c(1)

3 p(1)

2 p(2) F

5 p(1)

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

58

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.4

59

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: enleirar e desenleirar tm custo O(1), logo, o custo total com a la O(|V |). Cada lista de adjacentes percorrida no mximo uma vez, quando o vrtice desenleirado. 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|).

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 }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.5

60

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.5

61

Ordenao Topolgica
Ordenao linear de todos os vrtices, tal que se G contm uma aresta (u, v ) ento u aparece antes de 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
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 .
1/18 0 2/15 4/5 3 2 3/14 1 4 6/13 16/17 5 7/12 6 7 8/11 8 9/10 19/20 9

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.5

62

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.5

63

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).

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 nal, 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 }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

64

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

65

Componentes Fortemente Conectados


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 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.
0 1 0 1 0,1,2

Componentes Fortemente Conectados - Algoritmo


Usa o transposto de G, denido GT = (V, AT ), onde AT = {(u, v ) : (v, u) A}, isto , AT consiste das arestas de G com suas direes invertidas. 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 .

(a)

(b)

(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


1. Chama BuscaEmProfundidade(G) para obter os tempos de trmino t[u] para cada vrtice u. 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 oresta obtida como um componente fortemente conectado separado.

Componentes Fortemente Conectados - Exemplo


A parte (b) apresenta o resultado da busca em profundidade sobre o grafo transposto obtido, mostrando os tempos de trmino e a classicao das arestas. A busca em profundidade em GT resulta na oresta de rvores mostrada na parte (c).
1/8 0 2/7 1 cruz 3 4/5 2 3/6 1/6 0 ret arv 3/4 1 arv ret 0 cruz 3

arv cruz 2 arv 1

3 2 cruz 7/8 2/5

(a)

(b)

(c)

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

68

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 FGVazio(GrafoT) ; GrafoT.NumVertices : = Grafo.NumVertices; GrafoT.NumArestas := Grafo.NumArestas; for v := 0 to Grafo.NumVertices1 do i f not ListaAdjVazia (v , Grafo) then begin Aux : = PrimeiroListaAdj (v , Grafo ) ; FimListaAdj : = false ; while not FimListaAdj do begin ProxAdj(v , Grafo , u, Peso, Aux, FimListaAdj ) ; InsereAresta(u, v , Peso, GrafoT) ; end; end; end ; { GrafoTransposto }

Componentes Fortemente Conectados - Implementao


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.
type TipoTempoTermino = record t : array [ TipoValorVertice ] of TipoValorTempo; Restantes : array [ TipoValorVertice ] of boolean ; NumRestantes: TipoValorVertice ; end; Function MaxTT ( var TT: TipoTempoTermino) : TipoValorVertice ; var i , Temp: integer ; begin i :=0; while not TT.Restantes[ i ] do i : = i + 1; Temp : = TT. t [ i ] ; MaxTT : = i ; for i := 0 to Grafo.NumVertices1 do 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

71

Componentes Fortemente Conectados - Implementao


procedure BuscaEmProfundidadeCfc ( var Grafo : TipoGrafo; var TT: TipoTempoTermino) ; var Tempo x , VRaiz d, t Cor : TipoValorTempo; : TipoValorVertice ; : array [ TipoValorVertice ] of TipoValorTempo; : array [ TipoValorVertice ] of TipoCor;

Componentes Fortemente Conectados - Implementao


procedure VisitaDfs (u: TipoValorVertice ) ; var FimListaAdj : boolean ; Peso Aux v 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) then 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 Antecessor[ v ] : = u; VisitaDfs (v ) ; end; end; end; Cor[u] : = preto ; Tempo : = Tempo + 1; end ; { VisitaDfs } t [u] : = Tempo; writeln ( Visita ,u:2 , Tempo termino : , t [u]:2 , preto ) ; readln ; : TipoPeso; : Apontador; : TipoValorVertice ;

Antecessor : array [ TipoValorVertice ] of integer ; { Entra aqui o procedimento VisitaDFS (a seguir) } begin Tempo := 0; for x := 0 to Grafo.NumVertices1 do begin Cor[ x ] : = branco ; 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 VRaiz : = MaxTT (TT) ; writeln ( Raiz da proxima arvore : ,VRaiz: 2 ) ; VisitaDfs (VRaiz) ; end; end ; { BuscaEmProfundidadeCfc }

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.6

72

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7

73

Componentes Fortemente Conectados - Anlise


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

rvore Geradora Mnima - Aplicao


Projeto de redes de comunicaes conectando n localidades. 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 cujo peso total p(T ) = (u,v)T p(u, v ) minimizado.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7

74

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.1

75

rvore Geradora Mnima (AGM)


Como G = (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.
6 1 5 4 2 6 3 0 1 2 4 5 4 4 3 5 2 5 3 1 2 0 1 2 4 2 3

AGM - Algoritmo Genrico


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 3 4 Encontre uma aresta (u, v ) que segura para S ; S := S + {(u, v )}

5 return S ;

(a)

(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 ) S e (u, v ) seguro para S .

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.1

76

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.1

77

AGM - Denio de Corte


Um corte (V , V V ) de um grafo no direcionado G = (V, A) uma partio de V . Uma aresta (u, v ) A cruza o corte (V , V V ) se um de seus vrtices pertence a V e o outro vrtice pertence a V V . Um corte respeita um conjunto S de arestas se no existirem arestas em S que o cruzem. Uma aresta cruzando o corte que tenha custo mnimo sobre todas as arestas cruzando o corte uma aresta leve.
p p V V V 1 5 4 b 6 2 0 1 2 6 4 5 3 4 b 2 5 3 p V V V

AGM - Teorema para reconhecer arestas seguras


Seja G = (V, A) um grafo conectado, no direcionado, com pesos p sobre as arestas V . seja S um subconjunto de V que est includo em alguma AGM para G. Seja (V , V V ) um corte qualquer que respeita S . Seja (u, v ) uma aresta leve cruzando (V , V V ). Satisfeitas essas condies, a aresta (u, v ) uma aresta segura para S .

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

78

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

79

AGM - Algoritmo de Prim


O algoritmo de Prim para obter uma AGM pode ser derivado do algoritmo genrico. 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 . 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.

Algoritmo de Prim - Exemplo


(a)
6 1 5 4 2 6 3 0 0 2 1 2 1 6 4 5 4 6 4 3 2 2 1 2 1 4 4 3 0 1 2 4 5 4 4 2 5 3

(b)
6 1

0 0 5 3 2 1 5

(c)

(d)

0 0 2

(e)
2 1

0 0 2 3 2 1 5 4 5 4

(f)
2 1

0 0 2 3 2 1 3 4 5 4

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

80

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

81

Algoritmo de Prim - Implementao


{ Entram aqui os operadores de uma das implementaes para grafos } { bem como o operador Constroi do TAD HEAP } procedure AgmPrim ( var Grafo : TipoGrafo ; var Raiz : TipoValorVertice ) ; var Antecessor : array [ TipoValorVertice ] of integer ; p Pos A u, v : array [ TipoValorVertice ] of TipoPeso; : array [ TipoValorVertice ] of TipoValorVertice ; : Vetor ; : TipovalorVertice ; Itensheap : array [ TipoValorVertice ] of boolean ;

Algoritmo de Prim - Implementao


function RetiraMin ( var A: Vetor ) : Item ; begin if n < 1 then writeln ( Erro : heap vazio ) else begin RetiraMin : = A[ 1 ] ; A[ 1 ] : = A[n ] ; n : = n 1; Refaz ( 1 , n, A) ; end; end ; { Retira } procedure DiminuiChave ( i : Indice ; ChaveNova: TipoPeso ; var A: Vetor ) ; var x : Item ; begin i f ChaveNova > p[A[ i ] .Chave] then writeln ( Erro : ChaveNova maior que a chave atual ) else begin p[A[ i ] .Chave] : = ChaveNova; while ( i >1) and (p[A[ i div 2 ] .Chave] > p[A[ i ] .Chave] ) do begin x : = A[ i div 2 ] ; A[ i div 2 ] : = A[ i ] ; i : = i div 2; end; end; end ; { DiminuiChave } Pos[A[ i ] .Chave] : = i div 2; A[ i ] : = x ; Pos[ x .Chave] : = i ; Pos[A[n ] . chave] : = 1 ;

procedure Refaz (Esq, Dir : Indice ; var A : Vetor ) ; label 999; var i : Indice ; begin i : = Esq; begin i f j < Dir then i f p[A[ j ] .Chave] > p[A[ j + 1].Chave] then j : = j + 1; i f p[ x .Chave] <= p[A[ j ] .Chave] then goto 999; A[ i ] : = A[ j ] ; i := j ; end; 999 : A[ i ] : = x ; Pos[ x .Chave] : = i ; end ; { Refaz } Pos[A[ j ] .Chave] : = i ; j := 2 i ; j := 2 i ; x : = A[ i ] ; while j <= Dir do j : integer ; x : Item ;

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

82

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.2

83

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 ; A[u+1].Chave : = u ; {Heap a ser construido } 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 ) ; 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 } FimListaAdj : = false ;

Algoritmo de Prim - Implementao


Para realizar de forma eciente a seleo de uma nova aresta, todos os vrtices que no esto na AGM residem no heap A. O heap contm os vrtices, mas a condio do heap mantida pelo peso da aresta atravs do arranjo p[v ] (heap indireto). 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. Quando o algoritmo termina, A est vazia e a AGM est de forma implcita como S = {(v, Antecessor [v ]) : v V {Raiz }}

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

Algoritmo de Prim - Anlise


O corpo do anel while executado |V | vezes. 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 |). O while mais interno para percorrer a lista de adjacentes O(|A|) (soma dos comprimentos de todas as listas de adjacncia 2|A|). O teste para vericar 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 |). Logo, o tempo total para executar o algoritmo de Prim O(|V log |V | + |A| log |V |) = O(|A| log |V |).

AGM - Algoritmo de Kruskal


Pode ser derivado do algoritmo genrico. S uma oresta e a aresta segura adicionada a S sempre uma aresta de menor peso que conecta dois componentes distintos. Considera as arestas ordenadas pelo peso.
(a)
6 1 5 4 2 6 3 0 1 2 4 5 4 4 5 2 5 3 1 2

(b)
0 3

(c)
0 1 2 4 5 3

(d)
0 1 2 4 5 3

(e)
0 1 2 4 5 3

(f)
0 1 2 4 5 3

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3

86

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3

87

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 oresta uma aresta de menor peso. Obtm uma AGM adicionando uma aresta de cada vez oresta e, a cada passo, usa a aresta de menor peso que no forma ciclo. Inicia com uma oresta de |V | rvores de um vrtice: em |V | passos, une duas rvores at que exista apenas uma rvore na oresta.

Algoritmo de Kruskal - Implementao


Usa la 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 eciente de vericar 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.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3

88

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.7.3

89

Algoritmo de Kruskal - Implementao


Primeiro renamento:
procedure Kruskal ; 1. 2. 3. 4. 5. 6. 7. end; S := ; for v := 0 to Grafo.NumVertices1 do CriaConjunto ( v ) ; Ordena as arestas de A pelo peso; for cada ( u, v ) de A tomadas em ordem ascendente de peso do i f EncontreConjunto (u) <> EncontreConjunto ( v) then begin S := S + { (u, v) } ; Uniao ( u, v ) ; end;

AGM - Anlise do Algoritmo de Kruskal


A inicializao do conjunto S tem custo O(1). Ordenar arestas (linha 3) custa O(|A| log |A|). A linha 2 realiza |V | operaes CriaConjunto. 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). Como G conectado temos que |A| |V | 1, e assim as operaes sobre conjuntos disjuntos custam O(|A|(|V |). 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 |).

A implementao das operaes Unio e EncontraConjunto deve ser realizada de forma eciente. Esse problema conhecido na literatura como Unio-EncontraConjunto.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

90

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

91

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) = Caminho mais curto: (u, v ) =

k i=1

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.

p(vi1 , vi )

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

92

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

93

Caminhos Mais Curtos


A representao de caminhos mais curtos pode ser realizada pela varivel Antecessor. Para cada vrtice v V o Antecessor [v ] um outro vrtice u V ou nil (-1). 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. Dado um vrtice v no qual Antecessor [v ] = 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 nal do processamento, Antecessor contm uma rvore de caminhos mais curtos denidos em termos dos pesos de cada aresta de G, ao invs do nmero de arestas. Caminhos mais curtos no so necessariamente nicos.

rvore de caminhos mais curtos


Uma rvore de caminhos mais curtos com raiz em u V um subgrafo direcionado G = (V , A ), onde V V e A A, tal que: 1. V o conjunto de vrtices alcanveis a partir de s G, 2. G forma uma rvore de raiz s, 3. para todos os vrtices v V , o caminho simples de s at v um caminho mais curto de s at v em G.

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

94

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

95

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 ] = n il para todo vrtice v V, p[u] = 0, para o vrtice origem s, e p[v ] = para v V {s}.

Relaxamento
O relaxamento de uma aresta (u, v ) consiste em vericar 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

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

96

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

97

Algoritmo de Dijkstra - 1o Renamento


procedure Dijkstra ( Grafo , Raiz ) ; 1. 2. 3. 4. 5. 6 7. 8. 9 10. 11. 12. 13. for v := 0 to Grafo.NumVertices1 do p[ v ] : = I n f i n i t o ; Antecessor[ v] := 1; p[Raiz ] : = 0 ; Constroi heap no vetor A; S := ; While heap > 1 do u : = RetiraMin(A) ; S := S + u for v ListaAdjacentes [u ] do i f p[ v] > p[u] + peso da aresta ( u, v) then p[ v ] = p[u] + peso da aresta ( u, v) Antecessor[ v ] : = u

Algoritmo de Dijkstra - Exemplo


(a)
1 1 5 2 1 2 3 0 3 10 4 6

(b)
1 1 1 5 2 1

0 0 3 10 4 6 2 3 3 10

(c)
1 1 5 1 2 6 1

0 0 3 10 4 6 2 3 3 10

Invariante: o nmero de elementos do heap igual a V S no incio do anel while. A cada iterao do while, um vrtice u extrado do heap e adicionado ao conjunto S , mantendo assim o invariante. RetiraMin obtm o vrtice u com o caminho mais curto estimado at o momento e adiciona ao conjunto S . No anel da linha 10, a operao de relaxamento realizada sobre cada aresta (u, v ) adjacente ao vrtice u.
Iterao (a) (b) (c) S {0} {0, 1}

d[0] 0 0

d[1] 1 1

d[2] 6

d[3] 3 3

d[4] 10 10

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

98

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

99

Algoritmo de Dijkstra - Exemplo


(d)
1 1 5 2 5 1 2 3 1 0 0 3 10 4 6 3 0 1 1 5 2 5 1 2 3 0 3 10 4 6 3 6 9

Algoritmo de Dijkstra
Para realizar de forma eciente 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. Para cada vrtice v , p[v ] o caminho mais curto obtido at o momento, de v at o vrtice raiz. 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.

(e)
1 1 5 2 5 1 1

0 0 3 10 4 6 2 3 3 6

(f)
1

Iterao (d) (e) (f)

S {0, 1, 3} {0, 1, 3, 2} {0, 1, 3, 2, 4}

d[0] 0 0 0

d[1] 1 1 1

d[2] 5 5 5

d[3] 3 3 3

d[4] 9 6 6

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.

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


procedure Dijkstra ( var Grafo : TipoGrafo ; var Raiz : TipoValorVertice ) ; var Antecessor : array [ TipoValorVertice ] of integer ; P Pos A u, v : array [ TipoValorVertice ] of TipoPeso; : array [ TipoValorVertice ] of TipoValorVertice ; : Vetor ; : TipovalorVertice ;

Algoritmo de Dijkstra - Implementao


. . . while n >= 1 do {enquanto heap nao vazio} begin u : = RetiraMinInd(A) .Chave; ItensHeap[u] : = false ; i f not ListaAdjVazia (u,Grafo) then begin Aux : = PrimeiroListaAdj (u,Grafo ) ; while not FimListaAdj do begin ProxAdj(u, Grafo , v , Peso, Aux, FimListaAdj ) ; i f p[ v] > p[u] + Peso then begin p[ v ] : = p[u] + Peso; Antecessor[ v ] : = u; DiminuiChaveInd(Pos[ v ] ,p[ v ] ,A) ; write ( Caminho: v [ ,v, ] v [ ,Antecessor[ v ] , ] , d[ ,p[ v ] , ] ) ; readln ; end; end; end; end; end ; { Dijkstra } FimListaAdj : = false ;

Itensheap : array [ TipoValorVertice ] of boolean ;

{ Entram aqui os operadores de uma das implementaes de grafos, bem como o operador Constroi da implementao de las de prioridades, assim como os operadores RefazInd, RetiraMinInd e DiminuiChaveInd do Programa Constroi } begin { Dijkstra } 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 ; A[u+1].Chave : = u ; {Heap a ser construido } ItensHeap[u] : = true ; Pos[u] : = u+1; end; n : = Grafo.NumVertices ; {Tamanho do heap} p[Raiz ] : = 0 ; Constroi(A) ; . . .

Projeto de Algoritmos Cap.7 Algoritmos em Grafos Seo 7.8

102

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] = (R aiz, u).