Escolar Documentos
Profissional Documentos
Cultura Documentos
Grafos PDF
Grafos PDF
7 Algoritmos em Grafos 1
Motivação
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos 2 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 3
• Um grafo direcionado G é um par (V, A), onde • Um grafo não direcionado G é um par (V, A),
V é um conjunto finito de vértices e A é uma onde o conjunto de arestas A é constituído de
relação binária em V . pares de vértices não ordenados.
– Uma aresta (u, v) sai do vértice u e entra – As arestas (u, v) e (v, u) são consideradas
no vértice v. O vértice v é adjacente ao como uma única aresta. A relação de
vértice u. adjacência é simétrica.
– Podem existir arestas de um vértice para – Self-loops não são permitidos.
ele mesmo, chamadas de self-loops.
0 1 4
0 1 4
3 2 5
3 2 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 6 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 7
3 2 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 8 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 9
Ciclos Ciclos
0 1 4
3 2 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 10 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 11
0 1 4
3 2 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 12 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 13
3 2 0 1 4
s w x t 3 2 5
v z y u 1 4
2 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 14 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 15
• Cada aresta não direcionada (u, v) em G é • A versão não direcionada contém as arestas
substituída por duas arestas direcionadas de G sem a direção e sem os self-loops.
(u, v) e (v, u)
• Em um grafo não direcionado, u e v são
• Em um grafo direcionado, um vizinho de um vizinhos se eles são adjacentes.
vértice u é qualquer vértice adjacente a u na
0 1 4 0 1 4
versão não direcionada de G.
0 1 0 1
3 2 5 3 2 5
2 2
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 16 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 17
• Hipergrafo: grafo não direcionado em que • O número total de grafos diferentes com |V |
cada aresta conecta um número arbitrário de vértices é 2|V |(|V |−1)/2 (número de maneiras
vértices. diferentes de escolher um subconjunto a
partir de |V |(|V | − 1)/2 possíveis arestas).
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 18 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2 19
(a) (b)
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2 20 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2 21
8. GrafoTransposto(Grafo,GrafoT): Obtém o
transposto de um grafo direcionado.
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2 22 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.1 23
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.1 26 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.1 27
• A inserção de um novo vértice ou retirada de procedure InsereAresta ( var V1, V2: TipoValorVertice ;
var Peso : TipoPeso;
um vértice já existente pode ser realizada var Grafo : TipoGrafo ) ;
com custo constante. begin
Grafo.Mat[V1, V2] : = peso;
const MaxNumVertices = 100; end;
MaxNumArestas = 4500;
type function ExisteAresta ( Vertice1 , Vertice2 : TipoValorVertice ;
TipoValorVertice = 0..MaxNumVertices; var Grafo : TipoGrafo ) : boolean;
TipoPeso = integer ; begin
TipoGrafo = record 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; var Grafo : TipoGrafo ) : boolean;
Apontador = TipoValorVertice ; 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 i f Grafo.Mat[ Vertice , Aux] > 0
for i := 0 to Grafo.NumVertices do then ListaVazia : = false
for j := 0 to Grafo.NumVertices do Grafo.mat[ i , j ] : = 0 ; else Aux : = Aux + 1;
end; ListaAdjVazia : = ListaVazia = true ;
end; { ListaAdjVazia }
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.1 28 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.1 29
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.2 30 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.2 31
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.2 34 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.2 35
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.3 38 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.3 39
{−−Operador para obter a l i s t a de adjacentes−−} procedure RetiraAresta ( var V1, V2: TipoValorVertice ;
function ListaAdjVazia (var Vertice : TipoValorVertice ; var Peso: TipoPeso ; var Grafo : TipoGrafo ) ;
var Grafo : TipoGrafo ) : boolean; var Aux, AuxAnterior : Apontador ; EncontrouAresta : boolean;
begin begin
ListaAdjVazia : = Grafo.Prox[ Vertice ] = 0; AuxAnterior : = V1; Aux : = Grafo.Prox[V1] ;
end; { ListaAdjVazia } EncontrouAresta : = false ;
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+2∗MaxNumArestas
{−−Apenas marca como retirado −−}
{−−Operador para obter a l i s t a de adjacentes−−}
else writeln ( ’Aresta nao existe ’ ) ;
procedure ProxAdj ( var Vertice : TipoValorVertice ;
end; { RetiraAresta }
var Grafo : TipoGrafo;
var Adj : TipoValorVertice ;
procedure LiberaGrafo ( var Grafo : TipoGrafo ) ;
var Peso : TipoPeso;
begin {Nada no caso de posicoes contiguas} end; { LiberaGrafo }
var Prox : Apontador;
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 ( ’ Cab Prox Peso ’ ) ;
Prox : = Grafo.Prox[Prox ] ; for i := 0 to Grafo.NumVertices+2∗Grafo.NumArestas−1 do
i f Prox = 0 then FimListaAdj : = true ; writeln ( i :2 ,Grafo.Cab[ i ]:4 ,Grafo.Prox[ i ] : 4 , Grafo.Peso[ i ] : 4 ) ;
end; { ProxAdj− } end; { ImprimeGrafo }
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.3 42 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.3 43
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.3 46 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.3 47
b( / ) b( / ) b( / ) b( / )
b( / ) 2 3 b( / ) 2 3
p(3/4) 2 3 p(3/4) 2 3
b( / ) b( / ) c(7/ ) p(7/8)
b( / ) 2 3 c(3/ ) 2 3
p(3/4) 2 3 p(3/4) 2 3
c(1/ ) c(2/ )
0 1
b( / )
p(3/4) 2 3
(e)
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.3 48 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.3.1 49
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.3.1 50 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.3.2 51
• Classificação de arestas pode ser útil para • A busca em profundidade pode ser usada
derivar outros algoritmos. para verificar se um grafo é acíclico ou
contém um ou mais ciclos.
• Na busca em profundidade cada aresta pode
ser classificada pela cor do vértice que é • Se uma aresta de retorno é encontrada
alcançado pela primeira vez: durante a busca em profundidade em G,
– Branco indica uma aresta de árvore. então o grafo tem ciclo.
3 cruz 4 cruz 5
4/5 7/8 11/12
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.4 52 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.4 53
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.4 54 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.4 55
{−− Entram aqui os operadores FFVazia, Vazia, Enfileira e Desenfileira do−−} procedure VisitaBfs (u: TipoValorVertice ) ;
{−− TAD Filas com arranjos ou apontadores, dependendo da implementação−−} var v : TipoValorVertice ; Aux: Apontador ; FimListaAdj : boolean;
{−− da busca em largura usar arranjos ou apontadores, respectivamente−−} Peso: TipoPeso ; Item : TipoItem ; Fila : TipoFila ;
procedure BuscaEmLargura ( var Grafo : TipoGrafo ) ; begin
var x : TipoValorVertice ; Cor[u] : = cinza ; Dist [u] : = 0 ;
Dist : array [ TipoValorVertice ] of integer ; FFVazia ( Fila ) ; Item . Vertice : = u;
Cor : array [ TipoValorVertice ] of TipoCor; Enfileira ( Item , Fila ) ;
write( ’ Visita origem ’ ,u:2 , ’ cor : cinza F: ’ ) ;
Antecessor : array [ TipoValorVertice ] of integer ;
ImprimeFila ( Fila ) ; readln;
while not FilaVazia ( Fila ) do
{−−−Entra aqui o procedimento VisitaBfs (a seguir)−−−}
begin
Desenfileira ( Fila , Item ) ; u : = Item . vertice ;
begin
i f not ListaAdjVazia (u, Grafo)
for x := 0 to Grafo.NumVertices−1 do
then begin
begin
Aux : = PrimeiroListaAdj (u,Grafo ) ; FimListaAdj : = false ;
Cor[ x ] : = branco ; Dist [ x ] : = i n f i n i t o ; Antecessor[ x] := −1;
while FimListaAdj = false do
end;
begin
for x := 0 to Grafo.NumVertices−1 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 }
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.4 56 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.4 57
3 2 5 3 2 5 3 2 5 3 2 5
b( ) b( ) b( ) c(1) b( ) b( ) p(1) p(2) b( ) p(1) p(2) b( )
F 0 F 1 3
F F 4
0 1 1
0
3 2 5 3 2 5 3 2 5 3 2 5
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 F 2 F
F 5
1 2 2
1
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.4 58 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.4 59
• Ordenação linear de todos os vértices, tal que • Os grafos direcionados acíclicos são usados
se G contém uma aresta (u, v) então u para indicar precedências entre eventos.
aparece antes de v.
• Uma aresta direcionada (u, v) indica que a
• Pode ser vista como uma ordenação de seus atividade u tem que ser realizada antes da
vértices ao longo de uma linha horizontal de atividade v.
tal forma que todas as arestas estão
direcionadas da esquerda para a direita. 1/18 16/17 19/20
0 5 9
• Pode ser feita usando a busca em 2/15 7/12
profundidade. 4/5 3 1 6 8 9/10
2 4 7
3/14 6/13 8/11
9 0 5 1 2 4 6 7 8 3
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.5 62 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.5 63
3 2 3 2 3
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.6 66 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.6 67
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.6 70 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.6 71
• Modelagem:
– G = (V, A): grafo conectado, não
direcionado.
– V : conjunto de cidades.
– A: conjunto de possíveis conexões
– p(u, v): peso da aresta (u, v) ∈ A, custo
total de cabo para conectar u a v.
minimizado.
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7 74 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.1 75
• Como G0 = (V, T ) é acíclico e conecta todos • Uma estratégia gulosa permite obter a AGM
os vértices, T forma uma árvore chamada adicionando uma aresta de cada vez.
árvore geradora de G.
• Invariante: Antes de cada iteração, S é um
• O problema de obter a árvore T é conhecido subconjunto de uma árvore geradora mínima.
como árvore geradora mínima (AGM).
• A cada passo adicionamos a S uma aresta
Ex.: Árvore geradora mínima T cujo peso total é (u, v) que não viola o invariante. (u, v) é
12. T não é única, pode-se substituir a aresta chamada de uma aresta segura.
(3, 5) pela aresta (2, 5) obtendo outra árvore
procedure GenericoAGM;
geradora de custo 12. 1 S := ∅ ;
2 while S não constitui uma árvore geradora mínima do
0 0 3 Encontre uma aresta (u, v) que é segura para S ;
6 5
1 1 4 S := S + {(u, v)}
1 2 2 3 1 2 2 3 5 return S ;
2 2
5 6 4 4 4
4 5 4 5 • Dentro do while, S tem que ser um
3 3
subconjunto próprio da AGM T , e assim tem
(a) (b)
que existir uma aresta (u, v) ∈ T tal que
(u, v) 6∈ S e (u, v) é seguro para S.
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.1 76 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.1 77
• Uma aresta cruzando o corte que tenha custo • Seja (u, v) uma aresta leve cruzando
mínimo sobre todas as arestas cruzando o (V 0 , V − V 0 ).
corte é uma aresta leve.
• Satisfeitas essas condições, a aresta (u, v) é
p
0 uma aresta segura para S.
p 6 5 p
1
V’ 1 2 2 3 V’
2
V − V’ 5 4 V − V’
6 4
4 5
3
b b
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.2 78 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.2 79
GS = (V, S).
(e) 0 (f) 0
• De acordo com o teorema anterior, quando o 0 0
2 2 2 2
algoritmo termina, as arestas em S formam 1 3 1 3
uma árvore geradora mínima. 2 2
1 1
4 5 4 5
5 4 3 4
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.2 80 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.2 81
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.2 82 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.2 83
• O corpo do anel while é executado |V | vezes. • Pode ser derivado do algoritmo genérico.
• S é uma floresta e a aresta segura adicionada
• O procedimento Refaz tem custo O(log |V |).
a S é sempre uma aresta de menor peso que
• Logo, o tempo total para executar a operação conecta dois componentes distintos.
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 (a) (b)
adjacentes é O(|A|) (soma dos comprimentos 6
0
5
0
1
de todas as listas de adjacência é 2|A|). 1 2 2 3 1 3
2 2
5 4
• O teste para verificar se o vértice v pertence 6 4
4 5 4 5
ao heap A tem custo O(1). 3
antecessor de v é armazenado em 1 3 1 3
2 2
Antecessor e uma operação DiminuiChave é
realizada sobre o heap A na posição Pos[v], a 4 5 4 5
qual tem custo O(log |V |).
(e) (f)
• Logo, o tempo total para executar o algoritmo
0 0
de Prim é
1 3 1 3
O(|V log |V | + |A| log |V |) = O(|A| log |V |). 2 2
4 5 4 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.3 86 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.3 87
• Sejam C1 e C2 duas árvores conectadas por • Usa fila de prioridades para obter arestas em
(u, v): ordem crescente de pesos.
– Como (u, v) tem de ser uma aresta leve • Testa se uma dada aresta adicionada ao
conectando C1 com alguma outra árvore, conjunto solução S forma um ciclo.
(u, v) é uma aresta segura para C1 . • Tratar conjuntos disjuntos: maneira
• É guloso porque, a cada passo, ele adiciona à eficiente de verificar se uma dada aresta
forma um ciclo. Utiliza estruturas dinâmicas.
floresta uma aresta de menor peso.
• Os elementos de um conjunto são
• Obtém uma AGM adicionando uma aresta de
representados por um objeto. Operações:
cada vez à floresta e, a cada passo, usa a
– CriaConjunto(x): cria novo conjunto cujo
aresta de menor peso que não forma ciclo.
único membro, x, é seu representante.
• Inicia com uma floresta de |V | árvores de um Para que os conjuntos sejam disjuntos, x
vértice: em |V | passos, une duas árvores até não pode pertencer a outro conjunto.
que exista apenas uma árvore na floresta. – União(x, y): une conjuntos dinâmicos
contendo x (Cx ) e y (Cy ) em novo conjunto,
cujo representante pode ser x ou y. Como
os conjuntos na coleção devem ser
disjuntos, Cx e Cy são destruídos.
– EncontreConjunto(x): retorna apontador
para o representante do conjunto (único)
contendo x.
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.3 88 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.7.3 89
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.8 90 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.8 91
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.8 94 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.8 95
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.8 98 Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.8 99