0% acharam este documento útil (0 voto)
23 visualizações43 páginas

7 Caminho Minimo

O documento aborda o conceito de caminhos mínimos em dígrafos valorados, incluindo propriedades, algoritmos como o de Dijkstra e aplicações práticas. Ele descreve APIs para manipulação de arestas e implementação em Java, além de discutir variantes de problemas de caminhos mínimos e estruturas de dados associadas. O texto também menciona a importância do relaxamento de arestas na determinação de caminhos mais curtos.
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
0% acharam este documento útil (0 voto)
23 visualizações43 páginas

7 Caminho Minimo

O documento aborda o conceito de caminhos mínimos em dígrafos valorados, incluindo propriedades, algoritmos como o de Dijkstra e aplicações práticas. Ele descreve APIs para manipulação de arestas e implementação em Java, além de discutir variantes de problemas de caminhos mínimos e estruturas de dados associadas. O texto também menciona a importância do relaxamento de arestas na determinação de caminhos mais curtos.
Direitos autorais
© © All Rights Reserved
Levamos muito a sério os direitos de conteúdo. Se você suspeita que este conteúdo é seu, reivindique-o aqui.
Formatos disponíveis
Baixe no formato PDF, TXT ou leia on-line no Scribd
Você está na página 1/ 43

Algorithms R OBERT S EDGEWICK | K EVIN W AYNE

4.4 C AMINHOS M ÍNIMOS


‣ APIs
‣ Propriedades de caminhos mínimos
‣ Algoritmo de Dijkstra
Algorithms F O U R T H E D I T I O N
‣ DAGs valorados
‣ Pesos negativos
R OBERT S EDGEWICK | K EVIN W AYNE

http://algs4.cs.princeton.edu
Caminhos mínimos em um dígrafo valorado

Dado um dígrafo valorado, encontre o caminho mínimo de s a t.

edge-weighted digraph
4->5 0.35
5->4 0.35
4->7 0.37
5->7 0.28
7->5 0.28
5->1 0.32
0->4 0.38
0->2 0.26
7->3 0.39 shortest path from 0 to 6
1->3 0.29
0->2 0.26
2->7 0.34
2->7 0.34
6->2 0.40
7->3 0.39
3->6 0.52
3->6 0.52
6->0 0.58
6->4 0.93

An edge-weighted digraph and a shortest path

2
Google maps

3
Aplicações de caminho mínimo

PERT/CPM.
Rotas em mapas.
Seam carving.
Mapeamento de textura.
Navegação de robôs.
http://en.wikipedia.org/wiki/Seam_carving
Typesetting em TeX.
Planejamento de tráfego urbano.
Pipelining ótimo de chip VLSI.
Agendamento de operadores de telemarketing.
Roteamento de mensagens.
Protocolos de roteamento em rede (OSPF, BGP, RIP).
Exploração de oportunidades de câmbio.
Roteamento ótimo de caminhões considerando congestionamentos.

Reference: Network Flows: Theory, Algorithms, and Applications, R. K. Ahuja, T. L. Magnanti, and J. B. Orlin, Prentice Hall, 1993.

4
Variantes de caminho mínimo

Quais vértices?
Single source: de um vértice s para todos os demais.
Single sink: de cada vértice para um vértice específico t.
Source-sink: de um vértice s para outro t.
All pairs: entre todos os pares de vértice.

Restrições nos pesos das arestas?


Pesos não negativos.
Pesos Euclideanos.
Pesos arbitrários.

Ciclos?
Sem ciclos dirigidos.
Sem “ciclos negativos”. Qual variante?

Observação de simplificação: Sempre há caminho entre s até cada v.


5
4.4 C AMINHOS M ÍNIMOS
‣ APIs
‣ Propriedades de caminhos mínimos
‣ Algoritmo de Dijkstra
Algorithms
‣ DAGs valorados
‣ Pesos negativos
R OBERT S EDGEWICK | K EVIN W AYNE

http://algs4.cs.princeton.edu
API de arestas dirigidas e valoradas

public class DirectedEdge

DirectedEdge(int v, int w, double weight) weighted edge v→w

int from() vertex v

int to() vertex w

double weight() weight of this edge

String toString() string representation

weight
v w

Como processar uma aresta e: int v = e.from(), w = e.to();

7
Implementação em Java:

Similar a Edge de grafos não dirigidos, mas mais simples.


public class DirectedEdge
{
private final int v, w;
private final double weight;

public DirectedEdge(int v, int w, double weight)


{
this.v = v;
this.w = w;
this.weight = weight;
}

public int from()


{ return v; }
from() and to() replace
either() and other()
public int to()
{ return w; }

public int weight()


{ return weight; }
}
8
API de dígrafo valorado

public class EdgeWeightedDigraph

EdgeWeightedDigraph(int V) edge-weighted digraph with V vertices

EdgeWeightedDigraph(In in) edge-weighted digraph from input stream

void addEdge(DirectedEdge e) add weighted directed edge e

Iterable<DirectedEdge> adj(int v) edges pointing from v

int V() number of vertices

int E() number of edges

Iterable<DirectedEdge> edges() all edges

String toString() string representation

9
Dígrafo valorado: listas de adjacência

tinyEWD.txt
V 0 2 .26 0 4 .38
8 E
15
4 5 0.35 1 3 .29
adj
5 4 0.35
0
4 7 0.37 2 7 .34 Bag objects
5 7 0.28 1
7 5 0.28 2
5 1 0.32 3 6 .52 reference to a
3 DirectedEdge
0 4 0.38
0 2 0.26 4 object
4 7 .37 4 5 .35
7 3 0.39 5
1 3 0.29
6
2 7 0.34 5 1 .32 5 7 .28 5 4 .35
6 2 0.40 7
3 6 0.52
6 4 .93 6 0 .58 6 2 .40
6 0 0.58
6 4 0.93
7 3 .39 7 5 .28

Edge-weighted digraph representation

10
Dígrafo valorado: listas de adjacência (implementação em Java)

Igual a EdgeWeightedGraph exceto trocando Graph por Digraph.


public class EdgeWeightedDigraph
{
private final int V;
private final Bag<DirectedEdge>[] adj;

public EdgeWeightedDigraph(int V)
{
this.V = V;
adj = (Bag<DirectedEdge>[]) new Bag[V];
for (int v = 0; v < V; v++)
adj[v] = new Bag<DirectedEdge>();
}

public void addEdge(DirectedEdge e)


{
int v = e.from();
add edge e = v→w to
adj[v].add(e); only v's adjacency list
}

public Iterable<DirectedEdge> adj(int v)


{ return adj[v]; }
} 11
API para caminho mínimo single-source

Objetivo: Encontrar o menor caminho de s a todos os demais.

public class SP

SP(EdgeWeightedDigraph G, int s) shortest paths from s in graph G

double distTo(int v) length of shortest path from s to v

Iterable <DirectedEdge> pathTo(int v) shortest path from s to v

boolean hasPathTo(int v) is there a path from s to v?

SP sp = new SP(G, s);


for (int v = 0; v < G.V(); v++)
{
StdOut.printf("%d to %d (%.2f): ", s, v, sp.distTo(v));
for (DirectedEdge e : sp.pathTo(v))
StdOut.print(e + " ");
StdOut.println();
}

12
API para caminho mínimo single-source

Objetivo: Encontrar o menor caminho de s a todos os demais.

public class SP

SP(EdgeWeightedDigraph G, int s) shortest paths from s in graph G

double distTo(int v) length of shortest path from s to v

Iterable <DirectedEdge> pathTo(int v) shortest path from s to v

boolean hasPathTo(int v) is there a path from s to v?

% java SP tinyEWD.txt 0
0 to 0 (0.00):
0 to 1 (1.05): 0->4 0.38 4->5 0.35 5->1 0.32
0 to 2 (0.26): 0->2 0.26
0 to 3 (0.99): 0->2 0.26 2->7 0.34 7->3 0.39
0 to 4 (0.38): 0->4 0.38
0 to 5 (0.73): 0->4 0.38 4->5 0.35
0 to 6 (1.51): 0->2 0.26 2->7 0.34 7->3 0.39 3->6 0.52
0 to 7 (0.60): 0->2 0.26 2->7 0.34
13
4.4 C AMINHOS M ÍNIMOS
‣ APIs
‣ Propriedades de caminhos mínimos
‣ Algoritmo de Dijkstra
Algorithms
‣ DAGs valorados
‣ Pesos negativos
R OBERT S EDGEWICK | K EVIN W AYNE

http://algs4.cs.princeton.edu
Estruturas de dados para caminhos mínimos single-source

Objetivo: Encontrar o menor caminho de s a todos os demais.

Obs: Uma solução de árvore de caminhos mínimos (SPT) existe. Por que?

Consequência: Podemos representar a SPT com dois arrays indexados por


vértice:
distTo[v] é o comprimento do caminho mínimo de s a v.
edgeTo[v] é a última aresta no caminho mínimo de s a v.

edgeTo[] distTo[]
edgeTo[] distTo[]
0 null 0
0 null 0
1 1
5->1 0.32
5->1 0.32
1.05
1.05
2 2 0->2
0->20.26
0.26 0.26
0.26
3 3 7->3
7->30.37
0.37 0.97
0.97
4 4 0->4
0->40.38
0.38 0.38
0.38
5 5 4->5
4->50.35
0.35 0.73
0.73
6 3->6 0.52 1.49
6 3->6 0.52 1.49
7 2->7 0.34 0.60
7 2->7 0.34 0.60
SPT a partir deShortest
0 paths data structures
Representação pai-link
Shortest paths data structures
15
Estruturas de dados para caminhos mínimos single-source

Objetivo: Encontrar o menor caminho de s a todos os demais.

Obs: Uma solução de árvore de caminhos mínimos (SPT) existe. Por que?

Consequência: Podemos representar a SPT com dois arrays indexados por


vértice:
distTo[v] é o comprimento do caminho mínimo de s a v.
edgeTo[v] é a última aresta no caminho mínimo de s a v.
public double distTo(int v)
{ return distTo[v]; }

public Iterable<DirectedEdge> pathTo(int v)


{
Stack<DirectedEdge> path = new Stack<DirectedEdge>();
for (DirectedEdge e = edgeTo[v]; e != null; e = edgeTo[e.from()])
path.push(e);
return path;
} 16
Conceito chave: “Relaxamento” de arestas

"Relaxar" aresta e = v→w.


distTo[v] é o comprimento do caminho mínimo conhecido de s a v.
distTo[w] é o comprimento do caminho mínimo conhecido de s a w.
edgeTo[w] é a última aresta no caminho mínimo conhecido de s a w.
Se e = v→w produz um caminho menor até w através de v,
atualiza distTo[w] e edgeTo[w].

v→w “relaxa" com sucesso

v 3.1

1.3
s

w 7.2 4.4

Arestas pretas
estão em edgeTo[]

17
“Relaxamento" de arestas

"Relaxar" aresta e = v→w.


distTo[v] é o comprimento do caminho mínimo conhecido de s a v.
distTo[w] é o comprimento do caminho mínimo conhecido de s a w.
edgeTo[w] é a última aresta no caminho mínimo conhecido de s a w.
Se e = v→w produz um caminho menor até w através de v,
atualiza distTo[w] e edgeTo[w].

private void relax(DirectedEdge e)


{
int v = e.from(), w = e.to();
if (distTo[w] > distTo[v] + e.weight())
{
distTo[w] = distTo[v] + e.weight();
edgeTo[w] = e;
}
}

18
4.4 C AMINHOS M ÍNIMOS
‣ APIs
‣ Propriedades de caminhos mínimos
‣ Algoritmo de Dijkstra
Algorithms
‣ DAGs valorados
‣ Pesos negativos
R OBERT S EDGEWICK | K EVIN W AYNE

http://algs4.cs.princeton.edu
Edsger W. Dijkstra: algumas frases…

“ Do only what only you can do. ”

“ In their capacity as a tool, computers will be but a ripple on the


surface of our culture. In their capacity as intellectual challenge,
they are without precedent in the cultural history of mankind. ”

“ The use of COBOL cripples the mind; its teaching should,


Edsger W. Dijkstra
therefore, be regarded as a criminal offence. ” Turing award 1972

“ It is practically impossible to teach good programming to


students that have had a prior exposure to BASIC: as potential
programmers they are mentally mutilated beyond hope of
regeneration. ”

“ APL is a mistake, carried through to perfection. It is the


language of the future for the programming techniques
of the past: it creates a new generation of coding bums. ”
20
Edsger W. Dijkstra: algumas frases

21
Demonstração do algoritmo de Dijkstra

Considera vértices em ordem crescente de distância de s


(vértice ainda fora da árvore com o menor valor distTo[]).
Adiciona vértice à árvore e relaxa todas as arestas que saem dele.

1 15 3 0→1 5.0
0→4 9.0
5
4 0→7 8.0
12
s 0 3 1→2 12.0
8 1→3 15.0
7 2 9
7 1→7 4.0
9 2→3 3.0
6 1
11 2→6 11.0
5
5 3→6 9.0
4 13 4→5 4.0
4→6 20.0
4 20 6
4→7 5.0
5→2 1.0
5→6 13.0
Um dígrafo valorado 7→5 6.0
7→2 7.0
22
Demonstração do algoritmo de Dijkstra

Considera vértices em ordem crescente de distância de s


(vértice ainda fora da árvore com o menor valor distTo[]).
Adiciona vértice à árvore e relaxa todas as arestas que saem dele.

1 3
v distTo[] edgeTo[]
0 0.0 -
s 0 1 5.0 0→1
2 14.0 5→2
7 2 3 17.0 2→3
4 9.0 0→4
5 13.0 4→5
5 6 25.0 2→6
7 8.0 0→7

4 6

Árvore de caminhos mínimos a partir do vértice s

23
Visualização do algoritmo de Dijkstra

24
Visualização do algoritmo de Dijkstra

25
Algoritmo de Dijkstra: implementação em Java

public class DijkstraSP


{
private DirectedEdge[] edgeTo;
private double[] distTo;
private IndexMinPQ<Double> pq;

public DijkstraSP(EdgeWeightedDigraph G, int s) {


edgeTo = new DirectedEdge[G.V()];
distTo = new double[G.V()];
pq = new IndexMinPQ<Double>(G.V());

for (int v = 0; v < G.V(); v++)


distTo[v] = Double.POSITIVE_INFINITY;
distTo[s] = 0.0;

pq.insert(s, 0.0);
while (!pq.isEmpty()) {
int v = pq.delMin(); relaxa vértices em ordem
de distância de s
for (DirectedEdge e : G.adj(v))
relax(e);
}
}
}
26
Algoritmo de Dijkstra: implementação em Java

private void relax(DirectedEdge e)


{
int v = e.from(), w = e.to();
if (distTo[w] > distTo[v] + e.weight())
{
distTo[w] = distTo[v] + e.weight();
edgeTo[w] = e;
if (pq.contains(w)) pq.decreaseKey(w, distTo[w]); atualiza PQ
else pq.insert (w, distTo[w]);
}
}

27
Algoritmo de Dijkstra: qual fila de prioridade?

Depende da implementação de PQ: V insert, V delete-min, E decrease-key.

Implementação de PQ insert delete-min decrease-key total

Array desordenado 1 V 1 V2

Heap binário log V log V log V E log V

Heap d-way logd V d logd V logd V E logE/V V

Heap de Fibonacci
1† log V † 1† E + V log V

† amortizado

Em resumo:.
Implementação de array é a melhor para grafos densos.
Heap binário é muito mais rápido para grafos esparsos.
Heap 4-way é indicado para situações de alta performance
Heap de Fibonacci é a melhor na teoria, mas na prática…
28
Calculando uma árvore geradora em um grafo

O algoritmo de Dijkstra parece familiar?


Essencialmente igual ao algoritmo de Prim.
Ambos fazem parte de uma família de algoritmos que calcula uma
árvore geradora.

Principal diferença: Regra para escolher o próximo vértice da árvore.


Prim: Vértice mais próximo da árvore (por uma aresta não dirigida).
Dijkstra: Vértice mais próximo à origem (por um caminho dirigido).

29
4.4 C AMINHOS M ÍNIMOS
‣ APIs
‣ Propriedades de caminhos mínimos
‣ Algoritmo de Dijkstra
Algorithms
‣ DAGs valorados
‣ Pesos negativos
R OBERT S EDGEWICK | K EVIN W AYNE

http://algs4.cs.princeton.edu
Dígrafos acíclicos e valorados

P: Suponha que um dígrafo valorado não tenha ciclos dirigidos.


Será que é mais fácil encontrar caminhos mínimos que em um dígrafo
genérico?

1 15 3

5
4
12
s 0 3
8
7 2 9
7

9 6 1
11
5
5
4 13

4 20 6

R: Sim!
31
Demonstração de caminhos mínimos em DAG

Considere os vértices em ordem topológica.


Relaxe todas as arestas que saem de cada vértice.

0→1 5.0
0→4 9.0
1 15 3
0→7 8.0
5 1→2 12.0
4
12
s 0 3 1→3 15.0
8 1→7 4.0
7 2 9
7
2→3 3.0
9 6 2→6 11.0
1
11
5 3→6 9.0
5 4→5 4.0
4 13
4→6 20.0
4 20 6 4→7 5.0
5→2 1.0
5→6 13.0
Um DAG valorado 7→5 6.0
7→2 7.0
32
Demonstração de caminhos mínimos em DAG

Considere os vértices em ordem topológica.


Relaxe todas as arestas que saem de cada vértice.

0 1 4 7 5 2 3 6

1 3
v distTo[] edgeTo[]
0 0.0 -
s 0 1 5.0 0→1
2 14.0 5→2
7 2
3 17.0 2→3
4 9.0 0→4
5 13.0 4→5
5 6 25.0 2→6
7 8.0 0→7

4 6

Árvore de caminhos mínimos a partir do vértice s

33
Implementação de caminhos mínimos em DAG

public class AcyclicSP


{
private DirectedEdge[] edgeTo;
private double[] distTo;

public AcyclicSP(EdgeWeightedDigraph G, int s)


{
edgeTo = new DirectedEdge[G.V()];
distTo = new double[G.V()];

for (int v = 0; v < G.V(); v++)


distTo[v] = Double.POSITIVE_INFINITY;
distTo[s] = 0.0;

Topological topological = new Topological(G);


for (int v : topological.order()) ordem topológica
for (DirectedEdge e : G.adj(v))
relax(e);
}
}

34
Redimensionamento baseado em conteúdo

Seam carving. [Avidan and Shamir] Redimensionar uma imagem sem


distorções, para exibição em celulares e navegadores.

http://www.youtube.com/watch?v=vIFCV2spKtg
35
Redimensionamento baseado em conteúdo

Seam carving. [Avidan and Shamir] Redimensionar uma imagem sem


distorções, para exibição em celulares e navegadores.

Já implementado: Photoshop CS 5, Imagemagick, GIMP, ...


36
Redimensionamento baseado em conteúdo

Para encontrar uma “costura" (seam) vertical:


DAG em grade: vértice=pixel; aresta=do pixel para os 3 vizinhos de
baixo.
Peso do pixel = função de energia dos 8 pixels vizinhos.
Seam = caminho mínimo (soma dos pesos dos vértices) de cima até
embaixo.

37
Redimensionamento baseado em conteúdo

Para encontrar uma “costura" (seam) vertical:


DAG em grade: vértice=pixel; aresta=do pixel para os 3 vizinhos de
baixo.
Peso do pixel = função de energia dos 8 pixels vizinhos.
Seam = caminho mínimo (soma dos pesos dos vértices) de cima até
embaixo. seam

38
Redimensionamento baseado em conteúdo

Para remover uma seam vertical:


Remover os pixels na seam (uma em cada linha).

seam

39
Redimensionamento baseado em conteúdo

Para remover uma seam vertical:


Remover os pixels na seam (uma em cada linha).

40
Caminho máximo em DAGs valorados

Formulando como um problema de caminho mínimo em DAGs valorados:


Negativar todos os pesos
Encontrar caminhos mínimos Equivale a inverter igualdade em relax()

Negativar novamente.

Entrada de caminho máx. Entrada de caminho mín.

5->4 0.35 5->4 -0.35


4->7 0.37 4->7 -0.37
5->7 0.28 5->7 5->4
-0.28-0.35
s
5->1 0.32 5->1 4->7
-0.32-0.37
4->0 0.38 4->0 5->7
-0.38-0.28
0->2 0.26 0->2 5->1
-0.26-0.32
3->7 0.39 3->7 -0.39
4->0 -0.38
1->3 0.29 1->3 -0.29
0->2 -0.26
7->2 0.34 7->2 -0.34
6->2 0.40 6->2 3->7
-0.40-0.39
3->6 0.52 3->6 1->3
-0.52-0.29
6->0 0.58 6->0 7->2
-0.58-0.34
6->4 0.93 6->4 6->2
-0.93-0.40
3->6 -0.52
6->0 -0.58
6->4 -0.93
Ponto chave: Ordenação topológica funciona até com pesos negativos.
41
Aplicação de caminho máximo

Agendamento de tarefas paralelas: Dado um conjunto de tarefas com


durações e relações de precedência, agendar as tarefas (encontrando um
tempo inicial para cada uma), de forma a finalizar o projeto no menor
tempo possível.

job duration must complete


before
0 41.0 1 7 9
1 51.0 2
2 50.0
3 36.0
4 38.0
1
5 45.0
7 3
6 21.0 3 8
0 9 6 8 2
7 32.0 3 8
5 4
8 32.0 2
9 29.0 4 6
0 41 70 91 123 173

A job scheduling problem Parallel job scheduling solution

42
Resumo: custo dos algoritmos de caminho mínimo single source

Algoritmo restrição Caso típico Pior caso Espaço extra

Sem ciclos
Ordenação topológica dirigidos E+V E+V V

Dijkstra Sem pesos


negativos E log V E log V V
(heap binário)

Bellman-Ford EV EV V
Sem ciclos
negativos
Bellman-Ford
E+V EV V
(queue-based)

Obs. 1: Ciclos dirigidos tornam o problema mais difícil.


Obs. 2: Pesos negativos tornam o problema mais difícil.
Obs. 3: Ciclos negativos impedem a solute do problema.

43

Você também pode gostar

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy