Escolar Documentos
Profissional Documentos
Cultura Documentos
Aula 5
Algoritmos de Caminhos Mínimos
Por exemplo:
• - Minimizar o custo ou o tempo gasto
• - Maximizar o lucro ou o ganho
Motivação
• Considere uma empresa de entregas, com um
centro de distribuição e um caminhão
• Problema:
• Dada uma lista de endereços de entregas encontrar
uma sequência que minimize a quilometragem total
do caminhão para realizar todas as entregas
Vértices:
Endereços de entrega
Arestas:
Uma rota conectando 2
endereços de entrega
Peso/custo:
Distâncias entre as
extremidades
Motivação
• Considere um programa de GPS para o cálculo da
“melhor rota” entre dois pontos
• Problema:
• Dado um endereço de origem e destino, encontrar um
caminho mínimo entre a origem e o destino, i.e.,
encontrar a rota com a menor distância
Vértices:
Cruzamentos entre ruas
Arestas:
Cada trecho de rua
Peso/custo:
Comprimento do trecho (em
quilômetros)
Distância
Um caminho C, em um grafo, é mínimo se não
existe outro caminho com mesma origem e mesmo
término que C mas comprimento menor que o de C
b c Distância entre:
h,e = 3
a d f h,k = Infinito
e k
Distância
• Grafos ponderados
5 7 1 Esse número é o
custo/peso da aresta, que
a d f
2 10 pode ser associado a uma
3 7 característica física da
e k
conexão
Distância
• Grafos ponderados
h
1
1
b c Distância entre:
5 7 1 h,k = Infinito
a d f h,e = ?
2 10
3 7
e k
Distância
• Grafos ponderados
h
1
1
b c Distância entre:
5 7 1 h,k = Infinito
a d f h,e = 8
2 10
3 7
e k
Distância
• Grafos ponderados
Distância entre:
h
h,k = Infinito
1
1 h,e = 8
b c
5 7 1
O comprimento de um
a d f
2 10 caminho é a soma dos
3 7 pesos/custos das
e k arestas do caminho
Busca de Caminhos Mínimos
Grafo não-ponderado
O caminho mais curto entre os vértices v e w de um determinado
grafo não-ponderado é aquele que possui o menor número de
arestas entre os referidos vértices
Grafo ponderado
O caminho mais curto entre os vértices v e w de um determinado
grafo ponderado é aquele cuja soma dos pesos das arestas possui
o menor valor possível dentre todos os caminhos existentes
entre os referidos vértices
Busca de Caminhos Mínimos
Algoritmos específicos:
– (1) Caminhos mínimos a partir de um dado vértice
a
1 10
3
b e
5 1 6
c d
2
Algoritmo de Dijkstra
Vértices
∞
iteração a.dist b.dist c.dist d.dist e.dist
visitados
a 0 {} ∞ ∞ ∞ ∞ ∞
1 10
∞ 3 ∞
b e
5 1 6
c d
∞ 2 ∞
Algoritmo de Dijkstra
Vértices
iteração a.dist b.dist c.dist d.dist e.dist
0 visitados
a 0 {} ∞ ∞ ∞ ∞ ∞
1 10 1 {a} 0 1 ∞ 3 10
1 3 10
b e
5 1 6 Origem s = a
c d
∞ 2 3
Algoritmo de Dijkstra
Vértices
iteração a.dist b.dist c.dist d.dist e.dist
0 visitados
a 0 {} ∞ ∞ ∞ ∞ ∞
1 10 1 {a} 0 1 ∞ 3 10
1 3 10 2 {a,b} 0 1 6 3 10
b e
5 1 6
c d
6 2 3
Algoritmo de Dijkstra
Vértices
iteração a.dist b.dist c.dist d.dist e.dist
0 visitados
a 0 {} ∞ ∞ ∞ ∞ ∞
1 10 1 {a} 0 1 ∞ 3 10
1 3 9 2 {a,b} 0 1 6 3 10
b e
3 {a,b,d} 0 1 5 3 9
5 1 6
c d
5 2 3
Algoritmo de Dijkstra
Vértices
iteração a.dist b.dist c.dist d.dist e.dist
0 visitados
a 0 {} ∞ ∞ ∞ ∞ ∞
1 10 1 {a} 0 1 ∞ 3 10
1 3 6 2 {a,b} 0 1 6 3 10
b e
3 {a,b,d} 0 1 5 3 9
4 {a,b,d,c} 0 1 5 3 6
5 1 6
c d
5 2 3
Algoritmo de Dijkstra
Vértices
iteração a.dist b.dist c.dist d.dist e.dist
0 visitados
a 0 {} ∞ ∞ ∞ ∞ ∞
1 10 1 {a} 0 1 ∞ 3 10
1 3 6 2 {a,b} 0 1 6 3 10
b e
3 {a,b,d} 0 1 5 3 9
4 {a,b,d,c} 0 1 5 3 6
5 1 6 5 {a,b,d,c,e} 0 1 5 3 6
c d
5 2 3
Algoritmo de Dijkstra
• Inicialização:
Atribui uma distância infinita para todos os vértices
O vértice de origem recebe distância zero (0)
Todos os vértices são marcados como não visitados
Observação: por sempre escolher como próximo vértice a ser analisado aquele que
parece ser a melhor opção, o algoritmo é chamado de guloso (Greedy)
Algoritmo de Dijkstra
b
2 4
3
a c
6
7
3 3
e d
2
Algoritmo de Dijkstra
∞
Vértices
iteração a.dist b.dist c.dist d.dist e.dist
visitados
b 0 {} ∞ ∞ ∞ ∞ ∞
2 4
∞
a
6
3
c ∞
7
3 3
e d
∞ 2 ∞
Algoritmo de Dijkstra
Vértices
iteração a.dist b.dist c.dist d.dist e.dist
2 visitados
a 0 {} ∞ ∞ ∞ ∞ ∞
2 4 1 {b} 2 0 3 6 ∞
0
b
6
3
e ∞
7
3 3 Origem s = b
c d
3 2 6
Algoritmo de Dijkstra
Vértices
iteração a.dist b.dist c.dist d.dist e.dist
2 visitados
a 0 {} ∞ ∞ ∞ ∞ ∞
2 4 1 {b} 2 0 3 6 ∞
0 3 2 {b,a} 2 0 3 6 6
b e 6
6
7
3 3
c d
3 2 6
Algoritmo de Dijkstra
Vértices
iteração a.dist b.dist c.dist d.dist e.dist
2 visitados
a 0 {} ∞ ∞ ∞ ∞ ∞
2 4 1 {b} 2 0 3 6 ∞
0 3 2 {b,a} 2 0 3 6 6
b e 6 3 {b,a,c} 2 0 3 5 6
6
7
3 3
c d
3 2 5
Algoritmo de Dijkstra
Vértices
iteração a.dist b.dist c.dist d.dist e.dist
2 visitados
a 0 {} ∞ ∞ ∞ ∞ ∞
2 4 1 {b} 2 0 3 6 ∞
0 3 2 {b,a} 2 0 3 6 6
b e 6 3 {b,a,c} 2 0 3 5 6
6
7
4 {b,a,c,d} 2 0 3 5 6
3 3
c d
3 2 5
Algoritmo de Dijkstra
a 0 {} ∞ ∞ ∞ ∞ ∞
2 4 1 {b} 2 0 3 6 ∞
0 3 2 {b,a} 2 0 3 6 6
b e 6 3 {b,a,c} 2 0 3 5 6
6
7
4 {b,a,c,d} 2 0 3 5 6
3 3 5 {b,a,c,d,e} 2 0 3 5 6
c d
3 2 5
Exemplo 1
Para encontrarmos todos os menores caminhos
partindo do vértice A, iniciamos indicando que a
distância de A até ele mesmo é 0, e para todos os
outros vértices é INFINITO (INF)
INF INF
0
2 B
1
C
A
INF 1
5
3 E 2
D INF
INF G
1
2
H INF F INF
Exemplo 1
Na busca em largura o vértice A enviaria a
informação paralelamente para vértices B e G
INF INF
0
2 B
1
C
A
INF 1
5
3 E 2
D INF
INF G
1
2
H INF F INF
Exemplo 1
Expandimos tais vértices atualizamos a distância
até eles somando o valor do vértice A às arestas
correspondentes
2 INF
0
2 B
1
C
A
INF 1
5
3 E 2
5 G
1 D INF
2
H INF F INF
Exemplo 1
Ao invés de expandir paralelamente os vértices B e
G, vamos escolher o vértice com menor distância
para expandir. No nosso caso esse é o vértice B
2 INF
0
2 B
1
C
A
INF 1
5
3 E 2
5 G
1 D INF
2
H INF F INF
Exemplo 1
Do vértice B podemos expandir apenas o vértice C,
com distância igual a 2 + 1 = 3
2 3
0
2 B
1
C
A
INF 1
5
3 E 2
5 G
1 D INF
2
H INF F INF
Exemplo 1
Na sequência expandimos o vértice C, que tem
apenas o vértice D com valor igual a 3 + 1 = 4
2 3
0
2 B
1
C
A
INF 1
5
3 E 2
5 G
1 D 4
2
H INF F INF
Exemplo 1
Do vértice D expandimos o vértice E com o valor
4+2=6
2 3
0
2 B
1
C
A
6 1
5
3 E 2
5 G
1 D 4
2
H INF F INF
Exemplo 1
Como o vértice G agora tem um valor menor,
expandimos a partir dele, o vértice H (o E já foi
utilizado). O valor ficará 5 + 2 = 7
2 3
0
2 B
1
C
A
6 1
5
3 E 2
5 G
1 D 4
2
H 7 F INF
Exemplo 1
Finalmente expandimos o vértice E, que leva ao
vértice F com valor 6 + 1 = 7
2 3
0
2 B
1
C
A
6 1
5
3 E 2
5 G
1 D 4
2
H 7 F 7
Exemplo 1
Não tendo mais nenhum vértice para expandirmos a
busca é encerrada, formando a seguinte árvore
2 3
0
2 B
1
C
A
6 1
5
E 2
5 G
1 D 4
2
H 7 F 7
Exemplo 2
94
Examinando o vértice d
O vértice a ser examinado, em cada iteração, é aquele que acumula o menor valor relativo à distância
entre ele e o vértice origem, o segundo valor do rótulo
Exemplo 2
Lista de vértices já identificados = {a,d,c}
94
Examinando o vértice c
A rotulação do vértice e não é alterada, pois 54+67 resultaria em uma distância maior que 68
Exemplo 2
Lista de vértices já identificados = {a,d,c,b}
Examinando o vértice b
O rótulo do vértice f adjacente a b é atualizado, pois o caminho de “a” até “f” passando por “b” é
menor que o anteriormente encontrado que passava por “d”
Exemplo 2
Lista de vértices já identificados = {a,d,c,b,e}
Examinando o vértice e
Exemplo 2
Lista de vértices já identificados = {a,d,c,b,e,f}
Examinando o vértice f
O rótulo do vértice g adjacente a f é atualizado, pois o caminho de “a” até “g” passando por “f” é
menor que o anteriormente encontrado que passava por “d”
Exemplo 2
Lista de vértices já identificados = {a,d,c,b,e,f,g}
Examinando o vértice g
Exemplo 2
Lista de vértices já identificados = {a,d,c,b,e,f,h}
Examinando o vértice h
O rótulo do vértice j adjacente a h é atualizado, pois o caminho de “a” até “j” passando por “h” é
menor que o anteriormente encontrado que passava por “g”
Exemplo 2
Lista de vértices já identificados = {a,d,c,b,e,f,h,j}
1
t x
10 9
2 3
s
4 6
5 7
y z
2
Algoritmo de Dijkstra
Inicialização
Para cada vértice v em G
v.dist = INFINITO
v.pre = 0
s.dist = 0
T = todos os vértices de G
∞ ∞ iteração
Vértices
visitados
s.dist t.dist x.dist y.dist z.dist
1
t x
0 {} ∞ ∞ ∞ ∞ ∞
10 9
∞ 2 3
s
4 6
5 7
y z
2
∞ ∞ Anterior s t x y z
0 0 0 0 0
Algoritmo de Dijkstra
Enquanto T VAZIO faça
u = vértice em T com menor distância
Se u.dist == INFINITO
Sai do laço
remove u de T
Para cada vizinho v de u
d = u.dist + w(u,v)
Se d < v.dist
v.dist = d
v.pre = u
10 ∞ iteração
Vértices
visitados
s.dist t.dist x.dist y.dist z.dist
1
t x
0 {} ∞ ∞ ∞ ∞ ∞
10 9 1 {s} 0 10 ∞ 5 ∞
0 2 3
s
4 6
5 7
y z
2
5 ∞ Anterior s t x y z
0 s 0 s 0
Algoritmo de Dijkstra
Enquanto T VAZIO faça
u = vértice em T com menor distância
Se u.dist == INFINITO
Sai do laço
remove u de T
Para cada vizinho v de u
d = u.dist + w(u,v)
Se d < v.dist
v.dist = d
v.pre = u
8 14 iteração
Vértices
s.dist t.dist x.dist y.dist z.dist
1 visitados
t x
0 {} ∞ ∞ ∞ ∞ ∞
10 9 1 {s} 0 10 ∞ 5 ∞
0 2 3
2 {s,y} 0 8 14 5 7
s
4 6
5 7
y z
2
5 7 Anterior s t x y z
0 y y s y
Algoritmo de Dijkstra
Enquanto T VAZIO faça
u = vértice em T com menor distância
Se u.dist == INFINITO
Sai do laço
remove u de T
Para cada vizinho v de u
d = u.dist + w(u,v)
Se d < v.dist
v.dist = d
v.pre = u
8 13 iteração
Vértices
s.dist t.dist x.dist y.dist z.dist
1 visitados
t x
0 {} ∞ ∞ ∞ ∞ ∞
10 9 1 {s} 0 10 ∞ 5 ∞
0 2 3
2 {s,y} 0 8 14 5 7
s
4 6
3 {s,y,z} 0 8 13 5 7
5 7
y z
2
5 7 Anterior s t x y z
0 y z s y
Algoritmo de Dijkstra
Enquanto T VAZIO faça
u = vértice em T com menor distância
Se u.dist == INFINITO
Sai do laço
remove u de T
Para cada vizinho v de u
d = u.dist + w(u,v)
Se d < v.dist
v.dist = d
v.pre = u
8 9 iteração
Vértices
s.dist t.dist x.dist y.dist z.dist
1 visitados
t x
0 {} ∞ ∞ ∞ ∞ ∞
10 9 1 {s} 0 10 ∞ 5 ∞
0 2 3
2 {s,y} 0 8 14 5 7
s
4 6
3 {s,y,z} 0 8 13 5 7
5 7
4 {s,y,z,t} 0 8 9 5 7
y z
2
5 7 Anterior s t x y z
0 y t s y
Algoritmo de Dijkstra
Enquanto T VAZIO faça
u = vértice em T com menor distância
Se u.dist == INFINITO
Sai do laço
remove u de T
Para cada vizinho v de u
d = u.dist + w(u,v)
Se d < v.dist
v.dist = d
v.pre = u
8 9 iteração
Vértices
s.dist t.dist x.dist y.dist z.dist
1 visitados
t x
0 {} ∞ ∞ ∞ ∞ ∞
10 9 1 {s} 0 10 ∞ 5 ∞
0 2 3
2 {s,y} 0 8 14 5 7
s
4 6
3 {s,y,z} 0 8 13 5 7
5 7
4 {s,y,z,t} 0 8 9 5 7
5 {s,y,z,t,x} 0 8 9 5 7
y z
2
5 7 Anterior s t x y z
0 y t s y
Limitações
O algoritmo é incapaz de calcular os caminhos
mínimos caso existam arestas com custo negativo
https://www.cs.usfca.edu/~galles/visualization/Dijkstra.html
Caminhos entre todos os pares de vértices
1 2 3 4 5
1 1 0 5 0 2 0
2 3
2 5 0 1 0 0
5 1
3 0 1 0 1 0
1 4 5 4 2 0 1 0 10
2 10
5 0 0 0 10 0
1 2 3 4 5
1 1 0 5 ∞ 2 ∞
2 3
2 5 0 1 ∞ ∞
5 1
3 ∞ 1 0 1 ∞
1 4 5 4 2 ∞ 1 0 10
2 10
5 ∞ ∞ ∞ 10 0
Exemplo 1
1 2 3 4 5 D[1,1] > D[1,1]+D[1,1] ? Não
K=1
D[1,2] > D[1,1]+D[1,2] ? Não
1 0 5 ∞ 2 ∞ D[1,3] > D[1,1]+D[1,3] ? Não
2 5 0 1 ∞ ∞ D[1,4] > D[1,1]+D[1,4] ? Não
D[1,5] > D[1,1]+D[1,5] ? Não
3 ∞ 1 0 1 ∞
2 ∞ 1 0 10 D[2,1] > D[2,1]+D[1,1] ? Não
4 D[2,2] > D[2,1]+D[1,2] ? Não
5 ∞ ∞ ∞ 10 0 D[2,3] > D[2,1]+D[1,3] ? Não
D[2,4] > D[2,1]+D[1,4] ? SIM D[2,4]= 5+2=7
D[2,5] > D[2,1]+D[1,5] ? Não
1 2 3 4 5 …
1 0 5 ∞ 2 ∞
D[4,2] > D[4,1]+D[1,2] ? SIM D[4,2]= 2+5=7
2 5 0 1 7 ∞
∞ 1 0 1 ∞ ...
3
4 2 7 1 0 10
5 ∞ ∞ ∞ 10 0
Exemplo 1
1 2 3 4 5 D[1,1] > D[1,2]+D[2,1] ? Não
K=2
D[1,2] > D[1,2]+D[2,2] ? Não
1 0 5 ∞ 2 ∞
D[1,3] > D[1,2]+D[2,3] ? SIM D[1,3]= 5+1=6
2 5 0 1 7 ∞ D[1,4] > D[1,2]+D[2,4] ? Não
D[1,5] > D[1,2]+D[2,5] ? Não
3 ∞ 1 0 1 ∞
4 2 7 1 0 10
…
5 ∞ ∞ ∞ 10 0
D[3,1] > D[3,2]+D[2,1] ? SIM D[3,1]= 1+5=6
1 2 3 4 5 ...
1 0 5 6 2 ∞
2 5 0 1 7 ∞
3 6 1 0 1 ∞
4 2 7 1 0 10
5 ∞ ∞ ∞ 10 0
Exemplo 1
1 2 3 4 5 D[1,1] > D[1,3]+D[3,1] ? Não
K=3
D[1,2] > D[1,3]+D[3,2] ? Não
1 0 5 6 2 ∞ D[1,3] > D[1,3]+D[3,3] ? Não
2 5 0 1 7 ∞ D[1,4] > D[1,3]+D[3,4] ? Não
D[1,5] > D[1,3]+D[3,5] ? Não
3 6 1 0 1 ∞
2 7 1 0 10 D[2,1] > D[2,3]+D[3,1] ? Não
4 D[2,2] > D[2,3]+D[3,2] ? Não
5 ∞ ∞ ∞ 10 0 D[2,3] > D[2,3]+D[3,3] ? Não
D[2,4] > D[2,3]+D[3,4] ? SIM D[2,4]=1+1=2
D[2,5] > D[2,3]+D[3,5] ? Não
1 2 3 4 5 …
1 0 5 6 2 ∞
D[4,2] > D[4,3]+D[3,4] ? SIM D[4,2]=1+1=2
2 5 0 1 2 ∞
6 1 0 1 ∞ ...
3
4 2 2 1 0 10
5 ∞ ∞ ∞ 10 0
Exemplo 1
1 2 3 4 5 …
K=4
1 0 5 6 2 ∞ D[1,2] > D[1,4]+D[4,2] ? SIM D[1,2]=2+2=4
D[1,3] > D[1,4]+D[4,3] ? SIM D[1,3]=2+1=3
2 5 0 1 2 ∞ D[1,5] > D[1,4]+D[4,5] ? SIM D[1,5]=2+10=12
...
3 6 1 0 1 ∞
D[2,1] > D[2,4]+D[4,1] ? SIM D[2,1]=2+2=4
4 2 2 1 0 10 D[2,5] > D[2,4]+D[4,5] ? SIM D[2,5]=2+10=12
…
5 ∞ ∞ ∞ 10 0
D[3,1] > D[3,4]+D[4,1] ? SIM D[3,1]=1+2=3
D[3,5] > D[3,4]+D[4,5] ? SIM D[3,5]=1+10=11
1 2 3 4 5 …
1 0 4 3 2 12
D[5,1] > D[5,4]+D[4,1] ? SIM D[5,1]=10+2=12
2 4 0 1 2 12 D[5,2] > D[5,4]+D[4,2] ? SIM D[5,2]=10+2=12
D[5,3] > D[5,4]+D[4,3] ? SIM D[5,3]=10+1=11
3 3 1 0 1 11
4 2 2 1 0 10
5 12 12 11 10 0
Exemplo 1
1 2 3 4 5 K=5
0 4 2 Não houveram modificações
1 3 12
2 4 0 1 2 12
3 3 1 0 1 11
2 2 1 0 10
4
12 12 11 10 0
5
1 2 3 4 5
1 0 4 3 2 12
2 4 0 1 2 12
3 3 1 0 1 11
4 2 2 1 0 10
12 12 11 10 0
5
Exemplo 1
1 2 3 4 5
0 4 3 2 12
1 1
2 3
4 0 1 2 12
2
5 1
3 3 1 0 1 11
2 2 1 0 10 1 4 5
4 2 10
12 12 11 10 0
5
Exemplo 2
Matriz de Distâncias
K=1
K=3
1 2 3
1 0 7 5
2 3 0 8
3 5 2 0
Simulação
https://www.cs.usfca.edu/~galles/visualization/Floyd.html
Algoritmo de Prim
Uma árvore é um grafo conectado sem ciclo, e
constitui uma alternativa interessante quando se
deseja conectar todos os vértices de um grafo
com uma extensão MÍNIMA de arestas (árvore
geradora mínima)
Dado um grafo conectado, o Algoritmo de Prim
ajuda a encontrar quais arestas redundantes
podem ser retiradas para que todos os vértices
ainda continuem conectados através de uma
árvore com custo MÍNIMO
Algoritmo de Prim
Árvore
Geradora
Mínima
Exemplo 2
Origem s = a
Árvore
Geradora
Mínima
Exemplo 3
Origem s = 0
Árvore
Geradora
Mínima
Algoritmo de Prim Colorido
O algoritmo de Prim pode ser tornado mais
eficiente com um controle das arestas que são
examinadas
Senão
colorir (k,z) com vermelho
Exemplo
Grafo G
Exemplo
Vértice 1 é examinado
Arestas (1,2) e (1,3) são coloridas de verde
Exemplo
k z
z z
Analisando a aresta (2,3), verifica-se que há uma aresta verde (1,3) incidente ao vértice 3
Como dwz > dkz colorir a aresta (w,z) - (1,3) com vermelho e a aresta (k,z) – (2,3) com verde
Exemplo
Aresta (1,3) é colorida de vermelho
Aresta (2,3) é colorida de azul por ser a aresta com menor custo
k z
w z
Analisando a aresta (5,4), verifica-se que há uma aresta verde (2,4) incidente ao vértice 2
Como dwz > dkz colorir a aresta (w,z) - (2,4) com vermelho e a aresta (k,z) – (5,4) com verde
Exemplo
https://www.cs.usfca.edu/~galles/visualization/Prim.html
Bibliografia
Capítulos 3 e 4 Capítulo 24
Atividade 1
Para cada grafo, simule o Algoritmo de Dijkstra
e determine as distâncias a todos os vértices,
considerando como origem o vértice 1
1 1
2
1 1 1 1
2 2
3 3 1
5 5
Atividade 2
Encontre as árvores geradoras mínimas para o
grafo abaixo, utilizando os Algoritmos de Prim e
Prim Colorido. Considere como origem o vértice V1