A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Análise e Síntese de Algoritmos

Apresentações semelhantes


Apresentação em tema: "Análise e Síntese de Algoritmos"— Transcrição da apresentação:

1 Análise e Síntese de Algoritmos
Caminhos Mais Curtos CLRS, Cap. 24

2 Análise e Síntese de Algoritmos
Contexto Algoritmos elementares em grafos Grafos não dirigidos: Árvores abrangentes de menor custo Grafos dirigidos: Caminhos mais curtos Fonte única Entre todos os pares Redes de fluxo (grafos dirigidos com arcos capacitados) Fluxos máximos Fluxos de custo mínimo 2003/2004 Análise e Síntese de Algoritmos

3 Análise e Síntese de Algoritmos
Resumo Caminhos Mais Curtos Definições Caminhos Mais Curtos com Fonte Única (SSSPs) Propriedades Relaxações Algoritmo de Dijkstra Algoritmo de Bellman-Ford SSSPs em DAGs 2003/2004 Análise e Síntese de Algoritmos

4 Análise e Síntese de Algoritmos
Caminhos Mais Curtos Dado um grafo G = (V, E), dirigido, com uma função de pesos w : E  R, define-se o peso de um caminho p, p = v0,v1,…,vk, como a soma dos pesos dos arcos que compõem p: O peso do caminho mais curto de u para v é definido por: Um caminho mais curto de u para v é qualquer caminho p tal que w(p) = (u,v) 2003/2004 Análise e Síntese de Algoritmos

5 Problemas de Caminhos Mais Curtos
Caminhos Mais Curtos com Fonte Única (SSSPs) Identificar o caminho mais curto de um vértice fonte s  V para qualquer outro vértice v  V Caminhos Mais Curtos com Destino Único Identificar o caminho mais curto de qualquer vértice v  V para um vértice destino t  V Caminho Mais Curto entre Par Único Identificar caminho mais curto entre dois vértices u e v Caminhos Mais Curtos entre Todos os Pares (APSPs) Identificar um caminho mais curto entre cada par de vértices de V 2003/2004 Análise e Síntese de Algoritmos

6 Análise e Síntese de Algoritmos
Ciclos Negativos Arcos podem ter pesos com valor negativo É possível a existência de ciclos com peso total negativo Se ciclo negativo não atingível a partir da fonte s  (s,v) bem definido Se ciclo negativo atingível a partir da fonte s pesos dos caminhos mais curtos não são bem definidos é sempre possível encontrar um caminho mais curto de s para qualquer vértice incluído no ciclo define-se (s,v) = - 2003/2004 Análise e Síntese de Algoritmos

7 Ciclos Negativos (Cont.)
Identificação de ciclos negativos: Alguns algoritmos requerem pesos não negativos Dijkstra Alguns algoritmos identificam ciclos negativos e reportam a sua existência Bellman-Ford Exemplo: 3 -5 -2 s z x y w(s,x,y,z) = 4 w(s,x,y,x,y,z) = 2 w(s,x,y,x,y,x,y,z) = 0 2003/2004 Análise e Síntese de Algoritmos

8 Representação de Caminhos Mais Curtos
Para cada vértice v  V associar predecessor [v] Após identificação dos caminhos mais curtos, [v] identifica vértice anterior a v em caminho mais curto de s para v Sub-grafo de predecessores G = (V, E): 2003/2004 Análise e Síntese de Algoritmos

9 Representação de Caminhos Mais Curtos (Cont.)
Uma árvore de caminhos mais curtos é um sub-grafo dirigido G’ = (V’, E’), V’  V e E’  E, tal que: V’ é o conjunto de vértices atingíveis a partir de s em G G’ forma uma árvore com raiz s Para todo o v  V’, o único caminho de s para v em G’ é um caminho mais curto de s para v em G OBS: Após identificação dos caminhos mais curtos de G, G’ é dado por G = (V, E) OBS: Dado G = (V, E), G’ não é necessariamente único 2003/2004 Análise e Síntese de Algoritmos

10 Análise e Síntese de Algoritmos
Estudo dos SSSPs Sub-estrutura óptima: (sub-caminhos de caminhos mais curtos são caminhos mais curtos) Seja p = v1,v2,…,vk um caminho mais curto entre v1 e vk, e seja pij = vi,vi+1,…,vj um sub-caminho de p entre vi e vj. Então pij é um caminho mais curto entre vi e vj Se existisse caminho mais curto entre vi e vj então seria possível construir caminho entre v1 e vk mais curto do que p; uma contradição ! 24.1 2003/2004 Análise e Síntese de Algoritmos

11 Análise e Síntese de Algoritmos
Estudo dos SSSPs Seja p = s,…,v um caminho mais curto entre s e v, que pode ser decomposto em p’ = s,…,u e (u,v). Então (s,v) = (s,u) + w(u,v) p’ é caminho mais curto entre s e u (s,v) = w(p) = w(p’) + w(u,v) = (s,u) + w(u,v) Para todos os arcos (u,v)  E verifica-se (s,v)  (s,u) + w(u,v) Caminho mais curto de s para v não pode ter mais peso do que qualquer outro caminho de s para v Assim, peso do caminho mais curto de s para v não superior ao peso do caminho mais curto de s para u seguido do arco (u,v) (i.e. exemplo de um dos caminhos de s para v) 24.1 24.10 2003/2004 Análise e Síntese de Algoritmos

12 Estudo dos SSSPs (Cont.)
Relaxação: Algoritmos para SSSPs utilizam relaxação d[v]: limite superior no valor do peso do caminho mais curto entre s e v; estimativa do caminho mais curto Algoritmos para SSSPs aplicam sequência de relaxações dos arcos de G após inicialização Initialize-Single-Source(G,s) for v  V[G] d[v] =  [v] = NIL d[s] = 0 Relax(u,v,w) if d[v] > d[u] + w(u,v) d[v] = d[u] + w(u,v) [v] = u 2003/2004 Análise e Síntese de Algoritmos

13 Estudo dos SSSPs (Cont.)
Propriedades da relaxação: Após relaxar arco (u,v), d[v]  d[u] + w(u,v) Se d[v] > d[u] + w(u,v) antes da relaxação, então d[v] = d[u] + w(u,v) após relaxação Se d[v]  d[u] + w(u,v) antes da relaxação, então d[v]  d[u] + w(u,v) após relaxação Em qualquer caso, d[v]  d[u] + w(u,v) após relaxação 24.13 2003/2004 Análise e Síntese de Algoritmos

14 Estudo dos SSSPs (Cont.)
Propriedades da relaxação: d[v]  (s, v) para qualquer v  V e para qualquer sequência de passos de relaxação nos arcos de G. Se d[v] atinge o valor (s,v) então o valor não é mais alterado d[v]  (s, v) é válido após inicialização Prova por contradição. Seja v o primeiro vértice para o qual a relaxação do arco (u,v) causa d[v] < (s, v) Após relaxar arco: d[u] + w(u,v) = d[v] < (s, v)  (s, u) + w(u,v) Pelo que, d[u] < (s, u) antes da relaxação de (u,v); contradição ! Após ter d[v] = (s, v), o valor de d[v] não pode decrescer; e pela relaxação também não pode crescer ! 24.11 24.10 2003/2004 Análise e Síntese de Algoritmos

15 Estudo dos SSSPs (Cont.)
Propriedades da relaxação: Seja p = s,…,u,v um caminho mais curto em G, e seja Relax(u,v,w) executada no arco (u,v). Se d[u] = (s, u) antes da chamada a Relax(u,v,w), então d[v] = (s, v) após a chamada a Relax(u,v,w) Se d[u] = (s, u) então valor de d[u] não é mais alterado Após relaxar arco (u,v): d[v]  d[u] + w(u,v) = (s, u) + w(u,v) = (s, v) Mas, d[v]  (s, v), pelo que d[v] = (s, v), e não se altera ! 24.14 24.1 24.11 2003/2004 Análise e Síntese de Algoritmos

16 Estudo dos SSSPs (Revisão)
Seja p = v1,v2,…,vk um caminho mais curto entre v1 e vk, e seja pij = vi,vi+1,…,vj um sub-caminho de p entre vi e vj. Então pij é um caminho mais curto entre vi e vj Seja p = s,…,v um caminho mais curto entre s e v, que pode ser decomposto em p’ = s,…,u e (u,v). Então (s,v) = (s,u) + w(u,v) Para todos os arcos (u,v)  E verifica-se (s,v)  (s,u) + w(u,v) 24.1 24.10 2003/2004 Análise e Síntese de Algoritmos

17 Estudo dos SSSPs (Revisão)
Propriedades da relaxação: Após relaxar arco (u,v), d[v]  d[u] + w(u,v) d[v]  (s, v) para qualquer v  V e para qualquer sequência de passos de relaxação nos arcos de G. Se d[v] atinge o valor (s,v) então o valor não é mais alterado Seja p = s,…,u,v uma caminho mais curto em G, e seja Relax(u,v,w) executada no arco (u,v). Se d[u] = (s, u) antes da chamada a Relax(u,v,w), então d[v] = (s, v) após a chamada a Relax(u,v,w) 24.13 24.11 24.14 2003/2004 Análise e Síntese de Algoritmos

18 Algoritmo de Dijkstra — Organização
Todos os arcos com pesos não negativos Algoritmo Greedy Algoritmo mantém conjunto de vértices S com pesos dos caminhos mais curtos já calculados A cada passo algoritmo selecciona vértice u em V - S com menor estimativa do peso do caminho mais curto vértice u é inserido em S arcos que saem de u são relaxados Fila de prioridade Q é mantida e actualizada com operações de relaxação 2003/2004 Análise e Síntese de Algoritmos

19 Algoritmo de Dijkstra — Pseudo-Código
Exemplo Dijkstra(G,w,s) Initialize-Single-Source(G,s) S =  Q = V[G] // Fila de prioridade Q while Q   u = Extract_Min(Q) S = S  {u} foreach v  Adj[u] Relax(u,v,w) // Actualizar Q O(lg V) O(E) O(V) 2003/2004 Análise e Síntese de Algoritmos

20 Algoritmo de Dijkstra vs. Alg. de Prim
MST-Prim(G,w,r) Q = V[G] // Fila de prioridade Q foreach u  Q // Inicialização key[u] =  key[r] = 0 [r] = NIL while Q   u = Extract_Min(Q) foreach v  Adj[u] if v  Q and w(u,v) < key[v] [v] =u key[v] = w(u,v) // Q é actualizada! 2003/2004 Análise e Síntese de Algoritmos

21 Algoritmo de Dijkstra — Complexidade
Extract-Min e actualização de chaves na fila de prioridade O(lg V) cada operação, em amontoado binário (binary heap) Extract-Min executado O(V) vezes Número de vezes que chaves são actualizadas é O(E) OBS: cada arco é analisado apenas uma vez, independentemente do ciclo while exterior, e não causa mais do que uma actualização do amontoado ! Tempo de execução é: O((V+E) lg V) Se fila de prioridade utiliza um amontoado binário 2003/2004 Análise e Síntese de Algoritmos

22 Algoritmo de Dijkstra — Correcção
Como resultado da aplicação do algoritmo de Dijkstra, d[u] = (s,u) para u  V[G] Provar que d[u] = (s,u) quando u adicionado ao conjunto S, e que a igualdade é posteriormente mantida Prova por contradição. Seja u o primeiro vértice tal que quando u é adicionado ao conjunto S, d[u]  (s,u) u  s, porque d[s] = (s,s) = 0 s  S, pelo que S   quando u adicionado a S Existe caminho de s para u (caso contrário, d[u] = (s,u) = ; uma contradição) existe caminho mais curto p de s para u y: primeiro vértice de p em V-S x: predecessor de y, último vértice de p em S 24.6 2003/2004 Análise e Síntese de Algoritmos

23 Algoritmo de Dijkstra — Correcção
Quando u é adicionado a S, d[y] = (s,y) x pertence a S d[x] = (s,x) (porque u é o primeiro vértice para o qual igualdade não se verifica) Quando x adicionado a S, relaxação causa d[y] = (s,y), porque caminho mais curto para y passa por x y aparece antes de u num caminho mais curto, pelo que (s,y)  (s,u) (pesos não negativos) d[y] = (s,y)  (s,u)  d[u] Mas y e u em V-S, e u escolhido antes de y, pelo que d[u]  d[y]  d[y] = (s,y) = (s,u) = d[u], o que contradiz escolha de u ! Necessariamente, valor de d[u] mantém-se após d[u] = (s,u) 24.14 24.11 24.11 2003/2004 Análise e Síntese de Algoritmos

24 Algoritmo de Dijkstra — Condições
Pesos dos arcos têm que ser não negativos: Execução do algoritmo de Dijkstra: Analisar w (com d[w] = 3) Analisar v (com d[v] = 4) Analisar u (com d[u] = 6) Corrigir d[v] para 1 Estimativa de w incorrecta (final=3; correcto=2) ! 6 3 -5 s v u w 1 2003/2004 Análise e Síntese de Algoritmos

25 Algoritmo de Bellman-Ford — Organização
Permite pesos negativos e identifica existência de ciclos negativos Baseado em sequência de passos de relaxação Apenas requer manutenção da estimativa associada a cada vértice 2003/2004 Análise e Síntese de Algoritmos

26 Algoritmo de Bellman-Ford — Pseudo-Código
Exemplo Bellman-Ford(G,w,s) Initialize-Single-Source(G,s) for i = 1 to |V[G]|-1 foreach (u,v)  E[G] Relax(u,v,w) if d[v] > d[u] + w(u,v) // Ciclo negativo return FALSE // Sem ciclos negativos return TRUE (V E) 2003/2004 Análise e Síntese de Algoritmos

27 Algoritmo de Bellman-Ford — Complexidade
Por inspecção: Inicialização: (V) Ciclo for: Tempo de execução é (VE) devido aos dois ciclos, em V e em E OBS: para cada i, todos os arcos de E são relaxados ! 2003/2004 Análise e Síntese de Algoritmos

28 Algoritmo de Bellman-Ford — Correcção
Se G = (V,E) não contém ciclos negativos, então após a aplicação do algoritmo de Bellman-Ford, d[v] = (s,v) para todos os vértices atingíveis a partir de s Seja v atingível a partir de s, e seja p = vo,v1,…,vk um caminho mais curto entre s e v, com v0 = s e vk = v p é simples, pelo que k  |V|-1 Objectivo: provar por indução que para i = 0,1,…,k, d[vi] = (s,vi) após iteração i sobre os arcos de G, e que valor não é alterado posteriormente Base: d[v0] = (s,v0) = 0 após inicialização (e não se altera) Passo indutivo: assumir d[vi-1] = (s,vi-1) após iteração (i-1) Arco (vi-1,vi) relaxado na iteração i, pelo que d[vi] = (s,vi) após iteração i (ver propriedades da relaxação) (e não se altera) 24.2 24.11 24.14 2003/2004 Análise e Síntese de Algoritmos

29 Algoritmo de Bellman-Ford — Correcção
Se G=(V,E) não contém ciclos negativos, o algoritmo de Bellman-Ford retorna TRUE. Se o grafo contém algum ciclo negativo atingível a partir de s, o algoritmo retorna FALSE Sem ciclos negativos, resultado anterior assegura que para qualquer arco (u,v) de E, d[v]  d[u] + w(u,v), pelo que teste do algoritmo falha para todo o (u,v) e o valor retornado é TRUE Na presença de pelo menos um ciclo negativo atingível a partir de s, c = vo,v1,…,vk, onde vo = vk Prova por contradição. Admitir que algoritmo retorna TRUE Pelo que d[vi]  d[vi-1] + w(vi-1,vi), para i =1,…,k 24.4 2003/2004 Análise e Síntese de Algoritmos

30 Algoritmo de Bellman-Ford — Correcção
Somando desigualdades através do ciclo c: Nota: Obtendo-se: O que contradiz a hipótese de existência de um ciclo negativo  algoritmo retorna FALSE. Por ser um ciclo ! 2003/2004 Análise e Síntese de Algoritmos

31 Algoritmos de Dijkstra e Bellman-Ford
Só permite pesos não negativos Tempo de execuçao é O((V + E) lg V) Bellman-Ford Permite pesos negativos e identifica ciclos negativos Tempo de execução é (V E) 2003/2004 Análise e Síntese de Algoritmos

32 SSSPs em DAGs — Organização
Tempo de execução: O(V+E) Exemplo DAG-Shortest-Paths(G,w,s) Ordenação topológica dos vértices de G Initialize-Single-Source(G,s) foreach u  V[G] por ordem topológica foreach v  Adj[u] Relax(u,v,w) 2003/2004 Análise e Síntese de Algoritmos

33 SSSPs em DAGs — Correcção
Dado G = (V, E),dirigido, acíclico, como resultado do algoritmo, d[v] = (s,v) para todo o v  V Se v não atíngivel de s, então d[v] = (s,v) =  Seja p = v0,v1,,vk um caminho mais curto, com v0 = s e vk = v Ordem topológica implica arcos analisados por ordem (v0, v1), (v1, v2), …, (vk-1, vk) Cada arco é relaxado apenas uma vez Valor de d[v] não é alterado após d[v] = (s,v) Por indução, d[vi] = (s,vi) sempre que cada vértice vi é terminado Base: Estimativa de s não alterada; d[s] = d[v0] = (s,v0) = 0 Indução: d[vi-1] = (s,vi-1) após terminar análise de vi-1 Relaxação de (vi-1, vi) causa d[vi] = (s,vi), pelo que d[vi] = (s,vi) após terminar análise de vi 24.5 24.11 24.14 2003/2004 Análise e Síntese de Algoritmos

34 Análise e Síntese de Algoritmos
Revisão Caminhos Mais Curtos com Fonte Única (SSSPs) Definições e Propriedades Algoritmo de Dijkstra Algoritmo de Bellman-Ford SSSPs em DAGs A seguir: Caminhos Mais Curtos entre Todos os Pares (CLRS, Cap. 25) 2003/2004 Análise e Síntese de Algoritmos


Carregar ppt "Análise e Síntese de Algoritmos"

Apresentações semelhantes


Anúncios Google