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
,
uma função-demanda
com valores em ,
uma função-capacidade
com valores
em ,
e uma função-custo
com valores em .
[Poderíamos escrever
,
e .
Seria mais realista trocar todos os
por ,
uma vez que computadores digitais
não conhecem números irracionais.]
Note que
mas e
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
é qualquer vetor
com valores em .
Um fluxo respeita
se e
satisfaz se
(Como na seção 2.1,
para cada nó ,
é a quantidade de fluxo que entra em
menos a quantidade de fluxo que sai de .)
Um fluxo é viável
se satisfaz e respeita .
Dada uma função-custo ,
o custo
de um fluxo é o número .
Convém lembrar que não tem restrições de sinal:
podemos ter em alguns arcos e em outros.
Problema 4.A (fluxo de custo mínimo)
Encontrar um fluxo viável
de custo mínimo numa rede .
(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 que tenha os parâmetros
, ,
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
para todo subconjunto de .
(Essas condições também podem ser escritas
de maneira mais simétrica:
para todo .)
Toda rede viável tem um fluxo de custo mínimo
pois todo fluxo viável é limitado:
para todo fluxo viável
e todo arco .
Exemplo 4.1:
Seja o grafo dirigido
com nós descrito abaixo
por sua matriz de adjacências.
A função-demanda está representada à direita da matriz.
Mais à direita,
as capacidades e os custos dos arcos
bem como dois diferentes fluxos viáveis, e .
Verifique que
e
.
Observe como é fácil conferir a viabilidade e o custo de um fluxo
percorrendo as linhas da tabela.
Exercícios 4.1
-
Suponha que é um arco de custo máximo na rede, ou seja,
.
Se é um fluxo viável de custo mínimo, é verdade que ?
-
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)?
-
Mostre que o problema do fluxo de intensidade máxima
de um nó a um nó
numa rede capacitada
(problema 2.A no capítulo 2)
é um caso particular do problema 4.A.
(Dica: acrescente arco ao grafo.)
[CCPS 4.7]
-
★
Seja uma rede viável.
Mostre
que a rede não é ilimitada,
ou seja, tem um fluxo ótimo.
-
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]
-
Seja um grafo dirigido
tal que o número é par em cada nó .
Para cada arco ,
seja o custo de inverter
(isto é, trocar por ).
Queremos encontrar um conjunto de arcos de custo mínimo
cuja inversão faz com que 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]
-
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é terminais.
Para cada terminal , o custo de uma ligação direta com a CPU é
e o custo de uma ligação com um concentrador é .
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]
-
★
Roteamento de cargueiros vazios.
Para um certo conjunto de portos marítimos,
temos os seguinte dados
relativos ao ano que passou:
para cada porto , temos
o número de toneladas de carga que entraram no porto e
o número de toneladas de carga que saíram do porto.
Em cada porto ,
a diferença é uma medida do suprimento de cargueiros vazios
em
e é uma medida da demanda por cargueiros vazios
em .
Cada cargueiro vazio saiu de um porto em que é positivo
e foi para um porto em que é negativo.
Se a distância do porto ao porto é de milhas,
o deslocamento de a
de um cargueiro vazio com capacidade para toneladas
representa um desperdício de toneladasmilha.
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 que
(Convém lembrar que podemos ter
em alguns arcos e em outros.)
Esse programa linear pode ser escrito assim em termos da
matriz de incidências
do grafo :
O dual desse pl
consiste em encontrar vetores reais
e que
e esse dual pode ser escrito por extenso assim:
encontrar e que
Para qualquer solução viável
do pl
e qualquer solução viável do pl
temos então
Se então é solução ótima
de
e é solução ótima
de .
O teorema forte da dualidade
garante a recíproca:
se os dois pl's
são viáveis então
existe viável no primal
e existe viável no dual
tais que .
Essa igualdade equivale às
condições de folgas complementares:
Lema 4.1 (folgas complementares)
Para qualquer solução viável do pl
e qualquer solução viável do pl ,
a igualdade vale se e somente se
-
ou
e
-
ou
para cada arco .
Prova:
Temos em
se e somente se
e .
A primeira igualdade vale se e somente se
ou para cada arco .
(O ou
não é exclusivo.)
A segunda igualdade vale se e somente se ,
e esta última vale se e somente se ou
para cada arco . ■
As condições 1 e 2 de folgas complementares
podem também ser formuladas assim:
para cada arco ,
-
se então
e
-
se então .
Segue daí imediatamente que
se então
.
Algoritmo.
Poderíamos resolver o
problema 4.A
submetendo o programa linear
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 .
Exercícios 4.2
-
Verifique que o pl
é dual do pl .
-
★
Mostre que o pl dual
é viável,
ou seja, exiba alguma solução viável do pl.
-
Suponha que numa rede de fluxo com custos.
Mostre que o pl
é inviável nesse caso.
Mostre que o pl
dual
é
ilimitado nesse caso
(ou seja, não tem máximo).
-
Suponha que para algum .
Mostre que pl é inviável nesse caso.
Mostre que o pl dual
é
ilimitado nesse caso
(isto é, não tem máximo).
-
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 temos ou .
Afirmação B:
temos para cada ou
temos para cada .
-
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 do problema do fluxo de custo mínimo
(problema 4.A),
que informação
é possível apresentar para certificar a minimalidade
de ?
Como o problema 4.A é idêntico ao
programa linear ,
qualquer solução viável
do pl dual
que satisfaça a igualdade é um excelente certificado.
Alternativamente,
podemos exibir uma solução viável
que satisfaz as condições de folgas complementares
do lema 4.1.
Melhor ainda:
podemos omitir e exibir apenas um vetor apropriado,
como mostra o seguinte teorema.
Para enunciar o teorema, convém usar a palavra potencial
para designar qualquer vetor
com valores em .
Teorema 4.2 (condições de otimalidade)
Um fluxo viável numa rede é ótimo
se e somente se
existe um potencial
que satisfaz duas condições em cada arco :
-
ou
e
-
ou .
Prova:
Para provar a parte se
, suponha que é um potencial
que satisfaz as condições 1 e 2.
Seja o vetor definido por
para cada arco .
Em outras palavras, se então ,
senão
.
Observe que o par é solução viável
do pl .
Além disso, para cada arco , temos
ou
bem como
ou .
O lema 4.1
garante agora que e portanto minimiza .
Para provar o somente se
,
suponha que minimiza .
De acordo com o teorema forte da dualidade,
existe uma solução viável do
pl
tal que .
De acordo com o lema 4.1,
temos
-
ou e
-
ou
para cada arco .
Como e
em ,
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 ,
-
se então
e
-
se então .
Custo reduzido
A desigualdade
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
é conhecido como custo reduzido
do arco .
Usaremos a notação
[Essa notação deixa a desejar
pois esconde a dependência do potencial .
Quem sabe deveríamos escrever .]
Com essa notação, poderemos apresentar as condições de otimalidade do
teorema 4.2
de forma mais memorável:
para cada arco ,
-
se então
e
-
se então .
Isso tem a seguinte consequência:
se então
.
Exemplo 4.2:
Considere a rede do
exemplo 4.1.
Veja novamente a matriz de adjacências de
e o vetor de demandas .
À direita de temos um potencial .
Mais à direita, um fluxo viável
(diferente dos fluxos do
exemplo 4.1),
o custo dos arcos,
e o custo reduzido associado a .
O fluxo e o potencial satisfazem as
condições de otimalidade.
Portanto, é um fluxo ótimo e é um certificado de otimalidade,
conforme o teorema 4.2.
(Embora isso seja redundante,
podemos calcular o vetor definido
em
e verificar que .)
Exercícios 4.3
-
Seja um potencial arbitrário numa rede
e o correspondente custo reduzido.
Mostre que ,
sendo a matriz de incidências do grafo .
-
★
Custo versus custo reduzido.
Seja um fluxo que satisfaz e é um potencial arbitrário.
Seja o custo reduzido associado a .
Mostre que .
4.4 Ciclos de aumento
Dado um fluxo viável numa rede
,
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
em ,
seja o conjunto dos
arcos diretos
de e
o conjunto dos arcos
inversos.
Um ciclo é compatível com um fluxo viável
se para cada em
e para cada em .
A largura de é o maior número tal que
para cada em
e para cada em .
A operação de enviar unidades de fluxo ao longo do ciclo
consiste em
somar a para cada em
e subtrair de para cada em .
Se for menor ou igual à largura de ,
o envio unidades de fluxo ao longo de
produz um novo fluxo viável .
O custo de será
,
sendo
O número é o custo de .
Se esse custo for negativo e for positivo,
o fluxo será mais barato que .
Por isso, qualquer ciclo compatível com 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
é compatível com o fluxo e tem largura .
O custo do ciclo é e portanto o ciclo é de aumento.
Se enviarmos unidade de fluxo ao longo desse ciclo
teremos o fluxo viável do
exemplo 4.1.
Observe que .
Ainda no exemplo 4.1,
o ciclo é compatível com o fluxo
e tem largura .
O custo do ciclo é
e portanto trata-se de um ciclo de aumento.
Se enviarmos unidades de fluxo ao longo desse ciclo
teremos o fluxo viável abaixo.
Observe que .
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 numa rede é ótimo
se e somente se
não existe ciclo de aumento
para .
Prova:
Considere inicialmente a parte somente se
do teorema.
Suponha que o custo de é 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 .
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 .
Gostaríamos de usar os resultados do capítulo 1,
desenvolvidos para caminhos e ciclos
dirigidos,
para mostrar que tem custo mínimo.
Para fazer isso, será preciso construir uma rede auxiliar
que chamaremos residual.
O grafo dirigido residual
é definido da seguinte maneira.
O conjunto de nós de é ,
sendo um novo nó.
Para cada arco de tal que ,
há um arco de custo em .
Para cada arco de tal que ,
há um
arco de custo
em .
(Se então tem arcos e .)
Finalmente, para cada nó de ,
o grafo residual tem um arco de custo .
É fácil entender a relação entre e :
todo ciclo em que é compatível com
corresponde a um ciclo dirigido em , e vice-versa.
Ademais, o custo de em é igual ao custo de em .
Submeta a rede ,
com nó inicial ,
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 tal que
para cada arco de .
Agora considere as propriedades do potencial
no grafo dirigido original .
Se então é um arco de
e ,
donde ,
e portanto o custo reduzido de não é negativo:
Por outro lado, se então é um
arco de e
,
donde .
Logo ,
e portanto
Assim, o par satisfaz as
condições de otimalidade
(seção 4.3).
Isso garante que é ótimo. ■
Exemplo 4.4:
Seja o grafo dirigido descrito abaixo
por sua matriz de adjacências.
À direita da matriz, temos as demandas .
Mais à direita,
as capacidades ,
os custos , e um fluxo viável .
O ciclo induzido por é de aumento.
Envie unidade de fluxo ao longo do ciclo.
O novo fluxo é ótimo?
(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 com —
levaria a fluxos viáveis de custo arbitrariamente negativo
e tornaria essa instância ilimitada.)
Soluções inteiras
Muitas aplicações precisam de fluxos que são
inteiros
e de potenciais 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 uma rede que tem um fluxo viável.
Se e são inteiros então existe um fluxo ótimo que é inteiro.
Esboço da prova:
Dentre os fluxos viáveis inteiros,
escolha um fluxo para o qual
é o menor possível.
Se existisse um ciclo de aumento para ,
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 .
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 que satisfaz as
condições de otimalidade.
Logo,
para todo fluxo viável ,
inteiro ou não.
Portanto, é ótimo. ■
Teorema 4.5 (dual inteiro)
Seja um fluxo ótimo numa rede .
Se é inteiro então
o pl
tem uma solução ótima 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 tal que,
para cada ,
o número é o custo de um caminho dirigido de custo mínimo de a
na rede
residual .
Como é inteiro,
todos esses custos são inteiros.
Assim, o vetor e vetor definido
em
são inteiros.
Ademais,
satisfaz as condições de otimalidade descritas no
teorema 4.2
e portanto é solução ótima do
pl . ■
Exercícios 4.4
-
★
Seja um fluxo viável numa rede .
Seja a largura de um ciclo compatível com .
Prove que o envio de unidades de fluxo ao longo de
produz um novo fluxo viável.
Prove que o custo do novo fluxo é ,
sendo .
-
A figura mostra um fluxo viável numa rede .
Os três números ao lado de cada arco são .
O custo do fluxo é .
Encontre um ciclo de aumento.
Calcule um fluxo viável de custo menor que o de .
Parte 2: Exiba um fluxo viável de custo mínimo e um potencial que prove
a otimalidade do fluxo.
[CCPS fig.4.1]
-
Considere a rede de fluxo da figura.
Ao lado de cada nó vemos a demanda .
Ao lado de cada arco vemos os números .
Verifique que é um fluxo viável.
Prove que existe um fluxo viável de custo menor que
ou prove que é ótimo.
[CCPS 4.8]
-
Rede residual.
Considere o exemplo 4.1.
Faça uma figura da rede residual correspondente ao fluxo .
Faça uma figura da rede residual correspondente ao fluxo .
-
Caminhos dirigidos disjuntos.
Sejam e dois nós de um grafo dirigido .
Queremos encontrar uma coleção de caminhos dirigidos de a ,
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 e .
[AMO 11.8]
-
Considere o grafo dirigido definido pela matriz de adjacências abaixo.
À direita da matriz, uma função-demanda ,
as capacidades e custos dos arcos.
Não confunda o nó com a função-custo .
Encontre um fluxo ótimo na rede .
Encontre um potencial que satisfaça as condições de otimalidade
do teorema 4.2.
Calcule os custos reduzidos .
Faça uma tabela de resultados
para que seja fácil comparar com
e assim conferir a validade das
folgas complementares.
[AMO 9.22]
-
A figura mostra um potencial numa rede de fluxo
.
Ao lado de cada nó vemos os números e .
Ao lado de cada arco vemos os números e .
Encontre um fluxo viável 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
e tenta transformar num fluxo viável
de custo menor que .
Kantorovich
|
01
.
Gale
|
02
.
se indefinido
|
03
.ooo
então pare
|
04
.
repita
|
05
.ooo
CicloDeAumento
|
06
.ooo
se indefinido
|
07
.oooooo
então Potencial
|
08
.oooooo
então devolva e e pare
|
09
.ooo
|
10
.ooo
|
11
.ooo
|
12
.ooo
EnviaFluxo
|
A rotina Gale com argumentos
devolve um fluxo que satisfaz e respeita .
Se tal fluxo não existe, 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 CicloDeAumento
na linha 05
devolve um ciclo de aumento
para .
Para implementar a rotina, podemos usar as ideias contidas
na prova do teorema 4.3.
Se não existe ciclo de aumento, fica indefinido
e o fluxo é ótimo.
A rotina Potencial
na linha 07 recebe um fluxo ótimo e
calcula um potencial
que satisfaz as condições de otimalidade
do teorema 4.2.
A rotina EnviaFluxo
na linha 12 atualiza
enviando unidades de fluxo ao longo do ciclo ,
conforme discussão no início da
seção 4.4.
Número de iterações.
Se os vetores ,
, e são
racionais
e a rede é 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
-
Escreva em código a rotina EnviaFluxo.
-
★
Faça um esboço da implementação das rotinas CicloDeAumento
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.)
-
A figura mostra uma rede com capacidades (em negrito) e custos (em itálico)
nos arcos.
Os nós e têm demandas e respectivamente.
Os demais nós têm demanda .
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 em que
é uma função-demanda nos nós
e é uma função-custo nos arcos.
O custo de um fluxo é o número .
Problema 4.B (do transbordo)
Dada uma rede de transbordo ,
encontrar um fluxo que satisfaz
e tem custo mínimo.
Podemos imaginar que o problema 4.B é o caso especial
do problema 4.A
em que para todo arco .
(É 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 .
Uma rede
tem um fluxo que satisfaz se e somente se
-
e
-
para todo tal que .
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 que satisfaz numa rede de transbordo
é ótimo
se não existe fluxo
que satisfaz e tem custo menor que o de .
A adaptação
do teorema 4.2
ao problema 4.B toma a seguinte forma:
Teorema 4.6 (condições de otimalidade)
Um fluxo que satisfaz numa rede de transbordo
é ótimo se e somente se
existe um potencial
tal que
-
se então e
-
se então
para cada arco . ■
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 é uma
árvore orientada
tal que e .
(Num outro contexto, diríamos que é uma árvore geradora de .)
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 da rede é viável
se contém o suporte de algum fluxo que satisfaz .
Como mostra o seguinte lema,
existe no máximo um fluxo dotado dessa propriedade:
Lema 4.7
Numa rede com árvore ,
se é viável então
inclui o suporte de um único
fluxo que satisfaz .
Prova:
Seja uma árvore viável
e um fluxo que satisfaz e cujo suporte é subconjunto de .
Para cada arco de ,
seja a
componente conexa de
que contém .
Em virtude do lema 2.1
no capítulo 2 (com no papel de ),
temos
para cada arco de .
Aqui,
é uma abreviatura de .
Agora suponha que
é outro fluxo que satisfaz e tem suporte em .
Se repetirmos o argumento que acabamos de fazer
veremos que
para cada arco .
Logo, . ■
Diremos que o único fluxo descrito no lema 4.7
é induzido por .
Para calcular o fluxo induzido por
podemos usar .
Mas há um algoritmo mais eficiente,
que chamaremos FluxoInduzido.
Ao receber uma árvore viável ,
o algoritmo escolhe uma folha de ,
aplica o algoritmo recursivament a
depois de modificar ,
e finalmente define o valor do fluxo no único arco de que incide em .
É um bom exercício
escrever o código do algoritmo.
Nem toda árvore de uma rede é viável.
Para provar que uma dada árvore não é viável,
basta observar que
ou exibir um arco de tal que
,
sendo a
componente conexa de
que contém .
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 de uma rede ,
um potencial induzido por
é qualquer potencial
tal que
para cada arco de , como indicamos a seguir.
É fácil calcular um tal potencial.
Comece com uma folha de .
Se o único arco incidente a é ,
calcule o potencial de
e depois estenda esse potencial a
adotando .
Se o único arco incidente a for ,
calcule o potencial de
e depois estenda esse potencial a
adotando .
Vamos nos referir a esse algoritmo como
PotencialInduzido.
Formalizar o algoritmo é um
bom exercício.
Um potencial induzido por uma árvore é quase único:
se e são dois potenciais induzidos
então a diferença é a mesma para todos
os nós .
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 numa rede é
o número ,
sendo o conjunto dos arcos diretos
de e
o conjunto dos arcos inversos.
Lema 4.8
Suponha que é o potencial induzido por uma árvore de numa rede .
Para quaisquer dois nós e de tem-se
,
sendo o único caminho simples
de a em .
Prova:
Se tem um só nó então a afirmação é trivialmente verdadeira.
Agora suponha que
com .
Para cada nó ,
seja uma abreviatura de
e uma abreviatura de .
Seja
o caminho e suponha, a título de hipótese de indução,
que .
Se é um arco direto de ,
ou seja, se ,
então
.
Se é um arco inverso de ,
ou seja, se ,
então
. ■
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 de e um arco de ,
o ciclo fundamental
de
é o único ciclo do grafo no qual o arco é
direto.
O custo desse ciclo fundamental é igual ao
custo reduzido
de :
Lema 4.9
Suponha que é o potencial induzido por uma árvore de uma rede
e seja o correspondente custo reduzido.
Então para todo arco de e
para todo arco fora de ,
sendo o ciclo fundamental de .
Prova:
Por definição de , temos para todo arco de .
Agora tome um arco que não pertence a .
Seja o caminho de a em .
É claro que .
Pelo lema 4.8,
.
Logo,
. ■
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
(= TransshipmentSimplex),
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
tal que é conexo e e devolve
-
um fluxo e um potencial que satisfazem as
condições de otimalidade enunciadas no teorema 4.6, ou
-
a informação de que a rede não tem fluxo que satisfaz ,
ou
-
a informação de que a rede não tem fluxo que satisfaz e tem custo mínimo.
TransshipmentSimplex
|
01
.
ÁrvoreViável
|
02
.
repita
|
03
.ooo
FluxoInduzido
|
04
.ooo
PotencialInduzido
|
05
.ooo
seja o custo reduzido associado a
|
06
.ooo
se
|
07
.oooooo
então devolva e e pare
|
08
.ooo
escolha um arco tal que
|
09
.ooo
seja o ciclo fundamental de
|
10
.ooo
|
11
.ooo
se
|
12
.oooooo
então pare
|
13
.ooo
escolha em tal que
|
14
.ooo
|
No começo de cada iteração (linha 02),
é uma árvore viável da rede.
No fim da linha 05,
é o fluxo induzido por ,
é o potencial induzido por ,
e para todo arco de .
No linha 07, e satisfazem as condições
de otimalidade enunciadas no teorema 4.6
e portanto é um fluxo ótimo.
No fim da linha 09,
o custo de é negativo
em virtude do lema 4.9.
Na linha 11,
a condição é equivalente a
e portanto
o ciclo é dirigido,
o que mostra
que a rede não tem fluxo de custo mínimo.
Na linha 13,
é um ciclo de aumento.
Se enviarmos unidades de fluxo
ao longo de ,
o valor do fluxo no arco será reduzido a zero.
Na linha 14,
o arco é removido de e
o arco é acrescentado a .
No fim da linha 14,
é uma árvore viável.
(Por quê?)
Durante a linha 14,
o número é implicitamente subtraído do
custo do fluxo .
No fim da linha 14,
poderíamos atualizar
os valores de , ,
e
evitando assim a necessidade de recalculá-los no início da iteração seguinte
(linhas 03 a 05 do código).
(No caso de , por exemplo,
bastaria enviar unidades de fluxo ao longo do ciclo .)
Resta discutir a linha 01.
Esta é a parte suja do algoritmo.
A rotina ÁrvoreViá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
ÁrvoreViá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ó da rede,
-
existe um arco para cada nó tal que e
-
existe um arco para cada nó tal que .
Essas hipóteses garantem uma árvore viável trivial:
o conjunto de arcos da árvore é ,
sendo
e .
Essa árvore inicial é viável uma vez que, por hipótese, .
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 .
Exemplo 4.5:
Considere a rede de transbordo descrita a seguir.
O grafo dirigido é dado por sua matriz de adjacências.
A função-demanda e os custos dos arcos são dadas nas tabelas.
Suponha que a primeira iteração do algoritmo
TransshipmentSimplex
começa a árvore
indicada em
magenta
na tabela abaixo.
A tabela também registra o fluxo e o potencial induzidos por ,
bem como os custos reduzidos .
O custo do fluxo é .
O algoritmo escolhe o arco
e envia unidade de fluxo ao longo do ciclo induzido por .
O novo fluxo terá custo .
O arco é acrescentado a e
o arco é retirado de .
A segunda iteração começa com a árvore indicada abaixo em
magenta.
A tabela dá o fluxo induzido ,
o potencial induzido ,
e o custo reduzido .
O fluxo tem custo .
O algoritmo escolhe o arco
e envia unidade de fluxo ao longo do ciclo .
O novo fluxo terá custo .
A terceira iteração começa a árvore ,
o fluxo , e o potencial indicados a seguir:
Como ,
a execução do algoritmo termina.
Para detetar eventuais erros de cálculo
cometidos durante a execução do algoritmo,
convém verificar que .
Número de iterações.
No fim da linha 14,
o custo do fluxo induzido por
é ,
sendo
(veja a seção 4.4
e o lema 4.9).
Se ,
o novo fluxo será mais barato que o anterior
e assim o algoritmo terá feito algum progresso.
Se ,
o fluxo não se altera,
embora a árvore seja modificada.
Se isso acontece, a iteração é considerada degenerada.
É claro que uma iteração é degenerada se a árvore
no início da iteração tiver um arco vazio,
ou seja, um arco tal que .
Diremos que uma tal árvore é degenerada.
É possível, no pior caso,
que o algoritmo comece com uma árvore ,
execute algumas iterações degeneradas,
e volte à árvore .
Essa sequência de iterações pode então se repetir
para sempre e a execução do algoritmo não para mais.
Portanto,
TransshipmentSimplex
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 seja mais que viável,
no sentido que passamos a definir.
Antes de começar a execução do algoritmo,
escolha um nó (arbitrário mas fixo) para fazer o papel de raiz.
No início de cada iteração, para cada nó ,
seja o único caminho simples de a em .
A árvore (viável) é considerada fortemente viável
se o fluxo induzido por tem a seguinte propriedade:
cada arco vazio de aponta para longe de
, ou seja,
se é um arco vazio de então é um
arco direto
de .
Suponha agora que é fortemente viável no início de uma iteração.
Para que a árvore
no início da linha 14 do código também seja fortemente viável,
é preciso escolher o arco
na linha 13
do código como passamos a explicar.
Seja o nó de que está mais próximo de em ,
isto é, o último nó comum aos caminhos e .
Percorra o ciclo fundamental
a partir de e
escolha para
Com isso,
a árvore será fortemente viável.
Se é fortemente viável no início de todas as iterações,
a execução de TransshipmentSimplex
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 descrita a seguir.
(Não confunda o nó com a função-demanda .)
O grafo dirigido é dado por sua matriz de adjacências.
Complete a figura usando o gabarito de posição dos nós.
A função-demanda e os custos dos arcos são dados nas tabelas.
A primeira iteração do algoritmo
TransshipmentSimplex
começa com a árvore indicada abaixo em
magenta.
A tabela dá o fluxo induzido ,
o potencial induzido ,
e o correspondente custo reduzido .
O custo do fluxo é .
O algoritmo escolhe o arco
e envia unidade de fluxo ao longo do ciclo induzido por .
Os arcos e ficam vazios.
O primeiro sai da árvore mas o segundo continua na árvore.
O novo fluxo tem custo .
A segunda iteração começa com os dados a seguir.
A árvore viável é degenerada.
O algoritmo escolhe o arco
e portanto o ciclo .
Apenas unidades de fluxo podem ser enviadas ao longo do ciclo.
A iteração é degenerada.
O fluxo não se altera
mas o arco é arescentado a e
o arco é retirado em .
A terceira iteração começa com os dados indicados a seguir:
O algoritmo escolhe o arco
e envia unidade de fluxo ao longo do ciclo .
O novo fluxo tem custo .
A quarta iteração começa com os seguintes dados:
O algoritmo escolhe o arco
e envia unidades de fluxo ao longo do ciclo .
O novo fluxo tem custo .
A quinta iteração começa com os seguintes dados:
Como , a execução do algoritmo termina.
Exemplo 4.7:
Considere a rede de transbordo descrita a seguir.
O grafo dirigido é dado por sua matriz de adjacências.
(Faça uma figura.)
Os custos , o potencial ,
e o custos reduzidos foram omitidos.
Adote o nó como raiz e suponha que .
Execute uma iteração do
TransshipmentSimplex
começando com a árvore viável
.
Note que é fortemente viável.
O algoritmo escolhe o arco pois .
O ciclo fundamental de é .
A largura do ciclo é .
Qualquer um dos arcos ,
, poderia ser removido de
para dar lugar a .
Para garantir que a nova árvore viável seja fortemente viável,
o algoritmo remove o arco .
Exemplo 4.8:
Considere a rede de transbordo descrita a seguir.
O grafo dirigido é dado por sua matriz de adjacências.
(Faça uma figura.)
A função-demanda e os custos dos arcos são dadas nas tabelas.
Adote o nó como raiz.
[CCPS fig.4.10]
A primeira iteração do
TransshipmentSimplex
começa com a árvore viável indicada a seguir
(os arcos de estão destacados em
magenta).
A árvore é degenerada mas fortemente viável.
O fluxo induzido tem custo .
O algoritmo escolhe o arco .
A sequência de nós do correspondente ciclo fundamental,
escrita a partir do nó mais próximo da raiz,
é .
Como , a iteração é degenerada.
O envio de 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 .
O algoritmo escolhe o arco .
O correspondente ciclo fundamental,
a partir do nó mais próximo da raiz, é .
Temos e o arco faz o papel de .
O envio de unidade de fluxo ao longo do ciclo
produz um novo fluxo de custo .
A terceira iteração começa com uma árvore viável
degenerada mas fortemente viável.
(Se a iteração anterior tivesse escolhido ,
a árvore não seria fortemente viável.)
Como , a execução do algoritmo termina.
Exercícios 4.6
-
★
Prove o teorema 4.6
a partir do
teorema 4.2.
-
Em que condições uma instância do problema do transbordo
(problema 4.B) é inviável?
Em que condições é ilimitada?
-
Seja um fluxo
num grafo dirigido conexo .
Suponha que todo ciclo (dirigido ou não) em
tem um arco vazio,
isto é, um arco tal que .
Mostre que existe uma árvore de
tal que o suporte de é subconjunto de .
-
★
Fluxo viável implica fluxo arbóreo.
Suponha que uma rede conexa tem um fluxo que satisfaz .
Prove que o suporte de algum fluxo que satisfaz
é subconjunto de alguma árvore da rede.
Parte 2:
Suponha que uma rede conexa tem um fluxo ótimo
e prove que o suporte de algum fluxo ótimo
é subconjunto de alguma árvore da rede.
-
★
Complete os detalhes da prova do
lema 4.7.
-
★
FluxoInduzido.
Escreva um algoritmo que receba uma árvore viável
de uma rede
e devolva o único fluxo em que satisfaz .
-
Escreva uma versão
completa
do algoritmo
FluxoInduzido.
O algoritmo deve receber uma árvore e uma função-demanda
tal que
e devolver o único fluxo em que satisfaz
ou uma prova de que tal fluxo não existe.
A prova consiste em um arco de tal que
.
-
★
PotencialInduzido.
Escreva um algoritmo que receba uma árvore
de uma rede
e devolva o potencial induzido por .
Mais exercícios
-
Custo de arcos artificiais,
Seja uma rede de transbordo com arcos arficiais.
Atribua custo
a cada arco artificial.
Suponha que o algoritmo
Simplex-para-Transbordo
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]
-
Resolva a instância do problema do transbordo indicada na figura.
Use o algoritmo TransshipmentSimplex.
Os números junto aos nós são as demandas .
Os números nos arcos são os custos .
Comece com o fluxo induzido pela árvore viável
representada pelas linhas contínuas.
[CCPS 4.22]
-
Solução inicial no
Simplex-para-transbordo.
Escreva uma implementação da rotina ÁrvoreViável
sob as hipóteses (a) e (b).
Prove que sua implementação está correta.
-
Solução inicial no Simplex-para-transbordo.
Discuta a seguinte ideia de implementação da rotina ÁrvoreViável.
1. Calcule um fluxo em que satisfaz
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 seja subconjunto do conjunto de arcos de uma árvore).
4. Extraia uma árvore do suporte de .
-
Árvore fortemente viável inicial.
Encontre uma maneira de construir a árvore viável
na linha 01
de TransshipmentSimplex
de modo que ela seja fortemente viável.
-
Mostre como representar de maneira eficiente
no algoritmo TransshipmentSimplex.
Mostre como os valores ,
, e podem ser calculados,
a cada iteração, a partir dos valores de ,
, e
na iteração anterior
(evitando assim que os valores sejam
calculadas diretamente a partir de ).
[CCPS 4.23]
-
No algoritmo TransshipmentSimplex,
suponha que é fortemente viável no início de uma iteração
em que .
Mostre que estará em (e não em ).
Mostre que será o último arco direto vazio de .
-
Exemplo 4.6.
Analise o exemplo 4.6.
Adote o nó como raiz e verifique que
no início de cada iteração do algoritmo
a árvore viável é fortemente viável.
-
Mostre que toda árvore não-degenerada
é fortemente viável.
-
De fortemente viável a fortemente viável.
Suponha que é fortemente viável e
é escolhido de acordo com a
regra .
Mostre que no início da linha 14 de TransshipmentSimplex
a árvore viável é fortemente viável.
-
O número de iterações é finito.
Seja a raiz de e defina
na linha 04
de TransshipmentSimplex
de modo que
(e portanto
para cada ).
Suponha que é fortemente viável no início de uma iteração
e seja o valor da soma
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 será menor que .
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 é um terno
em que é uma árvore de
e
é uma partição
do conjunto de arcos de .
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
é viável
se satisfaz e respeita .
Em relação a um fluxo viável ,
diremos que um arco está vazio se
e está cheio se .
(Se ,
o arco 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 para cada arco .)
Uma tripartição arbórea da rede é viável
se algum fluxo viável em
deixa todos os arcos de vazios
e todos os arcos de cheios.
(Nada impede que esse mesmo fluxo deixe alguns arcos de vazios
e alguns arcos de cheios.)
Segue do lema 4.7 que existe no máximo um tal fluxo:
Lema 4.10
Para qualquer tripartição arbórea de uma rede
,
existe no máximo um fluxo viável
que deixa os arcos de vazios
e os arcos de cheios. ■
Dizemos que o único fluxo viável a que se refere o lema 4.10
é induzido por ,
Se o fluxo induzido deixa algum arco de vazio ou algum arco cheio,
dizemos que a tripartição é degenerada.
Potenciais induzidos por tripartições arbóreas.
Numa rede ,
um potencial é induzido por
uma tripartição arbórea
se para cada arco de .
Tal como
no caso das redes de transbordo,
toda tripartição arbórea tem um potencial induzido
e esse potencial é essencialmente único.
Seja uma tripartição arbórea do grafo .
Para cada em ,
o ciclo fundamental
de é o único ciclo em no qual
é um arco direto.
Para cada em ,
o ciclo fundamental
de é o único ciclo em no qual
é um arco inverso.
O seguinte lema generaliza o lema 4.9:
Lema 4.11
Seja uma tripartição arbórea de uma rede .
Seja o potencial induzido pela tripartição
e o custo reduzido
associado a .
Para cada arco ,
-
se então ,
-
se então ,
-
se então ,
sendo o ciclo fundamental de .
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 com conexo e ,
o algoritmo Simplex-para-redes
produz uma tripartição arbórea viável
e um potencial que satisfazem as condições
-
para em ,
-
para em ,
-
para em ,
sendo o custo reduzido associado a .
De acordo com teorema 4.2
(veja a formulação alternativa
do teorema),
o fluxo induzido por é ó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 ,
e uma cópia invertida
que cuida da restrição .
NetworkSimplex
|
01
.
TripartiçãoArbóreaViável
|
02
.
se é indefinida
|
03
.ooo
então pare
|
04
.
repita
|
05
.ooo
seja o fluxo induzido por
|
06
.ooo
seja um potencial induzido por
|
07
.ooo
seja o custo reduzido associado a
|
08
.ooo
se quando e quando
|
09
.oooooo
então devolva e e pare
|
10
.ooo
escolha tal que
ou tal que
|
11
.ooo
seja o ciclo fundamental de
|
12
.ooo
|
13
.ooo
|
14
.ooo
se
|
15
.oooooo
então escolha em tal que
|
16
.oooooo
senão escolha em tal que
|
17
.ooo
|
18
.ooo
se então senão
|
19
.ooo
se então senão
|
No começo de cada iteração (linha 04),
é uma tripartição arbórea viável.
A rotina
TripartiçãoArbóreaViá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
TripartiçãoArbóreaViável.
Um truque sujo clássico consiste em escolher um nó ,
arbitrário mas fixo,
e acrescentar à rede
(a) um arco para cada nó tal que e
(b) um arco para cada nó tal que .
Esses arcos artificiais devem ter capacidade infinita e custo infinito.
Feito isso,
considere a árvore com conjunto de arcos ,
sendo
e ,
e seja conjunto .
Agora, é uma tripartição arbórea viável.
Se o algoritmo NetworkSimplex
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 descrita a seguir.
O grafo dirigido é dado por sua matriz de adjacências.
A função-demanda e os custos dos arcos são dadas nas tabelas.
A primeira iteração do algoritmo
NetworkSimplex
começa com
a tripartição arbórea viável indicada abaixo.
Os arcos de estão indicados em
magenta,
os arcos de estão sublinhados,
e é vazio.
Veja na tabela o fluxo e o potencial induzidos pela tripartição.
O algoritmo escolhe o arco
e envia unidades de fluxo ao longo do ciclo induzido por .
O arco fica cheio e é transferido de para .
A tripartição não se altera.
O novo fluxo terá custo .
A segunda iteração começa com a tripartição arbórea
indicada abaixo
com uma barra acima
dos arcos de .
[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 .
Como para todo em
e para todo em ,
o fluxo é ótimo
e a execução do algoritmo termina.
Por via dúvidas, convém verificar que
.
(Essa é uma boa maneira de detetar eventuais erros de cálculo
cometido durante a execução do algoritmo.)
O vetor está indicado abaixo:
Portanto, ,
como deveria ser.
Consumo de tempo.
O algoritmo NetworkSimplex,
tal como TransshipmentSimplex,
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ó como raiz;
(ii) adote em todas as iterações;
(iii) tome providências para que a tripartição arbórea
seja fortemente viável no início de cada iteração.
Uma tripartição arbórea viável
é fortemente viável se
o fluxo induzido pela tripartição tem a seguinte propriedade:
cada arco de que está vazio aponta para longe da raiz
(ou seja, é um arco de ),
e cada arco de que está cheio
aponta na direção da raiz
(ou seja, é um arco de ).
Exercícios 4.7
-
Seja uma rede conexa.
Mostre que um fluxo é induzido por uma tripartição arbórea
se e somente se
todo ciclo de tem um arco vazio ou um arco cheio
(ou ambos).
-
★
Fluxo viável implica fluxo arbóreo.
Suponha que uma rede 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 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]
-
Prove o lema 4.10.
-
Escreva um algoritmo que receba uma tripartição arbórea
de uma rede ,
decida se a tripartição é viável,
e em caso afirmativo calcule o fluxo induzido pela tripartição.
-
Dê condições necessárias e suficientes para que
uma tripartição arbórea seja viável.
Mais exercícios
-
★
Prove o lema 4.11.
-
★
É possível ter no começo da linha 17
do NetworkSimplex?
Como o algoritmo se comporta nesse caso?
-
Tripartição arbórea inicial.
Eis um truque feio mas efetivo para calcular
a tripartição inicial na linha 01
de NetworkSimplex.
Antes de invocar o algoritmo,
acrescente a um novo nó
e novos arcos da seguinte maneira:
para cada nó com ,
acrescente um novo arco ;
para cada tal que ,
acrescente um novo arco .
Seja o conjunto dos novos arcos do tipo
e o conjunto dos novos arcos do tipo .
Cada novo arco deve ter custo e capacidade .
A constante deve ser positiva e muito grande.
Seja .
Adote fluxo para cada
e fluxo para cada .
Faça igual ao conjunto dos arcos originais
e faça igual a .
A tripartição arbórea é fortemente viável se tomarmos como raiz.
Como o custo é muito grande,
nenhum dos arcos artificiais estará na árvore
produzida por NetworkSimplex.