• Nenhum resultado encontrado

Algoritmo de Bellman-Ford

N/A
N/A
Protected

Academic year: 2022

Share "Algoritmo de Bellman-Ford"

Copied!
13
0
0

Texto

(1)

Algoritmo de Bellman-Ford

Algoritmos em Grafos — 1º sem 2012 1 / 1

Problema da SPT

Problema: Dado um vértice s de um digrafo com custos (possivelmente negativos) nos arcos, encontrar uma SPT com raiz s

Entra:

1 2

3

4 5

6

7 8

9 0 10

2

3

4

5 6

Sai:

1 2

3

4 5

6

7 9

10 8

0

2

3

4

5 1

Algoritmos em Grafos — 1º sem 2012 2 / 1

Propriedade da subestrutura ótima

Se G é um digrafo com custos não-negativos nos arcos e v0-v1-v2-. . . -vk é um caminho mínimo então vi-vi+1-. . . -vj é um caminho mínimo para

0 ≤ i ≤ j ≤ k

custo[v][w] = menor custo de uma caminho de v a w Propriedade 1

O valor de custo[s][t] é

min{custo[s][v] +G->adj[v][t] : v-t é arco}

Propriedade 2

O valor de custo[s][t] é

min{custo[s][v] +custo[v][t] : v é vértice}

Algoritmos em Grafos — 1º sem 2012 3 / 1

Subestrutura ótima . . .

todos custos = −1

G

s

t

Não vale para digrafos com ciclos negativos

Algoritmos em Grafos — 1º sem 2012 4 / 1

(2)

Ciclos negativos

Se o digrafo possui um ciclo (de custo) negativo alcançavel a partir de s, então não existe caminho mínimo de s a alguns vértices

pv pt

0 1 2

3

5 4

1

3

−4 2

Vamos supor que o digrafo não tem ciclos negativos.

Algoritmos em Grafos — 1º sem 2012 5 / 1

Caminho de custo mínimo

Problema: Dado vértices s e t de um digrafo com custos (possivelmente negativos) nos arcos, encontrar uma caminho de custo mínimo de s a t.

Esse problema pode ser:

inviável: não existe caminho de s a t;

viável e limitado: existe caminho de s a t e nenhum caminho de s a t passa por um ciclo negativo; ou

viável e ilimitado: existe caminho de s a t mas não existe um caminho de s a t de custo

mínimo, ou seja, existe caminho de s a t que passa por um ciclo negativo.

Algoritmos em Grafos — 1º sem 2012 6 / 1

Caminho simples de custo mínimo

Problema: Dado vértices s e t de um digrafo com custos (possivelmente negativos) nos arcos, encontrar uma caminho simples de custo mínimo de s a t.

Esse problema pode ser:

inviável: não existe caminho de s a t; ou viável (e limitado): existe caminho de s a t.

Este problema é NP-difícil.

Só sabemos resolver esse problema quando o caminho de custo mínimo é simples. . .

Algoritmos em Grafos — 1º sem 2012 7 / 1

Programação dinâmica

Como explorar a propriedade da subestrutura ótima custo[k][w] = menor custo de um caminho de

s a w com ≤ k arcos.

Recorrência

custo[0][s] = 0

custo[0][w] = INFINITO, w 6= s custo[k][w] = min{custo[k−1][w],

min{custo[k−1][v] +G->adj[v][w]}}

Se o digrafo não tem ciclo negativo acessível a partir de s, então custo[V-1][w] é o menor custo de um caminho de s a w

Algoritmos em Grafos — 1º sem 2012 8 / 1

(3)

Exemplo

36 36

36 36

36 3

6 −1

−7

−2 0

3 1

2

3 4

0

0 1 2 3 4 v

0 0 ∗ ∗ ∗ ∗

1 0 3 ∗ 6 ∗

2 0 3 3 6 −1

3 0 3 2 6 −1

4 0 3 2 6 −1

k 3

6 −1

−7

−2 0

3

0 3

6 −1

2 1

2

3 4

0

Algoritmos em Grafos — 1º sem 2012 9 / 1

void bellman_ford1(Digraph G, Vertex s){

1 Vertex v, w; double d;

2 for (v=0; v < G->V; v++) 3 custo[0][v] = INFINITO;

4 custo[0][s] = 0;

5 for (k=1; k < G->V; k++)

6 for (w=0; w < G->V; w++){

7 custo[k][w] = custo[k-1][w];

8 for (v=0; v < G->V; v++){

9 d=custo[k-1][v]+G->adj[v][w]; 10 if (custo[k][w] > d)

11 custo[k][w] = d;

} } }

Algoritmos em Grafos — 1º sem 2012 10 / 1

Consumo de tempo

O consumo de tempo da função bellman_ford1 é O(V3).

Algoritmos em Grafos — 1º sem 2012 11 / 1

Ciclos negativos

Se custo[k][v] 6= custo[k-1][v], então custo[k][v] é o custo de um caminho de s a v com exatamente k arcos.

Se custo[V][v] 6= custo[V-1][v], então custo[V][v] < custo[V-1][v] e

custo[V][v] é o custo de um caminho P de s a v com exatamente V arcos.

Seja C um ciclo em P e seja P0 o caminho resultante a partir de P após a remoção de C.

Algoritmos em Grafos — 1º sem 2012 12 / 1

(4)

Ciclos negativos

Note que P0 tem no ≤ V-1 arcos e portanto custo(P0) ≥ custo[V-1][v]

> custo[V][v]

= custo(P)

= custo(P0) +custo(C).

Logo, C é um ciclo de custo negativo.

Algoritmos em Grafos — 1º sem 2012 13 / 1

Conclusão

Se custo[V][v] 6= custo[V-1][v], então G tem um ciclo negativo alcançável a partir de s.

Algoritmos em Grafos — 1º sem 2012 14 / 1

void bellman_ford2(Digraph G, Vertex s){

1 Vertex v, w; double d;

2 for (v=0; v < G->V; v++) 3 cst[v] = INFINITO;

4 cst[s] = 0;

5 for (k=1; /* A */ k < G->V; k++) 6 for (v=0; v < G->V; v++){

7 for (w=0; w < G->V; w++){

8 d=cst[v]+G->adj[v][w];

9 if (cst[w] > d)

10 cst[w] = d;

} } }

Algoritmos em Grafos — 1º sem 2012 15 / 1

Relação invariante

Em /* A */ na linha vale que

cst[v] ≤ custo[k-1][v] = o menor custo de um caminho de s a v com até k-1 arcos

Algoritmos em Grafos — 1º sem 2012 16 / 1

(5)

Consumo de tempo

O consumo de tempo da função bellman_ford2 é O(V3).

Algoritmos em Grafos — 1º sem 2012 17 / 1

Bellman-Ford

void bellman_ford3(Digraph G, Vertex s){

1 Vertex v, w;

2 link p;

3 for (v=0; v < G->V; v++){

4 cst[v] = INFINITO;

5 parnt[v] = -1;

}

6 cst[s] = 0;

Algoritmos em Grafos — 1º sem 2012 18 / 1

Bellman-Ford

7 for (k=1; k < G->V; k++) 8 for (v=0;v < G->V; v++){

9 p = G->adj[v];

10 while (p != NULL) {

11 w= p->w;

12 if (cst[w] > cst[v]+p->cst){

13 cst[w]=cst[v]+p->cst;

14 parnt[w] = v;

}

15 p = p->next;

} } }

Algoritmos em Grafos — 1º sem 2012 19 / 1

Consumo de tempo

O consumo de tempo da função bellman_ford3 é O(VA).

Algoritmos em Grafos — 1º sem 2012 20 / 1

(6)

FIFO Bellman-Ford

S 21.7

Algoritmos em Grafos — 1º sem 2012 21 / 1

FIFO-Bellman-Ford

O algoritmo de Bellman e Ford pode ser divido em passos

um passo para cada valor de k (=0,1,2,. . . ).

36 36

36 36

6

36

−7 4

1

−5 −4

4 1

2

3 4

0

6

−7 4

1

−5 −4

4

0 36

36

36 36

1

2

3 4

0

Fim do passo k=0

6

−7 4

1

−5 −4

4

0 36

36

36 36

1

2

3 4

0

6

−7 4

1

−5 −4

4 0

36

36 36

4

1

2

3 4

0

6

−7 4

1

−5 −4

4

0 4

36

36 6

1

2

3 4

0

Fim do passo k=1

6

−7 4

1

−5 −4

4

0 4

36

36 6

1

2

3 4

0

6

−7 4

1

−5 −4

4

0 4

36 6

5 1

2

3 4

0

6

−7 4

1

−5 −4

4

0 4

6

5

0 1

2

3 4

0

6

−7 4

1

−5 −4

4

0 4

6

5

0 1

2

3 4

0

6

−7 4

1

−5 −4

4

0 4

6

5

0 1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

5

0 1

1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

1

−1

5 1

2

3 4

0

Fim do passo k=2

6

−7 4

1

−5 −4

4 0

6

1

−1

5 1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

1

−1

5 1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

1

−1

3 1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

1

−1

3 1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

1

−1

2 1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

1

2

−3 1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

1

2

−3 1

2

3 4

0

Fim do passo k=3

6

−7 4

1

−5 −4

4 0

6

1

2

−3 1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

1

2

−3 1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

1

2

−3 1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

1

−3

1 1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

1

−3

1 1

2

3 4

0

Fim do passo k=4

6

−7 4

1

−5 −4

4 0

6

1

−3

1 1

2

3 4

0

6

−7 4

1

−5 −4

4 0

6

1

−3

1 1

2

3 4

0

Fim do passo k=5

Algoritmos em Grafos — 1º sem 2012 22 / 1

bellman-ford

Recebe digrafo G com custos (possivelmente negativos) nos arcos e um vértice s

Se o digrafo não tem ciclo negativo alcançável a partir de s, calcula uma arborescência de caminhos mínimos com raiz s.

A arborescência é armazenada no vetor parnt As distâncias em relação a s são armazenadas no vetor cst

Algoritmos em Grafos — 1º sem 2012 23 / 1

bellman-ford

A implementação utiliza uma fila.

Supomos que em cada instante haja no máximo uma cópia de cada vértice na fila:

um vértice deve ser inserido na fila apenas se já não estiver na fila.

#define SENTINELA G–>V

#define maxV 10000;

double cst[maxV];

Vertex parnt[maxV];

void bellman-ford(Digraph G, Vertex s)

Algoritmos em Grafos — 1º sem 2012 24 / 1

(7)

bellman-ford

void bellman-ford(Digraph G, Vertex s) {

1 Vertex v, w; link p; int k=0;

2 for (v = 0; v < G->V; v++) {

3 cst[v] = maxCST;

4 parnt[v] = -1;

}

5 QUEUEinit(G->V);

6 cst[s] = 0;

7 parnt[s] = s;

8 QUEUEput(s); QUEUEput(SENTINELA);

Algoritmos em Grafos — 1º sem 2012 25 / 1

9 while (!QUEUEempty()) { 10 v = QUEUEget();

11 if (v == SENTINELA) {

12 if (k++ == G->V) return;

13 QUEUEput(SENTINELA);

} else

14 for(p=G->adj[v];p!=NULL;p=p->next) 15 if(cst[w=p->w]>cst[v]+p->cst)

16 cst[w]=cst[v]+p->cst;

17 parnt[w] = v;

18 QUEUEput(w);

} }

}

Algoritmos em Grafos — 1º sem 2012 26 / 1

Relação invariante

No início de cada iteração do while da linha 9 vale que

cst[v] ≤ custo[k][v] = o menor custo de um caminho de s a v com ≤ k arcos

Algoritmos em Grafos — 1º sem 2012 27 / 1

Ciclos negativos

11 if (v == SENTINELA) { 12 if (k++ == G->V) {

12 if (!QUEUEempty()) {

12 /* tem ciclo negativo */

12 }

12 return;

}

13 QUEUEput(SENTINELA);

}

O ciclo negativo pode ser encontrado no digrafo representado por parnt

Algoritmos em Grafos — 1º sem 2012 28 / 1

(8)

Consumo de tempo

linha número de execuções da linha 2–4 Θ(V)

5 = 1 QUEUEinit

6–7 = 1

8 = 2 QUEUEput

9–10 O(V2) QUEUEempty e QUEUEget 11 O(V2)

12 O(V)

13 ≤ V QUEUEput 14–17 O(VA)

18 O(VA) QUEUEput total = O(VA) + ???

Algoritmos em Grafos — 1º sem 2012 29 / 1

Conclusão

O consumo de tempo da função bellman-ford é O(VA) mais o consumo de tempo de

1 execução de QUEUEinit e QUEUEget, O(VA) execuções de QUEUEput,

O(V2) execuções de QUEUEempty, e O(V2) execuções de QUEUEget

Algoritmos em Grafos — 1º sem 2012 30 / 1

Conclusão

Se implementarmos a fila de tal forma que cada operação consuma tempo constante teremos:

O consumo de tempo da função bellman_ford é O(VA).

Algoritmos em Grafos — 1º sem 2012 31 / 1

Conclusão

Para todo grafo digrafo G com custo nos arcos e todo par de vértices s e t, vale uma e apenas

umas das seguintes afirmações:

não existe caminho de s a t;

existe um caminho mínimo de s a t; ou existe um caminho de s a t que contém um ciclo negativo

Algoritmos em Grafos — 1º sem 2012 32 / 1

(9)

Ciclos negativos

Problema: Dado um digrafo com custos nos arcos, decidir se o digrafo possui algum ciclo negativo.

Uma adaptação da função bellman_ford decide se um dado digrafo com custos nos arcos possui algum ciclo negativo. O consumo de tempo dessa

função adaptada é O(VA).

Algoritmos em Grafos — 1º sem 2012 33 / 1

Mais Potenciais

Algoritmos em Grafos — 1º sem 2012 34 / 1

Potenciais

Um potencial é um vetor y indexado pelos vértices do digrafo tal que

y[w]−y[v] ≤ G->adj[v][w] para todo arco v-w Exemplo:

6

−7 4

1

−5 −4

4 0

3

−4

−9

−6 1

2

3 4

0

Exemplo:

6

−7 4

1

−5 −4

4 0

6

1

−3

1 1

2

3 4

0

Algoritmos em Grafos — 1º sem 2012 35 / 1

Potenciais

Um potencial é um vetor y indexado pelos vértices do digrafo tal que

y[w] ≤ y[v] +G->adj[v][w] para todo arco v-w Exemplo:

6

−7 4

1

−5 −4

4 0

3

−4

−9

−6 1

2

3 4

0

Exemplo:

6

−7 4

1

−5 −4

4 0

6

1

−3

1 1

2

3 4

0

Algoritmos em Grafos — 1º sem 2012 36 / 1

(10)

Propriedade dos potencias

Lema da dualidade. Se P é um caminho de s a t e y é um potencial, então

custo(P) ≥ y[t]−y[s]

Exemplo:

6

−7 4

1

−5 −4

4 0

3

−4

−9

−6 1

2

3 4

0

Algoritmos em Grafos — 1º sem 2012 37 / 1

Propriedade dos potencias

Lema da dualidade. Se P é um caminho de s a t e y é um potencial, então

custo(P) + y[s] ≥ y[t]

Exemplo:

6

−7 4

1

−5 −4

4 0

3

−4

−9

−6 1

2

3 4

0

Algoritmos em Grafos — 1º sem 2012 38 / 1

Conseqüência

Se P é um caminho de s a t e y é um potencial tais que

custo(P) = y[t]−y[s],

então P é um caminho mínimo e y é um potencial tal que y[t]− y[s] é máximo

Algoritmos em Grafos — 1º sem 2012 39 / 1

Exemplo

6

−7 4

1

−5 −4

4 0

6

1

−3

1 1

2

3 4

0

Algoritmos em Grafos — 1º sem 2012 40 / 1

(11)

Teorema da dualidade

Da propriedade dos -potenciais (lema da dualidade) e da correção de dijkstra concluímos o seguinte:

Se s e t são vértices de um digrafo com custo não-negativos nos arcos e t está ao alcance de

s então

min{custo(P) : P é um st-caminho}

= max{y[t]− y[s] : y é um potencial}.

Algoritmos em Grafos — 1º sem 2012 41 / 1

Algoritmo de Floyd-Warshall

S 21.3

Algoritmos em Grafos — 1º sem 2012 42 / 1

Problema dos caminhos mínimos entre todos os pares

Problema: Dado um digrafo com custo nos arcos, determinar, para cada par de vértices s, t o custo de um caminho mínimo de s a t

Esse problema pode ser resolvido aplicando-se V vezes o algoritmo de Bellman-Ford

O consumo de tempo dessa solução é O(V2A).

Um algoritmo mais eficiente foi descrito por Floyd, baseado em uma idéia de Warshall.

O algoritmo supõe que o digrafo não tem ciclo negativo

Algoritmos em Grafos — 1º sem 2012 43 / 1

Programação dinâmica

0,1,2, . . . ,V−1 = lista dos vértices do digrafo custo[k][s][t] = menor custo de um caminho de

s a t usando vértices em {s,t,0,1, . . . ,k−1}

Recorrência:

custo[0][s][t] = G->adj[s][t]

custo[k][s][t] = min{custo[k-1][s][t],

custo[k-1][s][k-1] +custo[k-1][k-1][t]}

Se o digrafo não tem ciclo negativo acessível a partir de s, então custo[V][s][t] é o menor custo de um caminho simples de s a t

Algoritmos em Grafos — 1º sem 2012 44 / 1

(12)

void floyd_warshall (Digraph G){

1 Vertex s, t; double d;

2 for (s=0; s < G->V; s++) 3 for (t=0; t < G->V; t++)

4 custo[0][s][t] = G->adj[s][t]; 5 for (k=1; k <=G->V; k++)

6 for (s=0; s < G->V; s++)

7 for (t=0; t < G->V; t++){

8 custo[k][s][t]=custo[k-1][s][t];

9 d=custo[k-1][s][k-1]

+custo[k-1][k-1][t];

10 if (custo[k][s][t] > d) 11 custo[k][s][t] = d;

} }

Algoritmos em Grafos — 1º sem 2012} 45 / 1

Consumo de tempo

O consumo de tempo da função floyd_warshall1 é O(V3).

Algoritmos em Grafos — 1º sem 2012 46 / 1

void floyd_warshall (Digraph G){

1 Vertex s, t; double d;

2 for (s=0; s < G->V; s++) 3 for (t=0; t < G->V; t++) 4 cst[s][t] = G->adj[s][t];

5 for (k=1; k <= G->V; k++) 6 for (s=0; s < G->V; s++)

7 for (t=0; t < G->V; t++){

8 d=cst[s][k-1]+cst[k-1][t];

10 if (cst[s][t] > d)

11 cst[s][t] = d;

} } }

Algoritmos em Grafos — 1º sem 2012 47 / 1

Relação invariante

No início de cada iteração da linha 5 vale que

cst[s][t] = custo[k][s][t] = o menor custo de um caminho de s a t usando vértices em {s,t,0,1, . . . ,k−1}

Algoritmos em Grafos — 1º sem 2012 48 / 1

(13)

Novo resumo

função consumo de observação tempo

DAGmin O(V+A) digrafos acíclicos custos arbitrários dijkstra O(AlgV) custos ≥ 0, min-heap

O(V2) custos ≥ 0, fila bellman-ford O(V3) digrafos densos

O(VA) digrafos esparsos floyd-warshall O(V3) digrafos sem ciclos

negativos

O problema SPT em digrafos com ciclos negativos é NP-difícil.

Algoritmos em Grafos — 1º sem 2012 49 / 1

Referências

Documentos relacionados

Para este exemplo, caso não seja aplicada a definição de dominância e relaxando a restrição de tempo do nó (1.3 3.0 4.0), o conjunto solução obtido seria composto de 30

O algoritmo de Bellman e Ford pode ser divido em passos um passo para cada valor de

Para tanto, uma porção da cidade de Dourados foi modelada e testaram -se três diferentes algoritmos (Dijkstra, IDA* e Bellman -Ford) visando encontrar o menor

Figura 45 Comparação gráfica da taxa de escalonamento entre os algoritmos de escalonamento quando utilizado o algoritmo de roteamento Bellman-Ford de dupla

O aproveitamento da água de chuva deverá ser usado somente como água não potável e deve ser considerado como mais um recurso hídrico disponível como a água de reúso de

caminhos para desempenhar a missão que lhe cabe na sociedade. Observou-se, ainda, a atenção e perplexidade dos estudantes durante a explanação dos conceitos inerentes à

A primeira vez, no Direito Brasileiro, que a família foi tida como instituição e assegurada a sua proteção foi na Constituição de 1934, como também a

primeira foi utilizado o princípio de equivalência formal, que procura seguir a ordem das palavras que pertencem à mesma categoria gramatical do original.