Capítulo 4
Fluxo de custo mínimo

Este capítulo generaliza o problema de Gale (seção 3.1) e procura um fluxo que satisfaça demandas dos nós, respeita as capacidades dos arcos, e faça tudo isso ao menor custo possível. Para resolver o problema, o capítulo usa as ferramentas desenvolvidas na seção 3.1, no capítulo 1 (caminhos dirigidos de custo mínimo), e no capítulo 2 (fluxos de intensidade máxima).

Os ingredientes do problema são os mesmos dos capítulos anteriores: um grafo dirigido D:=(V,E), uma função-demanda (bv:vV) com valores em R, uma função-capacidade (ue:eE) com valores em R+, e uma função-custo (ce:eE) com valores em R.  [Poderíamos escrever bRV, uR+E e cRE. Seria mais realista trocar todos os R por Q, uma vez que computadores digitais não conhecem números irracionais.]  Note que u0 mas b e c não têm restrição de sinal.

(Consulte o índice remissivo e os apêndices para conferir as definições de termos técnicos.)

4.1 O problema

Um fluxo numa rede (D,b,u) é qualquer vetor (xe:eE) com valores em R+.  Um fluxo x respeita u se xu e satisfaz b se x+ = b.

(Como na seção 2.1, para cada v,  x+(v) é a quantidade de fluxo que entra em v menos a quantidade de fluxo que sai de v.)  Um fluxo x é viável se satisfaz b e respeita u.

Dada uma função-custo c, o custo de um fluxo x é o número cx. Convém lembrar que c não tem restrições de sinal: podemos ter ce<0 em alguns arcos e ce0 em outros.

Problema 4.A (fluxo de custo mínimo) Encontrar um fluxo viável de custo mínimo numa rede (D,b,u,c).

(Poderíamos dizer que esse é o problema de Gale com custos.)  Em inglês, o problema é conhecido como minimum-cost flow problem. Muitas vezes, dizemos simplesmente fluxo de custo mínimo, deixando o viável subentendido. Dizemos também que um fluxo é ótimo se for viável e tiver custo mínimo.

Uma rede de fluxo com custos é qualquer rede (D,b,u,c) que tenha os parâmetros b, u, c que acabamos de descrever. Uma tal rede é viável se tem um fluxo viável. De acordo com o lema 3.1 e o teorema de Gale (teorema 3.2), a rede é viável se e somente se b(V)=0eb(X)u+(X) para todo subconjunto X de V. (Essas condições também podem ser escritas de maneira mais simétrica: u(X) b(X) u+(X) para todo XV.)  Toda rede viável tem um fluxo de custo mínimo pois todo fluxo viável é limitado: xeu(E) para todo fluxo viável x e todo arco e.

Exemplo 4.1: Seja D o grafo dirigido com nós  p v w q  descrito abaixo por sua matriz de adjacências. A função-demanda b está representada à direita da matriz. Mais à direita, as capacidades e os custos dos arcos bem como dois diferentes fluxos viáveis, x e x. Verifique que cx=240 cx=180. Observe como é fácil conferir a viabilidade e o custo de um fluxo percorrendo as linhas da tabela.

pvwqbp112v111w1+1q+2pvpwvwvqwqu33333x02011x02102c30+80+40+9010
figs/xournalpp/my-romboid-B1.png

Exercícios 4.1

  1. Suponha que a é um arco de custo máximo na rede, ou seja, ca:=max(ce:eE). Se x é um fluxo viável de custo mínimo, é verdade que xa=0?
  2. O problema do caminho dirigido de custo mínimo (problema 1.A no capítulo 1) é um caso particular do problema fluxo de custo mínimo (problema 4.A)?
  3. Mostre que o problema do fluxo de intensidade máxima de um nó r a um s numa rede capacitada (problema 2.A no capítulo 2) é um caso particular do problema 4.A.  (Dica: acrescente arco sr ao grafo.) [CCPS 4.7]
  4. ★ Seja (D,b,u,c) uma rede viável. Mostre que a rede não é ilimitada, ou seja, tem um fluxo ótimo.
  5. Um emparelhamento num grafo não-dirigido é perfeito se incide em todos os nós. Considere o problema de encontrar um emparelhamento perfeito de custo mínimo em um grafo não-dirigido bipartido. Formule esse problema como um caso particular do problema 4.A. [CCPS 4.2]
  6. Seja D um grafo dirigido tal que o número |+(v)|+|(v)| é par em cada v. Para cada arco vw, seja cvw o custo de inverter vw (isto é, trocar vw por wv). Queremos encontrar um conjunto de arcos de custo mínimo cuja inversão faz com que D tenha um ciclo dirigido euleriano (veja exercício na seção 3.1). Formule esse problema como um caso particular do problema 4.A. [CCPS 4.5]
  7. Atribuição de terminais a concentradores. Uma rede de teleprocessamento tem um grande número de terminais geograficamente dispersos e uma CPU. É dado um conjunto de concentradores, instalados em certos lugares, sendo cada um ligado à CPU por uma linha de alta capacidade e custo nulo. Cada terminal precisa ser ligado à CPU e a ligação pode ser direta ou pode passar por um concentrador. Cada concentrador pode cuidar de até k terminais. Para cada terminal j, o custo de uma ligação direta com a CPU é dj e o custo de uma ligação com um concentrador i é dij. Queremos determinar a maneira mais barata de ligar os terminais à CPU. Formule esse problema como um caso particular do problema 4.A. [AMO 9.7]
  8. Roteamento de cargueiros vazios. Para um certo conjunto V de portos marítimos, temos os seguinte dados relativos ao ano que passou: para cada porto v, temos o número pv de toneladas de carga que entraram no porto e o número qv de toneladas de carga que saíram do porto. Em cada porto v, a diferença bv:=pvqv é uma medida do suprimento de cargueiros vazios em v e bv é uma medida da demanda por cargueiros vazios em v. Cada cargueiro vazio saiu de um porto v em que bv é positivo e foi para um porto w em que bw é negativo. Se a distância do porto v ao porto w é de cvw milhas, o deslocamento de v a w de um cargueiro vazio com capacidade para t toneladas representa um desperdício de tcvw tone­la­das×milha. Queremos organizar a movimentação de cargueiros vazios de modo a minimizar o desperdício total anual. [Sch17 p.73]

4.2 Programação linear

Na linguagem da programação linear, o problema do fluxo de custo mínimo (problema 4.A) pode ser formulado assim:  encontrar um vetor real (xv:vV) que

(1)minimizecxsujeito ax+(v)=bvpara cada vVxeuepara cada eExe0para cada eE.

(Convém lembrar que podemos ter ce0 em alguns arcos e ce<0 em outros.)  Esse programa linear pode ser escrito assim em termos da matriz de incidências A do grafo D: minimizecxsujeito aAx = bx  ux  0.

O dual desse pl consiste em encontrar vetores reais (yv:vV) e (ze:eE) que maximizemyb+zusujeito ayA+z  cz  0

e esse dual pode ser escrito por extenso assim: encontrar y e z que (2)maximizemyb+zusujeito aywyv+zvwcvwpara vwEzvw0para vwE.

Para qualquer solução viável x do pl (1) e qualquer solução viável (y,z) do pl (2) temos então (3)cx  (yA+z)x = (yA)x+zx = y(Ax)+zx  yb+zu.

Se cx=yb+zu então x é solução ótima de (1) e (y,z) é solução ótima de (2).teorema forte da dualidade garante a recíproca: se os dois pl's são viáveis então existe x viável no primal e existe (y,z) viável no dual tais que cx=yb+zu. Essa igualdade equivale às condições de folgas complementares:

Lema 4.1 (folgas complementares) Para qualquer solução viável x do pl (1) e qualquer solução viável (y,z) do pl (2), a igualdade  cx=yb+zu  vale se e somente se

  1. xvw=0  ou  ywyv+zvw=cvw   e
  2. xvw=uvw  ou  zvw=0

para cada arco vw.

Prova: Temos cx=yb+zu em (3) se e somente se cx=(yA+z)x e y(Ax)+zx=yb+zu. A primeira igualdade vale se e somente se xe=0 ou (yA)e+ze=ce para cada arco e. (O ou não é exclusivo.) A segunda igualdade vale se e somente se zx=zu, e esta última vale se e somente se ze=0 ou xe=ue para cada arco e. ■

As condições 1 e 2 de folgas complementares podem também ser formuladas assim: para cada arco vw,

  1.   se  xvw>0  então  ywyv+zvw=cvw  e
  2.   se  xvw<uvw  então  zvw=0.

Segue daí imediatamente que se  0<xvw<uvw  então  ywyv=cvw.

Algoritmo. Poderíamos resolver o problema 4.A submetendo o programa linear (1) ao algoritmo Simplex. Mas isso é ineficiente, uma vez que o Simplex, que foi projetado para programas lineares arbitrários, não leva em conta as muitas peculiaridades do pl (1).

Exercícios 4.2

  1. Verifique que o pl (2) é dual do pl (1).
  2. ★ Mostre que o pl dual (2) é viável, ou seja, exiba alguma solução viável (y,z) do pl.
  3. Suponha que b(V)0 numa rede (D,b,u,c) de fluxo com custos. Mostre que o pl (1) é inviável nesse caso. Mostre que o pl dual (2) é ilimitado nesse caso (ou seja, yb+zu não tem máximo).
  4. Suponha que b(X)>u+(X) para algum XV. Mostre que pl (1) é inviável nesse caso. Mostre que o pl dual (2) é ilimitado nesse caso (isto é, yb+zu não tem máximo).
  5. A leitura descuidada das condições no enunciado do lema 4.1 pode levar a interpretações erradas. Qual a diferença entre as duas afirmações a seguir?  Afirmação A: para cada vw temos xvw=0 ou ywyv+zvw=cvw.  Afirmação B: temos xvw=0 para cada vw ou temos ywyv+zvw=cvw para cada vw.
  6. Enuncie o problema do fluxo viável de custo máximo. Escreva o pl do problema. Escreva o pl dual. Como poderíamos usar um algoritmo para o problema 4.A para resolver o problema do fluxo viável de custo máximo?

4.3 Condições de otimalidade

Obtida uma solução x do problema do fluxo de custo mínimo (problema 4.A), que informação é possível apresentar para certificar a minimalidade de cx?  Como o problema 4.A é idêntico ao programa linear (1), qualquer solução viável (y,z) do pl dual (2) que satisfaça a igualdade yb+zu=cx é um excelente certificado.

Alternativamente, podemos exibir uma solução viável (y,z) que satisfaz as condições de folgas complementares do lema 4.1. Melhor ainda: podemos omitir z e exibir apenas um vetor y apropriado, como mostra o seguinte teorema. Para enunciar o teorema, convém usar a palavra potencial para designar qualquer vetor (yv:vV) com valores em R.

Teorema 4.2 (condições de otimalidade) Um fluxo viável x numa rede (D,b,u,c) é ótimo se e somente se existe um potencial y que satisfaz duas condições em cada arco vw:

  1. xvw=0  ou  ywyvcvw   e
  2. xvw=uvw  ou  ywyvcvw.

Prova: Para provar a parte se, suponha que y é um potencial que satisfaz as condições 1 e 2. Seja z o vetor definido por (4)zvw:=min(0,cvwyw+yv)

para cada arco vw. Em outras palavras, se ywyvcvw então zvw:=0, senão zvw:= cvwyw+yv. Observe que o par (y,z) é solução viável do pl (2). Além disso, para cada arco vw, temos xvw=0 ou ywyv+zvw=cvw bem como xvw=uvw ou zvw=0.lema 4.1 garante agora que cx=yb+zu e portanto x minimiza cx.

Para provar o somente se, suponha que x minimiza cx. De acordo com o teorema forte da dualidade, existe uma solução viável (y,z) do pl (2) tal que cx=yb+zu. De acordo com o lema 4.1, temos

  1. xvw=0 ou ywyv+zvw=cvw   e
  2. xvw=uvw ou zvw=0

para cada arco vw. Como ywyv+zvwcvw e zvw0 em (2), as condições 1 e 2 estão satisfeitas. ■

Para algumas aplicações, é conveniente colocar as condições 1 e 2 do teorema 4.2 na seguinte forma: para cada arco vw,

  1. se  xvw>0  então  ywyvcvw   e
  2. se  xvw<uvw  então  ywyvcvw.

Custo reduzido

A desigualdade ywyvcvw na condição 2 é familiar: ela caracteriza os arcos relaxados no problema do caminho de custo mínimo (seção 1.2). O número cvw(ywyv) é conhecido como custo reduzido do arco vw. Usaremos a notação c¯vw:=cvw(ywyv).

[Essa notação deixa a desejar pois esconde a dependência do potencial y. Quem sabe deveríamos escrever cvwy.]  Com essa notação, poderemos apresentar as condições de otimalidade do teorema 4.2 de forma mais memorável: para cada arco e,

  1. se  xe>0  então  c¯e0   e
  2. se  xe<ue  então  c¯e0.

Isso tem a seguinte consequência:  se  0<xe<ue  então  c¯e=0.

Exemplo 4.2: Considere a rede (D,b,u,c) do exemplo 4.1. Veja novamente a matriz de adjacências de D e o vetor de demandas b. À direita de b temos um potencial y. Mais à direita, um fluxo viável x (diferente dos fluxos do exemplo 4.1), o custo c dos arcos, e o custo reduzido c¯ associado a y.

pvwqbyp11210v11140w1+10q+210pvpwvwvqwqu33333x20302c30+80+40+9010c¯0+700+600
figs/xournalpp/my-romboid-B1.png

O fluxo x e o potencial y satisfazem as condições de otimalidade. Portanto, x é um fluxo ótimo e y é um certificado de otimalidade, conforme o teorema 4.2. (Embora isso seja redundante, podemos calcular o vetor z definido em (4) e verificar que cx=+40=yb+zu.)

Exercícios 4.3

  1. Seja y um potencial arbitrário numa rede D(b,u,c) e c¯ o correspondente custo reduzido. Mostre que c¯=cyA, sendo A a matriz de incidências do grafo G.
  2. Custo versus custo reduzido. Seja x um fluxo que satisfaz b e y é um potencial arbitrário. Seja c¯ o custo reduzido associado a y. Mostre que c¯x=cxyb.

4.4 Ciclos de aumento

Dado um fluxo viável x numa rede (D,b,u,c), como obter um novo fluxo viável mais barato? Usaremos um mecanismo análogo ao dos caminhos de aumento do algoritmo de Ford–Fulkerson (seção 2.5).

Para qualquer ciclo C em D, seja É(C) o conjunto dos arcos diretos de C e È(C) o conjunto dos arcos inversos. Um ciclo C é compatível com um fluxo viável x se xe<ue para cada e em É(C) e xe>0 para cada e em È(C).

largura de C é o maior número ϵ tal que xe+ϵue para cada e em É(C) e xeϵ0 para cada e em È(C). A operação de enviar ϵ unidades de fluxo ao longo do ciclo C consiste em somar ϵ a xe para cada e em É(C) e subtrair ϵ de xe para cada e em È(C). Se ϵ for menor ou igual à largura de C, o envio ϵ unidades de fluxo ao longo de C produz um novo fluxo viável x. O custo de x será cx+ϵc(C), sendo c(C):=c(É(C))c(È(C)).

O número c(C) é o custo de C. Se esse custo for negativo e ϵ for positivo, o fluxo x será mais barato que x. Por isso, qualquer ciclo compatível com x que tenha custo negativo é chamado ciclo de aumento.  (Quem sabe deveríamos dizer ciclo de decremento, já que o custo do fluxo diminui.)

Exemplo 4.3: No exemplo 4.1, o ciclo induzido por (v,w,q,v) é compatível com o fluxo x e tem largura 1. O custo do ciclo é 401090=60 e portanto o ciclo é de aumento. Se enviarmos 1 unidade de fluxo ao longo desse ciclo teremos o fluxo viável x do exemplo 4.1. Observe que cx=cx60×1=24060=180.

Ainda no exemplo 4.1, o ciclo (p,v,w,p) é compatível com o fluxo x e tem largura 2. O custo do ciclo é 30+4080=70 e portanto trata-se de um ciclo de aumento. Se enviarmos 2 unidades de fluxo ao longo desse ciclo teremos o fluxo viável x abaixo. Observe que cx=cx70×2=180140=40.

pvpwvwvqwqc30+80+40+9010x20302

O seguinte teorema mostra que a ausência de ciclos de aumento caracteriza fluxos ótimos:

Teorema 4.3 (dos ciclos de aumento) Um fluxo viável x numa rede (D,b,u,c) é ótimo se e somente se não existe ciclo de aumento para x.

Prova: Considere inicialmente a parte somente se do teorema. Suponha que o custo de x é mínimo. Se existisse um ciclo de aumento, poderíamos usar esse ciclo, como indicado acima, para obter um novo fluxo viável de custo menor que cx. Portanto, um tal ciclo não existe.

Agora considere a parte se do teorema, ou seja, suponha que não existe ciclo de aumento para x. Gostaríamos de usar os resultados do capítulo 1, desenvolvidos para caminhos e ciclos dirigidos, para mostrar que x tem custo mínimo. Para fazer isso, será preciso construir uma rede auxiliar (D,c) que chamaremos residual. O grafo dirigido residual D é definido da seguinte maneira. O conjunto de nós de D é D{r}, sendo r um novo nó. Para cada arco vw de D tal que xvw<uvw, há um arco vw de custo cvw=cvw em D. Para cada arco vw de D tal que xvw>0, há um

arco  wv  de custo cwv=cvw

em D. (Se 0<xvw<uvw então D tem arcos vw e wv.)  Finalmente, para cada v de D, o grafo residual D tem um arco rv de custo crv=0. É fácil entender a relação entre D e D: todo ciclo C em D que é compatível com x corresponde a um ciclo dirigido C em D, e vice-versa. Ademais, o custo de C em D é igual ao custo de C em D.

Submeta a rede (D,c), com nó inicial r, ao algoritmo de Ford para caminhos dirigidos de custo mínimo (seção 1.3). Por hipótese, a rede não tem ciclo dirigido de custo negativo. Portanto, de acordo com o teorema de Ford–­Bellman (teorema 1.5), o algoritmo produzirá um potencial viável, ou seja, um potencial y tal que ywyvcvw para cada arco vw de D.

Agora considere as propriedades do potencial y no grafo dirigido original D. Se xvw<uvw então vw é um arco de D e cvw=cvw, donde ywyvcvw, e portanto o custo reduzido de vw não é negativo: c¯vw0. Por outro lado, se xvw>0 então wv é um arco de D e cwv=cvw, donde yvywcwv. Logo ywyvcvw, e portanto c¯vw0. Assim, o par (x,y) satisfaz as condições de otimalidade (seção 4.3). Isso garante que x é ótimo. ■

Exemplo 4.4: Seja D o grafo dirigido descrito abaixo por sua matriz de adjacências. À direita da matriz, temos as demandas b. Mais à direita, as capacidades u, os custos c, e um fluxo viável x. O ciclo induzido por (c,b,a,c) é de aumento. Envie 1 unidade de fluxo ao longo do ciclo. O novo fluxo é ótimo?

abcdba1113b11+1c1+1d+1abacadbcbdcdu999999c+20+20+20+10+10+10x300110
figs/xournalpp/tetrahedron-B2.png

(No nosso problema 4.A, as capacidades dos arcos são finitas. Mas imagine por um momento que permitíssemos capacidades infinitas. Então a presença de um ciclo de aumento dirigido — um ciclo de aumento C com È(C)= levaria a fluxos viáveis de custo arbitrariamente negativo e tornaria essa instância ilimitada.)

Soluções inteiras

Muitas aplicações precisam de fluxos x que são inteiros e de potenciais y que são inteiros. Surpreendentemente, tais fluxos e potencias existem sempre que os parâmetros da rede são inteiros.

Teorema 4.4 (fluxo inteiro) Seja (D,b,u,c) uma rede que tem um fluxo viável. Se b e u são inteiros então existe um fluxo ótimo que é inteiro.

Esboço da prova: Dentre os fluxos viáveis inteiros, escolha um fluxo x para o qual cx é o menor possível. Se existisse um ciclo de aumento para x, poderíamos enviar uma quantidade inteira de fluxo ao longo do ciclo e assim produzir um novo fluxo viável inteiro de custo menor que cx. Logo, não existe ciclo de aumento. Então a prova do teorema dos ciclos de aumento (teorema 4.3) mostra que existe um potencial y que satisfaz as condições de otimalidade. Logo, cxcx para todo fluxo viável x, inteiro ou não. Portanto, x é ótimo. ■

Teorema 4.5 (dual inteiro) Seja x um fluxo ótimo numa rede (D,b,u,c). Se c é inteiro então o pl (2) tem uma solução ótima (y,z) que é inteira.

Prova: Como mostra a prova do teorema dos ciclos de aumento (teorema 4.3) e a análise dos algoritmos de caminhos dirigidos mínimos no capítulo 1, existe um potencial y tal que, para cada v, o número yv é o custo de um caminho dirigido de custo mínimo de r a v na rede residual (D,c). Como c é inteiro, todos esses custos são inteiros. Assim, o vetor y e vetor z definido em (4) são inteiros. Ademais, (y,z) satisfaz as condições de otimalidade descritas no teorema 4.2 e portanto (y,z) é solução ótima do pl (2). ■

Exercícios 4.4

  1. ★ Seja x um fluxo viável numa rede (D,b,u,c). Seja ϵ a largura de um ciclo C compatível com x. Prove que o envio de ϵ unidades de fluxo ao longo de C produz um novo fluxo viável. Prove que o custo do novo fluxo é cx+c(C)ϵ, sendo c(C):=c(É(C))c(È(C)).
  2. A figura mostra um fluxo viável x numa rede (D,b,u,c). Os três números ao lado de cada arco e são ce,ue,xe. O custo do fluxo é cx=25. Encontre um ciclo de aumento. Calcule um fluxo viável de custo menor que o de x.  Parte 2: Exiba um fluxo viável de custo mínimo e um potencial que prove a otimalidade do fluxo. [CCPS fig.4.1]
  3. Considere a rede de fluxo (D,b,u,c) da figura. Ao lado de cada nó v vemos a demanda bv. Ao lado de cada arco e vemos os números ce,ue,xe. Verifique que x é um fluxo viável. Prove que existe um fluxo viável de custo menor que cx ou prove que x é ótimo. [CCPS 4.8]
  4. Rede residual. Considere o exemplo 4.1. Faça uma figura da rede residual correspondente ao fluxo x. Faça uma figura da rede residual correspondente ao fluxo x.
  5. Caminhos dirigidos disjuntos. Sejam r e s dois nós de um grafo dirigido D. Queremos encontrar uma coleção de k caminhos dirigidos de r a s, sem arcos em comum, que use o menor número possível de arcos. Formule esse problema como um caso particular do problema 4.A. Repita o problema com caminhos dirigidos sem nós em comum exceto r e s. [AMO 11.8]
  6. Considere o grafo dirigido D definido pela matriz de adjacências abaixo. À direita da matriz, uma função-demanda b, as capacidades u e custos c dos arcos. Não confunda o nó b com a função-custo b. Encontre um fluxo ótimo x na rede (D,b,u,c). Encontre um potencial y que satisfaça as condições de otimalidade do teorema 4.2. Calcule os custos reduzidos c¯. Faça uma tabela de resultados para que seja fácil comparar x com c¯ e assim conferir a validade das folgas complementares. [AMO 9.22]
    abcdeba1125b110c10d+25e110abaebcbecdecedu25201025202025c+7+6+4+5+1+2+2
  7. A figura mostra um potencial y numa rede de fluxo (D,b,u,c). Ao lado de cada nó v vemos os números bv e yv. Ao lado de cada arco e vemos os números ce e ue. Encontre um fluxo viável x que satisfaça as condições de otimalidade do teorema 4.2. [CCPS 4.9]

4.5 Algoritmo dos ciclos de aumento

O algoritmo abaixo, proposto por Kantorovich em 1942, usa ciclos de aumento para resolver o problema do fluxo de custo mínimo (problema 4.A) como sugerido na seção 4.4. O algoritmo obtém um primeiro fluxo viável resolvendo a instância apropriada do problema de Gale (seção 3.1). A partir daí, cada iteração começa com um fluxo viável x e tenta transformar x num fluxo viável x de custo menor que cx. 

Kantorovich (D, b, u, c)
01 . x Gale(D, b, u)
02 . se x indefinido
03 .ooo então pare   instância inviável
04 . repita
05 .ooo C Ciclo­De­Aumento(D,u,c,x)
06 .ooo se C indefinido
07 .oooooo então y Potencial(D,u,c,x)
08 .oooooo então devolva x e y e pare   fluxo ótimo
09 .ooo ϵ1min(uexe:eÉ(C))
10 .ooo ϵ2min(xe:eÈ(C))
11 .ooo ϵmin(ϵ1,ϵ2)
12 .ooo x Envia­Fluxo(D,x,C,ϵ)

A rotina Gale com argumentos (D,b,u) devolve um fluxo x que satisfaz b e respeita u. Se tal fluxo não existe, x fica indefinido. Na linha 03, o algoritmo poderia devolver um conjunto de nós que viola as condições de Gale antes de parar.

A rotina Ciclo­De­Aumento na linha 05 devolve um ciclo de aumento para x. Para implementar a rotina, podemos usar as ideias contidas na prova do teorema 4.3. Se não existe ciclo de aumento, C fica indefinido e o fluxo x é ótimo.

A rotina Potencial na linha 07 recebe um fluxo ótimo x e calcula um potencial y que satisfaz as condições de otimalidade do teorema 4.2.

A rotina Envia­Fluxo na linha 12 atualiza x enviando ϵ unidades de fluxo ao longo do ciclo C, conforme discussão no início da seção 4.4.

Número de iterações. Se os vetores b, u, e c são racionais e a rede (D,b,u,c) é viável, o número de iterações do algoritmo Kantorovich é finito, a exemplo do que acontece com o algoritmo de Ford–Fulkerson para o problema do fluxo máximo (seção 2.5).

O algoritmo Kantorovich é útil para redes muito pequenas, quando pode ser executado com lápis e papel. Para redes grandes, entretanto, o algoritmo é ineficiente pois cada iteração consome muito tempo e o número de iterações pode aumentar explosivamente com o número de nós da rede. Isso acontece pelos mesmos motivos que tornam ineficiente o algoritmo de Ford–Fulkerson.

Exercícios 4.5

  1. Escreva em código a rotina Envia­Fluxo.
  2. ★ Faça um esboço da implementação das rotinas Ciclo­De­Aumento e Potencial do algoritmo de Kantorovich. (Sugestão: As duas rotinas são, na verdade, uma só. Veja a prova do teorema 4.3 e a seção 1.5.)
  3. A figura mostra uma rede com capacidades (em negrito) e custos (em itálico) nos arcos. Os nós s e t têm demandas 11 e 11 respectivamente. Os demais nós têm demanda 0. Calcule um fluxo viável de custo mínimo. Prove que o fluxo é ótimo. [Sch17 4.16i]

4.6 Algoritmo Simplex para redes de transbordo

O algoritmo Kantorovich (algoritmo dos ciclos de aumento) é lento e ineficiente. Para obter um algoritmo mais rápido, é preciso encontrar uma maneira mais eficiente de procurar ciclos de aumento. Discutiremos uma tal maneira ao longo das próximas seções. A ideia básica é representar o fluxo por meio de uma subárvore da rede. Essa ideia será introduzida a seguir no contexto de uma versão simplificada do problema 4.A, versão esta conhecida como problema do transbordo.

Uma rede de transbordo é uma rede de fluxo em que não há restrições de capacidade nos arcos. [Acredito que a palavra transbordo poderia ser substituída por baldeação. De qualquer forma, não vale a pena discutir a etimologia do termo transshipment.]  Mais formalmente, uma rede de transbordo (= transshipment network) é uma rede (D,b,c) em que b é uma função-demanda nos nós e c é uma função-custo nos arcos. O custo de um fluxo x é o número cx.

Problema 4.B (do transbordo) Dada uma rede de transbordo (D,b,c), encontrar um fluxo que satisfaz b e tem custo mínimo.

Podemos imaginar que o problema 4.B é o caso especial do problema 4.A em que ue= para todo arco e. (É preciso forçar um pouco a imaginação, pois o enunciado do problema 4.A não permite arcos de capacidade infinita.)

O primeiro passo para resolver uma instância do problema 4.B é obter algum fluxo que satisfaz b. Uma rede (D,b) tem um fluxo que satisfaz b se e somente se

  1. b(V)=0 e
  2. b(X)0 para todo XV tal que +(X)=.

Isso é consequência do que observamos acima sobre o problema 4.A bem como de um exercício na seção 3.1.

Um fluxo x que satisfaz b numa rede de transbordo (D,b,c) é ótimo se não existe fluxo x que satisfaz b e tem custo menor que o de x.  A adaptação do teorema 4.2 ao problema 4.B toma a seguinte forma:

Teorema 4.6 (condições de otimalidade) Um fluxo x que satisfaz b numa rede de transbordo (D,b,c) é ótimo se e somente se existe um potencial y tal que

  1. se xvw>0 então ywyv=cvw  e
  2. se xvw=0 então ywyvcvw

para cada arco vw. ■

Deduzir o teorema 4.6 do teorema 4.2 é um bom exercício.

Fluxos induzidos por árvores. Vamos procurar uma solução do problema 4.B entre os fluxos que fluem por alguma árvore da rede. Começamos por definir a terminologia necessária.

Uma árvore de um grafo dirigido D é uma árvore orientada T tal que V(T)=V(D) e E(T)E(D). (Num outro contexto, diríamos que T é uma árvore geradora de D.)

Para garantir que as redes em estudo tenham árvores, restringimos a atenção, daqui em diante, a redes conexas. Para redes não conexas, o problema 4.B pode ser resolvido separadamente em cada componente conexa.

Uma árvore T da rede (D,b) é viável se E(T) contém o suporte de algum fluxo que satisfaz b. Como mostra o seguinte lema, existe no máximo um fluxo dotado dessa propriedade:

Lema 4.7 Numa rede (D,b) com árvore T, se T é viável então E(T) inclui o suporte de um único fluxo que satisfaz b.

Prova: Seja T uma árvore viável e x um fluxo que satisfaz b e cujo suporte é subconjunto de E(T). Para cada arco ij de T, seja Tj a componente conexa de Tij que contém j. Em virtude do lema 2.1 no capítulo 2 (com Tj no papel de R), temos (5)xij=b(Tj) para cada arco ij de T. Aqui, b(Tj) é uma abreviatura de b(V(Tj)). Agora suponha que x é outro fluxo que satisfaz b e tem suporte em E(T). Se repetirmos o argumento que acabamos de fazer veremos que xij=b(Tj) para cada arco ij. Logo, x=x. ■

Diremos que o único fluxo descrito no lema 4.7 é induzido por T. Para calcular o fluxo induzido por T podemos usar (5). Mas há um algoritmo mais eficiente, que chamaremos Fluxo­Induzido. Ao receber uma árvore viável T, o algoritmo escolhe uma folha j de T, aplica o algoritmo recursivament a Tj depois de modificar b, e finalmente define o valor do fluxo no único arco de T que incide em j. É um bom exercício escrever o código do algoritmo.

Nem toda árvore de uma rede (D,b) é viável. Para provar que uma dada árvore T não é viável, basta observar que b(V)0 ou exibir um arco ij de T tal que b(Tj)0, sendo Tj a componente conexa de Tij que contém j.

Potenciais induzidos por árvores. Para certificar a otimalidade de um fluxo, usamos um potencial apropriado. Quando o fluxo é induzido por uma árvore, o potencial pode ser facilmente calculado a partir da árvore.  Dada uma árvore T de uma rede (D,c), um potencial induzido por T é qualquer potencial y tal que

cij=yjyi  para cada arco ij de T, como indicamos a seguir.

É fácil calcular um tal potencial. Comece com uma folha j de T. Se o único arco incidente a j é ij, calcule o potencial y de Tj e depois estenda esse potencial a T adotando yj:=yi+cij. Se o único arco incidente a j for ji, calcule o potencial y de Tj e depois estenda esse potencial a T adotando yj:=yicji. Vamos nos referir a esse algoritmo como PotencialInduzido. Formalizar o algoritmo é um bom exercício.

Um potencial induzido por uma árvore é quase único: se y e y são dois potenciais induzidos então a diferença yiyi é a mesma para todos os nós i. Como trabalhamos apenas com a diferença de potencial entre nós, podemos viver com a ilusão de que existe um só potencial induzido e trocar a expressão um potencial induzido pela expressão o potencial induzido.

O potencial induzido por uma árvore mede os custos de caminhos na árvore, como mostraremos a seguir. O custo de um caminho P numa rede (D,c) é o número c(P):= c(É(P))c(È(P)), sendo É(P) o conjunto dos arcos diretos de P e È(P) o conjunto dos arcos inversos.

Lema 4.8 Suponha que y é o potencial induzido por uma árvore T de numa rede (D,c). Para quaisquer dois nós r e s de T tem-se  ysyr=c(P),  sendo P o único caminho simples de r a s em T.

Prova: Se P tem um só nó então a afirmação é trivialmente verdadeira. Agora suponha que P=(v0,e0,v1,e1,,ek1,vk) com k>0. Para cada vi, seja yi uma abreviatura de yvi e ci uma abreviatura de cei. Seja P o caminho Pvk e suponha, a título de hipótese de indução, que yk1y0= c(P). Se ek1 é um arco direto de P, ou seja, se ek1=vk1vk, então c(P)= c(P)+ck1= yk1y0+ykyk1= yky0. Se ek1 é um arco inverso de P, ou seja, se ek1=vkvk1, então c(P)= c(P)ck1= yk1y0(yk1yk)= yky0. ■

Para trazer a ideia de circuito de aumento para o presente contexto, é preciso estabelecer a relação entre o potencial induzido e o custo de ciclos que têm apenas um arco fora de uma dada árvore. Faremos isso no lema 4.9 abaixo, que decorre do lema 4.8.

Dada uma árvore T de D e um arco vw de E(D)E(T), o ciclo fundamental de T+vw é o único ciclo do grafo T+vw no qual o arco vw é direto. O custo desse ciclo fundamental é igual ao custo reduzido  cvwyw+yv  de vw:

Lema 4.9 Suponha que y é o potencial induzido por uma árvore T de uma rede (D,c) e seja c¯ o correspondente custo reduzido. Então c¯ij=0 para todo arco ij de T e

c¯vw=c(C)

para todo arco vw fora de T, sendo C o ciclo fundamental de T+vw.

Prova: Por definição de y, temos c¯ij=0 para todo arco ij de T. Agora tome um arco vw que não pertence a T. Seja P o caminho de w a v em T. É claro que C=P+vw. Pelo lema 4.8, yvyw= C(P). Logo, c(C)= c(P)+cvw= yvyw+cvw= c¯vw. ■

Algoritmo Simplex-para-transbordo

O terreno está preparado para um algoritmo que resolve o problema 4.B trabalhando apenas com fluxos em árvores. O algoritmo, que chamaremos Simplex-para-transbordo (= Trans­ship­ment­Simplex), pode ser visto como uma versão especializada do algoritmo Simplex de programação linear (seção C.4).

O algoritmo Simplex-para-transbordo recebe uma rede de transbordo (D,b,c) tal que D é conexo e b(V)=0 e devolve

  1. um fluxo x e um potencial y que satisfazem as condições de otimalidade enunciadas no teorema 4.6, ou
  2. a informação de que a rede não tem fluxo que satisfaz b, ou
  3. a informação de que a rede não tem fluxo que satisfaz b e tem custo mínimo.
Trans­ship­ment­Simplex (D, b, c)   b(V)=0 e (a) e (b) abaixo
01 . T Árvore­Viável (D, b)
02 . repita
03 .ooo x FluxoInduzido (T,b)
04 .ooo y PotencialInduzido (T,c)
05 .ooo seja c¯ o custo reduzido associado a y
06 .ooo se c¯0
07 .oooooo então devolva x e y e pare   fluxo ótimo
08 .ooo escolha um arco e tal que c¯e<0
09 .ooo seja C o ciclo fundamental de T+e
10 .ooo ϵmin(xh:hÈ(C))   torcemos por ϵ>0
11 .ooo se ϵ=
12 .oooooo então pare   instância ilimitada
13 .ooo escolha h em È(C) tal que xh=ϵ
14 .ooo TT+eh

No começo de cada iteração (linha 02), T é uma árvore viável da rede.

No fim da linha 05, x é o fluxo induzido por T, y é o potencial induzido por T, e c¯e=0 para todo arco e de T.  No linha 07, x e y satisfazem as condições de otimalidade enunciadas no teorema 4.6 e portanto x é um fluxo ótimo.

No fim da linha 09, o custo de C é negativo em virtude do lema 4.9. Na linha 11, a condição ϵ= é equivalente a È(C)= e portanto o ciclo C é dirigido, o que mostra que a rede não tem fluxo de custo mínimo.

Na linha 13, C é um ciclo de aumento. Se enviarmos ϵ unidades de fluxo ao longo de C, o valor do fluxo no arco h será reduzido a zero.

Na linha 14, o arco h é removido de T e o arco e é acrescentado a T. No fim da linha 14, T é uma árvore viável. (Por quê?)  Durante a linha 14, o número ϵc¯vw é implicitamente subtraído do custo do fluxo x.

No fim da linha 14, poderíamos atualizar os valores de x, y, e c¯ evitando assim a necessidade de recalculá-los no início da iteração seguinte (linhas 03 a 05 do código). (No caso de x, por exemplo, bastaria enviar ϵ unidades de fluxo ao longo do ciclo C.)

Resta discutir a linha 01. Esta é a parte suja do algoritmo. A rotina Árvore­Viável deve produzir uma árvore viável, conhecida como solução inicial, ou decidir que uma tal árvore não existe e apresentar um conjunto de nós que viola a condições de Gale da seção 3.1.  Não há uma maneira limpa de implementar a rotina Árvore­Viável. Adotaremos o truque sujo clássico de forçar a existência de uma árvore viável. Para isso, suporemos que, em relação a um certo nó r da rede,

  1. existe um arco vr para cada nó vr tal que b(v)<0 e
  2. existe um arco rw para cada nó wr tal que b(w)0.

Essas hipóteses garantem uma árvore viável trivial: o conjunto de arcos da árvore é E1E2, sendo E1:={vr:b(v)<0} e E2:={rw:b(w)0}. Essa árvore inicial é viável uma vez que, por hipótese, b(V)=0.

Se a rede não tiver todos os arcos exigidos por (a) e (b), basta acrescentar os arcos faltantes atribuindo-lhes custo ; diremos que esses arcos são artificiais.  (É bem verdade que a formulação do problema 4.B supõe que todos os custos são finitos, mas vamos aceitar esse desvio sem fazer escândalo. Poderíamos também trocar por um número suficientemente grande.)  Se o algoritmo devolver um fluxo cujo suporte contém arcos artificiais, saberemos que a rede original (sem os arcos artificiais) não tem fluxo que satisfaz b.

Exemplo 4.5: Considere a rede de transbordo (D,b,c) descrita a seguir. O grafo dirigido D é dado por sua matriz de adjacências. A função-demanda b e os custos c dos arcos são dadas nas tabelas.

pvwqbp113v11+2w11q+2pvpwvwvqwqc+10+30+10+10+10
figs/xournalpp/my-romboid-B1.png

Suponha que a primeira iteração do algoritmo Trans­ship­ment­Simplex começa a árvore T indicada em magenta na tabela abaixo. A tabela também registra o fluxo x e o potencial y induzidos por T, bem como os custos reduzidos c¯. O custo do fluxo é cx=70.

pvpwvwvqwqx21002c¯0010200yp0v+10w+30q+40

O algoritmo escolhe o arco vw e envia 1 unidade de fluxo ao longo do ciclo induzido por (v,w,p,v). O novo fluxo terá custo cx=7010×1=60. O arco vw é acrescentado a T e o arco pw é retirado de T.

A segunda iteração começa com a árvore T indicada abaixo em magenta. A tabela dá o fluxo induzido x, o potencial induzido y, e o custo reduzido c¯. O fluxo tem custo cx=60.

pvpwvwvqwqx30102c¯0+100100yp0v+10w+20q+30

O algoritmo escolhe o arco vq e envia 1 unidade de fluxo ao longo do ciclo (v,q,w,v). O novo fluxo terá custo cx=6010×1=50.

A terceira iteração começa a árvore T, o fluxo x, e o potencial y indicados a seguir:

pvpwvwvqwqx30011c¯00+1000yp0v+10w+10q+20

Como c¯0, a execução do algoritmo termina.  Para detetar eventuais erros de cálculo cometidos durante a execução do algoritmo, convém verificar que cx=yb.

Número de iterações. No fim da linha 14, o custo do fluxo induzido por T é cx+ϵc¯e, sendo c¯e<0 (veja a seção 4.4 e o lema 4.9).  Se ϵ>0, o novo fluxo será mais barato que o anterior e assim o algoritmo terá feito algum progresso. Se ϵ=0, o fluxo não se altera, embora a árvore T seja modificada. Se isso acontece, a iteração é considerada degenerada. É claro que uma iteração é degenerada se a árvore T no início da iteração tiver um arco vazio, ou seja, um arco e tal que xe=0. Diremos que uma tal árvore é degenerada.

É possível, no pior caso, que o algoritmo comece com uma árvore T0, execute algumas iterações degeneradas, e volte à árvore T0.  Essa sequência de iterações pode então se repetir para sempre e a execução do algoritmo não para mais. Portanto, Trans­ship­ment­Simplex não é um algoritmo no sentido pleno da palavra.

Mesmo que não tenhamos iterações degeneradas, entretanto, o número de iterações pode ser muito grande pois o algoritmo pode ser levado a examinar todas as árvores da rede.

Felizmente, esses cenários de pior caso são muito raros. Na prática, o número de iterações é relativamente pequeno. Por isso, o algoritmo é bastante usado em aplicações no mundo real.

Viabilidade forte. Apesar das considerações que acabamos de fazer, é desejável evitar que o número iterações seja infinito. Para isso, basta que no início de cada iteração a árvore viável T seja mais que viável, no sentido que passamos a definir.

Antes de começar a execução do algoritmo, escolha um nó r (arbitrário mas fixo) para fazer o papel de raiz. No início de cada iteração, para cada j, seja Pj o único caminho simples de r a j em T. A árvore (viável) T é considerada fortemente viável se o fluxo induzido por T tem a seguinte propriedade: cada arco vazio de T aponta para longe de r, ou seja, se ij é um arco vazio de T então ij é um arco direto de Pj.

Suponha agora que T é fortemente viável no início de uma iteração. Para que a árvore Te+h no início da linha 14 do código também seja fortemente viável, é preciso escolher o arco h na linha 13 do código como passamos a explicar. Seja s o nó de C que está mais próximo de r em T, isto é, o último nó comum aos caminhos Pv e Pw. Percorra o ciclo fundamental C a partir de s e escolha para h (6)o primeiro arco em È(C) que tenha xh=ϵ.

Com isso, a árvore T+eh será fortemente viável.

Se T é fortemente viável no início de todas as iterações, a execução de Trans­ship­ment­Simplex termina depois de um número finito de iterações.

Resta apenas encontrar uma maneira de fazer com que a primeira árvore viável (linha 01 do código) seja fortemente viável. Isso é um bom exercício.

Exemplo 4.6: Considere a rede de transbordo (D,b,c) descrita a seguir. (Não confunda o nó b com a função-demanda b.)  O grafo dirigido D é dado por sua matriz de adjacências. Complete a figura usando o gabarito de posição dos nós. A função-demanda b e os custos c dos arcos são dados nas tabelas.

abcdefba114b10c111d110e1+1f+4abacbecdcedbdfefc+20+50+60+30+30+30+20+30 beafcd

A primeira iteração do algoritmo Trans­ship­ment­Simplex começa com a árvore T indicada abaixo em magenta. A tabela dá o fluxo induzido x, o potencial induzido y, e o correspondente custo reduzido c¯. O custo do fluxo é cx=560.

abacbecdcedbdfefx40510104c¯0+90009001000ya+10b+30c30d0e+90f+120

O algoritmo escolhe o arco ce e envia 1 unidade de fluxo ao longo do ciclo induzido por (c,e,b,d,c). Os arcos cd e db ficam vazios. O primeiro sai da árvore mas o segundo continua na árvore. O novo fluxo tem custo cx= 56090×1= 470.

A segunda iteração começa com os dados a seguir. A árvore viável é degenerada.

abacbecdcedbdfefx40401004c¯000+90001000ya+10b+30c+60d0e+90f+120

O algoritmo escolhe o arco df e portanto o ciclo (d,f,e,b,d). Apenas 0 unidades de fluxo podem ser enviadas ao longo do ciclo. A iteração é degenerada. O fluxo x não se altera mas o arco df é arescentado a T e o arco db é retirado em T.  A terceira iteração começa com os dados indicados a seguir:

abacbecdcedbdfefx40401004c¯000100+10000ya90b70c40d0e10f+20

O algoritmo escolhe o arco cd e envia 1 unidade de fluxo ao longo do ciclo (c,d,f,e,c). O novo fluxo tem custo cx=47010×1=460.  A quarta iteração começa com os seguintes dados:

abacbecdcedbdfefx40410013c¯01000+10+10000ya90b70c30d0e10f+20

O algoritmo escolhe o arco ac e envia 3 unidades de fluxo ao longo do ciclo (a,c,d,f,e,b,a). O novo fluxo tem custo cx=46010×3=430.  A quinta iteração começa com os seguintes dados:

abacbecdcedbdfefx13140040c¯00000+900+10ya80b60c30d0e0f+20

Como c¯0, a execução do algoritmo termina.

Exemplo 4.7: Considere a rede de transbordo (D,b,c) descrita a seguir. O grafo dirigido D é dado por sua matriz de adjacências. (Faça uma figura.) Os custos c, o potencial y, e o custos reduzidos c¯ foram omitidos. Adote o nó r como raiz e suponha que c¯ij<0.

rijklpqbr12i111j+1k1+1l110p+1q10rlijkjlklpqpiqx2012011

Execute uma iteração do Trans­ship­ment­Simplex começando com a árvore viável T= {rl,kj,lk,lp,qp,iq}. Note que T é fortemente viável. O algoritmo escolhe o arco ij pois c¯ij<0. O ciclo fundamental de T+ij é (i,j,k,l,p,q,i). A largura do ciclo é 1. Qualquer um dos arcos kj, qp, iq poderia ser removido de T para dar lugar a ij. Para garantir que a nova árvore viável seja fortemente viável, o algoritmo remove o arco qp.

Exemplo 4.8: Considere a rede de transbordo (D,b,c) descrita a seguir. O grafo dirigido D é dado por sua matriz de adjacências. (Faça uma figura.) A função-demanda b e os custos c dos arcos são dadas nas tabelas. Adote o nó p como raiz. [CCPS fig.4.10]

pvwqbp+10v11110w1110q+10vpwpvwvqwqc+10+10+10+10+20

A primeira iteração do Trans­ship­ment­Simplex começa com a árvore viável T indicada a seguir (os arcos de T estão destacados em magenta). A árvore é degenerada mas fortemente viável. O fluxo induzido tem custo cx=30.

vpwpvwvqwqx10001c¯0+100200yp0v10w0q+20

O algoritmo escolhe o arco vq. A sequência de nós do correspondente ciclo fundamental, escrita a partir do nó mais próximo da raiz, é (v,q,w,v). Como ϵ=0, a iteração é degenerada. O envio de 0 unidades de fluxo ao longo do ciclo não altera o fluxo mas altera a árvore viável.

A segunda iteração começa com uma árvore viável degenerada mas fortemente viável. O fluxo induzido tem custo cx=30.

vpwpvwvqwqx10001c¯010+2000yp0v10w20q0

O algoritmo escolhe o arco wp. O correspondente ciclo fundamental, a partir do nó mais próximo da raiz, é (p,v,q,w,p). Temos ϵ=1 e o arco vp faz o papel de h. O envio de 1 unidade de fluxo ao longo do ciclo produz um novo fluxo de custo cx=3010×1=20.

A terceira iteração começa com uma árvore viável degenerada mas fortemente viável. (Se a iteração anterior tivesse escolhido h=wq, a árvore não seria fortemente viável.)

vpwpvwvqwqx0100100c¯+100000yp0v0w10q+10

Como c¯0, a execução do algoritmo termina.

Exercícios 4.6

  1. ★ Prove o teorema 4.6 a partir do teorema 4.2.
  2. Em que condições uma instância do problema do transbordo (problema 4.B) é inviável? Em que condições é ilimitada?
  3. Seja x um fluxo num grafo dirigido conexo D. Suponha que todo ciclo (dirigido ou não) em D tem um arco vazio, isto é, um arco e tal que xe=0. Mostre que existe uma árvore T de D tal que o suporte de x é subconjunto de E(T).
  4. Fluxo viável implica fluxo arbóreo. Suponha que uma rede conexa (D,b) tem um fluxo que satisfaz b. Prove que o suporte de algum fluxo que satisfaz b é subconjunto de alguma árvore da rede.  Parte 2: Suponha que uma rede conexa (D,b,c) tem um fluxo ótimo e prove que o suporte de algum fluxo ótimo é subconjunto de alguma árvore da rede.
  5. ★ Complete os detalhes da prova do lema 4.7.
  6. FluxoInduzido.  Escreva um algoritmo que receba uma árvore viável T de uma rede (D,b) e devolva o único fluxo em T que satisfaz b.
  7. Escreva uma versão completa do algoritmo FluxoInduzido. O algoritmo deve receber uma árvore T e uma função-demanda b tal que b(V)=0 e devolver o único fluxo em T que satisfaz b ou uma prova de que tal fluxo não existe. A prova consiste em um arco kl de T tal que b(Tl)<0.
  8. PotencialInduzido.  Escreva um algoritmo que receba uma árvore T de uma rede (D,c) e devolva o potencial induzido por T.

Mais exercícios

  1. Custo de arcos artificiais, Seja (D,b,c) uma rede de transbordo com arcos arficiais. Atribua custo 1+|V|max{|ce|:eE} a cada arco artificial. Suponha que o algoritmo Simplex-para-Trans­bordo termina com fluxo não nulo em algum arco artificial. Mostre que a instância original do problema (antes da introdução dos arcos artificiais) não tem fluxo viável. [CCPS 4.21]
  2. Resolva a instância do problema do transbordo indicada na figura. Use o algoritmo Trans­ship­ment­Simplex. Os números junto aos nós são as demandas b. Os números nos arcos são os custos c. Comece com o fluxo x induzido pela árvore viável T representada pelas linhas contínuas. [CCPS 4.22]
  3. Solução inicial no Simplex-para-transbordo. Escreva uma implementação da rotina Árvore­Viável sob as hipóteses (a) e (b). Prove que sua implementação está correta.
  4. Solução inicial no Simplex-para-transbordo. Discuta a seguinte ideia de implementação da rotina Árvore­Viável. 1. Calcule um fluxo x em (D,b) que satisfaz b como sugere a seção 3.1, que trata do problema de Gale. (É assim que começa o algoritmo Kantorovich.)  2. Se houver um ciclo em que todos os arcos têm fluxo positivo, envie fluxo ao longo do ciclo de modo a anular o fluxo em algum arco. 3. Repita o processo até que o suporte de x seja subconjunto do conjunto de arcos de uma árvore). 4. Extraia uma árvore T do suporte de x.
  5. Árvore fortemente viável inicial. Encontre uma maneira de construir a árvore viável T na linha 01 de Trans­ship­ment­Simplex de modo que ela seja fortemente viável.
  6. Mostre como representar T de maneira eficiente no algoritmo Trans­ship­ment­Simplex. Mostre como os valores x, y, e c¯ podem ser calculados, a cada iteração, a partir dos valores de x, y, e c¯ na iteração anterior (evitando assim que os valores sejam calculadas diretamente a partir de T). [CCPS 4.23]
  7. No algoritmo Trans­ship­ment­Simplex, suponha que T é fortemente viável no início de uma iteração em que ϵ=0. Mostre que h estará em Pw (e não em Pv). Mostre que h será o último arco direto vazio de Pw.
  8. Exemplo 4.6. Analise o exemplo 4.6. Adote o nó d como raiz e verifique que no início de cada iteração do algoritmo a árvore viável T é fortemente viável.
  9. Mostre que toda árvore não-degenerada é fortemente viável.
  10. De fortemente viável a fortemente viável. Suponha que T é fortemente viável e h é escolhido de acordo com a regra (6). Mostre que no início da linha 14 de Trans­ship­ment­Simplex a árvore viável T+eh é fortemente viável.
  11. O número de iterações é finito. Seja r a raiz de D e defina y na linha 04 de Trans­ship­ment­Simplex de modo que yr=0 (e portanto yv=c(Pv) para cada v). Suponha que T é fortemente viável no início de uma iteração e seja Y o valor da soma (yv:vV) no fim da linha 04. Suponha que ϵ é nulo nessa iteração. Prove que na próxima iteração, no fim da linha 04, a soma (yv:vV) será menor que Y. Deduza daí que o número de iterações degeneradas é finito.

4.7 Algoritmo Simplex para redes arbitrárias

O algoritmo Simplex-para-redes (= Network Simplex) é uma generalização do algoritmo Simplex-para-transbordo discutido na seção anterior. O algoritmo resolve o problema do fluxo de custo mínimo (problema 4.A). Esse é o algoritmo mais usado na prática para resolver o problema.

Tripartições arbóreas e fluxo induzido. Para apresentar o Simplex-para-redes, é preciso generalizar os conceitos que introduzimos para tratar do Simplex-para-transbordo.

Uma tripartição arbórea de um grafo D é um terno (T,L,U) em que T é uma árvore de D e (E(T),L,U) é uma partição do conjunto de arcos de D. Para garantir que as redes em estudo tenham árvores, restringimos a atenção a redes conexas daqui em diante.

Como no início do capítulo, um fluxo numa rede (D,b,u) é viável se satisfaz b e respeita u. Em relação a um fluxo viável x, diremos que um arco e está vazio se xe=0 e está cheio se xe=ue.  (Se ue=0, o arco e está simultaneamente vazio e cheio. Pode ser conveniente remover tais arcos da rede — o que certamente não afeta o problema 4.A — e passar a supor que ue>0 para cada arco e.)

Uma tripartição arbórea (T,L,U) da rede (D,b,u) é viável se algum fluxo viável em (D,b,u) deixa todos os arcos de L vazios e todos os arcos de U cheios.  (Nada impede que esse mesmo fluxo deixe alguns arcos de T vazios e alguns arcos de T cheios.)  Segue do lema 4.7 que existe no máximo um tal fluxo:

Lema 4.10 Para qualquer tripartição arbórea (T,L,U) de uma rede (D,b,u), existe no máximo um fluxo viável que deixa os arcos de L vazios e os arcos de U cheios. ■

Dizemos que o único fluxo viável a que se refere o lema 4.10 é induzido por (T,L,U), Se o fluxo induzido deixa algum arco de T vazio ou algum arco cheio, dizemos que a tripartição (T,L,U) é degenerada.

Potenciais induzidos por tripartições arbóreas. Numa rede (D,c), um potencial y é induzido por uma tripartição arbórea (T,L,U) se  cvw=ywyv  para cada arco vw de T. Tal como no caso das redes de transbordo, toda tripartição arbórea tem um potencial induzido e esse potencial é essencialmente único.

Seja (T,L,U) uma tripartição arbórea do grafo D. Para cada e em L,ciclo fundamental de T+e é o único ciclo em T+e no qual e é um arco direto.  Para cada e em U,ciclo fundamental de T+e é o único ciclo em T+e no qual e é um arco inverso. O seguinte lema generaliza o lema 4.9:

Lema 4.11 Seja (T,L,U) uma tripartição arbórea de uma rede (D,b,c). Seja y o potencial induzido pela tripartição e c¯ o custo reduzido associado a y. Para cada arco e,

sendo C o ciclo fundamental de T+e.

Esboço da prova: Basta generalizar a prova do lema 4.9, que trata apenas de redes de transbordo. ■

Algoritmo Simplex-para-redes

Ao receber uma rede (D,b,u,c) com D conexo e b(V)=0, o algoritmo Simplex-para-redes produz uma tripartição arbórea viável (T,L,U) e um potencial y que satisfazem as condições

sendo c¯ o custo reduzido associado a y. De acordo com teorema 4.2 (veja a formulação alternativa do teorema), o fluxo x induzido por (T,L,U) é ótimo.

O algoritmo consiste em duas cópias do algoritmo Simplex-para-transbordo trabalhando simultaneamente: uma cópia normal, idêntica à discutida na seção anterior, que cuida da restrição x0, e uma cópia invertida que cuida da restrição xu.

figs/web/valette-playing-card.jpg
Network­Simplex (D,b,u,c)   D conexo e b(V)=0
01 . (T,L,U) Tripar­tição­Arbó­rea­Viável(D,b,u)
02 . se (T,L,U) é indefinida
03 .ooo então pare   rede inviável
04 . repita
05 .ooo seja x o fluxo induzido por (T,L,U)
06 .ooo seja y um potencial induzido por (T,L,U)
07 .ooo seja c¯ o custo reduzido associado a y
08 .ooo se c¯e0 quando eL e c¯e0 quando eU
09 .oooooo então devolva (T,L,U) e y e pare   fluxo ótimo
10 .ooo escolha eL tal que c¯e<0 ou eU tal que c¯e>0
11 .ooo seja C o ciclo fundamental de T+e
12 .ooo ϵmin(uhxh:hÉ(C))
13 .ooo ϵmin(xh:hÈ(C))
14 .ooo se ϵ<ϵ
15 .oooooo então escolha h em É(C) tal que uhxh=ϵ
16 .oooooo senão escolha h em È(C) tal que xh=ϵ
17 .ooo TT+eh
18 .ooo se eL então LLe senão UUe
19 .ooo se hÉ(C) então UU+h senão LL+h

No começo de cada iteração (linha 04), (T,L,U) é uma tripartição arbórea viável.

A rotina Tripar­tição­Arbó­rea­Viável na linha 01 deve produzir uma tripartição arbórea viável. Se tal tripartição não existe, a rede não admite fluxo viável.

Não há uma maneira limpa de implementar a rotina Tripar­tição­Arbó­rea­Viável. Um truque sujo clássico consiste em escolher um r, arbitrário mas fixo, e acrescentar à rede (a) um arco vr para cada nó vr tal que b(v)<0 e (b) um arco rw para cada nó wr tal que b(w)0. Esses arcos artificiais devem ter capacidade infinita e custo infinito. Feito isso, considere a árvore T com conjunto de arcos E1E2, sendo E1:={vr:b(v)<0} e E2:={rw:b(w)0}, e seja L conjunto E(D)E(T). Agora, (T,L,) é uma tripartição arbórea viável.

Se o algoritmo Network­Simplex terminar com um fluxo cujo suporte contém arcos artificiais, saberemos que a rede original não tem fluxo viável.

Exemplo 4.9: Considere a rede (D,b,u,c) descrita a seguir. O grafo dirigido D é dado por sua matriz de adjacências. A função-demanda b e os custos c dos arcos são dadas nas tabelas.

pvwqbp114v110w1+2q+2pvpwvwvqwqu1c+10+20+8+20+20
figs/xournalpp/my-romboid-B1.png

A primeira iteração do algoritmo Network­Simplex começa com a tripartição arbórea viável (T,L,U) indicada abaixo. Os arcos de T estão indicados em magenta, os arcos de L estão sublinhados, e U é vazio. Veja na tabela o fluxo x e o potencial y induzidos pela tripartição.

pvpwvwvqwqx22020c¯0020+10yp0v+10w+20q+30

O algoritmo escolhe o arco vw e envia 1 unidades de fluxo ao longo do ciclo induzido por (v,w,p,v). O arco vw fica cheio e é transferido de L para U. A tripartição (T,L,U) não se altera. O novo fluxo terá custo cx=1002×1=98.

A segunda iteração começa com a tripartição arbórea (T,L,U) indicada abaixo com uma barra acima dos arcos de U.  [Pode ser necessário aumentar ou diminuir (Ctrl+ ou Ctrl-) o tamanho da fonte no seu browser para que a barra fique visível.]  O fluxo tem custo cx=98.

pvpwvwvqwqx31120c¯0020+10yp0v+10w+20q+30

Como c¯e0 para todo e em L e c¯e0 para todo e em U, o fluxo x é ótimo e a execução do algoritmo termina.

Por via dúvidas, convém verificar que cx= yb+zu. (Essa é uma boa maneira de detetar eventuais erros de cálculo cometido durante a execução do algoritmo.) O vetor ze=min(0,c¯e) está indicado abaixo:

pvpwvwvqwqz00200

Portanto, cx=98=1002=yb+zu, como deveria ser.

Consumo de tempo. O algoritmo Network­Simplex, tal como Trans­ship­ment­Simplex, pode executar um número infinito de iterações, embora tal evento seja muito raro na prática. Para evitar que isso aconteça, basta fazer o seguinte: (i) antes de iniciar a execução do algoritmo, escolha um nó r como raiz; (ii) adote yr=0 em todas as iterações; (iii) tome providências para que a tripartição arbórea (T,L,U) seja fortemente viável no início de cada iteração.

Uma tripartição arbórea viável (T,L,U) é fortemente viável se o fluxo induzido pela tripartição tem a seguinte propriedade: cada arco ij de T que está vazio aponta para longe da raiz (ou seja, ij é um arco de Pj), e cada arco ij de T que está cheio aponta na direção da raiz (ou seja, ij é um arco de Pi).

Exercícios 4.7

  1. Seja (D,b) uma rede conexa. Mostre que um fluxo x é induzido por uma tripartição arbórea se e somente se todo ciclo de D tem um arco vazio ou um arco cheio (ou ambos).
  2. Fluxo viável implica fluxo arbóreo. Suponha que uma rede (D,b,u) tem um fluxo viável e prove que a rede também tem um fluxo viável induzido por alguma tripartição arbórea. Parte 2: Suponha que uma rede (D,b,u,c) tem um fluxo ótimo e prove que a rede também tem um fluxo ótimo induzido por alguma tripartição arbórea. [CCPS 4.27]
  3. Prove o lema 4.10.
  4. Escreva um algoritmo que receba uma tripartição arbórea (T,L,U) de uma rede (D,b,u), decida se a tripartição é viável, e em caso afirmativo calcule o fluxo induzido pela tripartição.
  5. Dê condições necessárias e suficientes para que uma tripartição arbórea (T,L,U) seja viável.

Mais exercícios

  1. ★ Prove o lema 4.11.
  2. ★ É possível ter h=e no começo da linha 17 do Network­Simplex? Como o algoritmo se comporta nesse caso?
  3. Tripartição arbórea inicial. Eis um truque feio mas efetivo para calcular a tripartição (T,L,U) inicial na linha 01 de Network­Simplex. Antes de invocar o algoritmo, acrescente a D um novo r e novos arcos da seguinte maneira: para cada nó v com bv<0, acrescente um novo arco vr; para cada v tal que bv0, acrescente um novo arco rv. Seja B+ o conjunto dos novos arcos do tipo vr e B o conjunto dos novos arcos do tipo rv. Cada novo arco deve ter custo M e capacidade . A constante M deve ser positiva e muito grande. Seja T:=B+B. Adote fluxo xvr:=bv para cada vrB+ e fluxo xrv:=bv para cada rvB. Faça L igual ao conjunto dos arcos originais e faça U igual a . A tripartição arbórea (T,L,U) é fortemente viável se tomarmos r como raiz. Como o custo M é muito grande, nenhum dos arcos artificiais estará na árvore produzida por Network­Simplex.