Modifique FASTER-ALL-PAIRS-SHORTEST-PATHS de modo que ele possa detectar a presença de um ciclo de peso negativo.
Algoritmo original:
FASTER-ALL-PAIRS-SHORTEST-PATH(W)
1 n ← linhas[W]
2 L(1) ← W
3 m ← 1
4 while m < (n - 1) do
5 L(2m)
← EXTEND-SHORTEST-PATHS(L(m), L(m))
6 m ← 2m
7 return L(m)
Foram consideradas duas estratégias para a resolução deste
exercício, apresentadas abaixo.
Depois de terminarem as iterações do algoritmo, executar uma nova iteração de EXTEND-SHORTEST-PATHS. Se algum valor na matriz foi alterado, isto significa que há pelo menos um ciclo de peso negativo. Esta alteração está descrita no pseudocódigo abaixo, linhas 7-11.
FASTER-ALL-PAIRS-SHORTEST-PATH_1(W)
1 n ← linhas[W]
2 L(1) ← W
3 m ← 1
4 while m < (n - 1)
do
5 L(2m)
← EXTEND-SHORTEST-PATHS(L(m), L(m))
6 m ← 2m
7 matrizCiclo ← EXTEND-SHORTEST-PATHS(L(m),
L(m))
8 for i
← 1 to n do
9 for
j ← 1 to n do
10 if
Lij(m) ≠ matrizCicloij
then
11 error
"Há ciclos negativos: impossível verificar os caminhos mais
curtos de todos os pares."
12 return L(m)
Depois de terminarem as iterações do algoritmo, verificar se há algum valor negativo na diagonal principal. Se não houver ciclos negativos, todos os valores da diagonal devem ter o valor zero. Se houver ciclos negativos, haverá pelo menos um valor negativo na diagonal principal. Esta alteração está descrita no pseudocódigo abaixo, linhas 7-9.
FASTER-ALL-PAIRS-SHORTEST-PATH_2(W)
1 n ← linhas[W]
2 L(1) ← W
3 m ← 1
4 while m < (n - 1)
do
5 L(2m)
← EXTEND-SHORTEST-PATHS(L(m), L(m))
6 m ← 2m
7 for i
← 1 to n do
8 if
Lii(m) ≠ 0 then
9 error
"Há ciclos negativos: impossível verificar os caminhos mais
curtos de todos os pares."
10 return L(m)
Como foi apresentado, o algoritmo de Floyd-Warshall exige o espaço Θ(n3), pois calculamos dij(k) para i,j,k = 1, 2, ..., n. Mostre que o procedimento a seguir, que simplesmente retira todos os sobrescritos, é correto e, desse modo, apenas o espaço Θ(n2) é necessário.
Algoritmo original | Algoritmo da questão | |
---|---|---|
FLOYD-WARSHALL(W) |
FLOYD-WARSHALL'(W) |
O algoritmo modificado (FLOYD-WARSHALL') poderia não funcionar já que, por estar usando uma única matriz (no lugar de n matrizes, uma para cada valor de k, 1 ≤ k ≤ n), algum valor poderia ser sobrescrito de forma indevida. A prova de correção do algoritmo equivale, portanto, a provar que o algoritmo nunca sobrescreve um valor indevidamente.
Em primeiro lugar, é preciso definir o que é sobrescrita indevida. É necessário preocupar-se apenas com um valor fixo para k, já que as escritas (atribuições a elementos das matrizes D) ocorrem em "lotes", cada lote com um valor fixo para k. Estas alterações dependem apenas de valores da matriz D anterior (k - 1), que não é alterada, e da matriz D atual.. Então, sobrescrita indevida ocorreria se, para um determinado valor de k, elementos na matriz D(k) fossem alterados para algum valor e, mais tarde, fosse necessário ler o valor que havia antes da alteração.
A linha 6 do algoritmo original pode ser definida da seguinte forma:
(1) a alteração de dij(k) depende de dik(k-1) , dkj(k-1)
Conseqüentemente,
(2) dik(k) depende de dik(k-1) e dkk(k-1) (quando j = k)
(3) dkj(k) depende de dkk(k-1) e dkj(k-1) (quando i = k)
Como a diagonal de toda matriz D é sempre zero (considerando-se que não existem ciclos negativos), as sentenças (2) e (3) podem ser reescritas da seguinte forma:
(4) dik(k) depende de dik(k-1) (pois dkk(k-1) = 0)
(5) dkj(k) depende de dkj(k-1) (pois dkk(k-1) = 0)
Ou seja, em cada iteração do for da linha 3, os elementos dik e dkj não são alterados para o valor de k naquela iteração.
A sentença (1) pode ser reescrita da seguinte forma:
(6) a alteração de dij(k) depende de dik(k), dkj(k)
Portanto, para um dado valor de k:
Isto significa que, para cada iteração do for da linha 3, a única alteração ocorre em elementos que não estejam nem na linha k e nem na coluna k. Além disso, qualquer alteração se deve apenas a elementos que estejam na linha k ou na coluna k. Logo, nenhum elemento é sobrescrito de forma indevida, o que prova a correção do algoritmo FLOYD-WARSHALL'.
Suponha que w(u,v) ≥ 0 para todas as arestas (u,v) ∈ E. Qual é o relacionamento entre as funções peso w e ŵ?
Ambas as funções têm o mesmo valor. A técnica de reponderação de pesos do algoritmo de Johnson funciona da seguinte forma: acrescenta-se um vértice s ao grafo tal que existe uma aresta com peso zero que vai de s a todo vértice do grafo. A função h : V → R, que mapeia os vértices para números reais, é definida como a menor distância entre s e todo vértice do grafo. Como todo peso de aresta é positivo, a menor distância entre s e qualquer vértice é zero.
A função ŵ é definida da seguinte forma:
(1) ŵ(u,v) = w(u,v) + h(u) - h(v)
Como a função h tem valor zero para qualquer vértice do grafo, tem-se:
(2) ŵ(u,v) = w(u,v) (pois h(u) e h(v) têm valor zero).
Disciplina: | MO417 - Complexidade de Algoritmos I |
Livro texto: | CORMEN, T. H. et alii. Algoritmos: Teoria e Prática. Tradução da 2ª edição americana: Vandenberg D. de Souza. Rio de Janeiro: Campus, 2002. |
Redator: | Augusto Jun Devegili (RA 025620) |