• Nenhum resultado encontrado

Curso de Otimização Combinatória

N/A
N/A
Protected

Academic year: 2021

Share "Curso de Otimização Combinatória"

Copied!
155
0
0

Texto

(1)

Otimização Combinatória

www.ime.usp.br/~pf/otimizacao-combinatoria/

Paulo Feofiloff

Departamento de Ciência da Computação Instituto de Matemática e Estatística

Universidade de São Paulo

(2)
(3)

Estas notas de aula foram escritas para as disciplinas deOtimização Combinatóriado

Instituto de Matemática e Estatística da Universidade de São Paulo. Uma versão antiga das notas pode ser vista no meu sítio Fluxo em Redes (https://www.ime.usp.br/~pf/ flows/).

As notas discutem algoritmos para alguns problemas de otimização combinatória, como o problema do caminho mínimo, o do fluxo máximo, o do fluxo viável de custo mínimo, o do corte não-dirigido mínimo, o do emparelhamento máximo, e o do empa-relhamento perfeito de custo mínimo.

Supõe-se que o leitor tem algum conhecimento prévio deteoria dos grafos, de progra-mação linear, deanálise de algoritmos, e deestruturas de dados básicas.

As notas foram baseadas, em boa parte, no livro de Cook, Cunningham, Pulleyblank e Schrijver [CCPS98], que apelidei de CCPS. A maior parte das figuras foi copiada (sem permissão) desse livro.

Os livros de Schrijver [Sch03], e Ahuja, Magnanti e Orlin [AMO93] também serviram de referência e fonte de material. A maneira de escrever pseudocódigo foi copiada de Cormen, Leiserson, Rivest e Stein [CLRS01]. Apelidei esses livros de Sch, AMO e CLRS, respectivamente.

Os exercícios marcados com “?” complementam pontos que o texto indicou mas não desenvolveu. Exercícios particularmente interessantes ou importantes também são marcados com “?”. Mas essas indicações não são sistemáticas nem consistentes.

—P.F.

(4)
(5)

1 Preliminares 1

1.1 Digrafos . . . 1

1.2 Grafos não-dirigidos . . . 5

1.3 Programação linear . . . 6

1.4 Complexidade de algoritmos . . . 9

1.5 Comparação assintótica de funções . . . 10

1.6 Convenções gerais de notação e terminologia . . . 10

2 Caminhos dirigidos de custo mínimo 13 2.1 O problema . . . 13 2.2 Potencial viável . . . 15 2.3 Algoritmo de Ford . . . 16 2.4 Algoritmo de Ford-Bellman . . . 19 2.5 Dicircuitos negativos . . . 21 2.6 Programas lineares . . . 21

2.7 Algoritmo especial para redes acíclicas . . . 23

2.8 Algoritmo especial para custos não-negativos . . . 25

2.9 Custos unitários e busca em largura . . . 26

2.10 Exercícios adicionais . . . 27

3 Fluxo máximo e corte mínimo 29 3.1 Fluxo . . . 29

3.2 O problema do fluxo máximo . . . 32

3.3 Condições de otimalidade . . . 33

3.4 Teorema do fluxo máximo e corte mínimo . . . 34

3.5 Algoritmo de Ford e Fulkerson . . . 37

(6)

3.6 Versão Edmonds-Karp do algoritmo . . . 38

3.7 Programas lineares . . . 40

3.8 Exercícios adicionais . . . 42

4 Aplicações de fluxo máximo e corte mínimo 43 4.1 Emparelhamentos bipartidos e coberturas por nós . . . 43

4.2 O problema do transporte . . . 45

4.3 O problema de Gale . . . 47

4.4 O problema de Hoffman . . . 50

4.5 Fluxo mínimo entre dois nós. . . 53

4.6 Teorema de Dilworth . . . 55

5 Fluxo viável de custo mínimo 59 5.1 O problema . . . 59

5.2 Programas lineares . . . 60

5.3 Condições de otimalidade . . . 62

5.4 Circuitos de aumento . . . 63

5.5 Algoritmo dos circuitos de aumento . . . 67

5.6 Algoritmo Simplex Para Redes de Transbordo . . . 68

5.7 Algoritmo Simplex Para Redes arbitrárias . . . 76

6 Cortes não-dirigidos mínimos 81 6.1 Submodularidade . . . 81

6.2 Corte mínimo entre dois nós . . . 82

6.3 Contrações e laminaridade . . . 84

6.4 Corte globalmente mínimo. . . 85

6.5 Árvores Gomory-Hu . . . 89

6.6 Algoritmo para árvore Gomory-Hu. . . 91

6.7 Construção iterativa da árvore Gomory-Hu . . . 94

7 Emparelhamentos máximos 97 7.1 O problema . . . 97

7.2 Caminhos alternantes. . . 98

7.3 Componentes ímpares e a fórmula de Tutte-Berge . . . 100

(7)

7.5 Algoritmo do emparelhamento máximo . . . 113

8 Emparelhamento de custo mínimo 117 8.1 Emparelhamento perfeito mínimo . . . 117

8.2 Programa linear . . . 118

8.3 Algoritmo para grafos bipartidos . . . 120

8.4 Um programa linear mais poderoso . . . 124

8.5 Algoritmo para grafos arbitrários . . . 127

8.6 Emparelhamentos de custo máximo . . . 129

9 Poliedros inteiros 131 9.1 Casco convexo e separação. . . 131

9.2 Poliedro dos emparelhamentos perfeitos. . . 133

9.3 Poliedros, politopos, e seus vértices. . . 134

9.4 Politopos de programas lineares . . . 138

Bibliografia 141

(8)
(9)

Preliminares

Este primeiro capítulo faz uma rápida revisão dos conceitos e da terminologia básica da teoria dos grafos, da programação linear e da complexidade de algoritmos. Também estabelece as convenções de notação que serão usadas no restante das notas. A termi-nologia e a notação adotados são essencialmente os de CCPS.

Muitos problemas de otimização combinatória são formuladas sobre grafos. Examinar esses problemas sob o prisma da programação linear é muito revelador. Para estudar a eficiência dos algoritmos que resolvem os problemas é preciso conhecer um mínimo das técnicas de análise de algoritmos.

1.1

Digrafos

Um digrafo (= digraph) é um par (V, E) de conjuntos, sendo V qualquer conjunto finito e E um conjunto de pares ordenados de elementos de V . Os elementos de V são chamados nós e os elementos de E são chamados arcos.1

Digrafos também são conhecidos como grafos dirigidos (= directed graphs). O neolo-gismo “digrafo” é fácil de escrever, mas difícil de pronunciar. Em discussões orais, prefiro usar o sinônimo “grafo dirigido”. Quando o contexto permite, podemos deixar o prefixo “di” e o adjetivo “dirigido” subentendidos e dizer “grafo”.

Podemos dar um nome — como G, por exemplo — a um digrafo. O conjunto de nós de um digrafo G é denotado por V (G) e o conjunto de arcos por E(G).

Um arco (v, w) pode ser denotado simplesmente por vw. O nó v é a ponta inicial (= tail) e o nó w é a ponta final (= head) do arco. Dizemos que um tal arco sai de v e entra em w. A ponta inicial de um arco também poderia ser chamada ponta negativa e a ponta final poderia ser chamada ponta positiva.

Digrafos não têm “arcos paralelos”: dois arcos diferentes não podem ter a mesma ponta inicial e a mesma ponta final. Além disso, as pontas inicial e final de cada arco

1As letras “V ” e “E” são as iniciais de “vertex” e “edge”, respectivamente. Teria sido mais coerente

usar as iniciais “N ” e “A” de “node” e “arc”.

(10)

são distintas; portanto, digrafos não têm “laços” (= loops).

Dois arcos vw e v0w0 são antiparalelos, ou mutuamente inversos, se v0 = w e w0 = v.

Um digrafo é simétrico se a presença de um arco implica na presença do arco inverso. Em outras palavras, um digrafo é simétrico se tem um arco wv para cada arco vw. O número de nós de um digrafo é denotado por n e o número de arcos por m. Portanto, se G é o digrafo em discussão então n := |V (G)| e m := |E(G)|. É claro que m ≤ n(n − 1) < n2.

Um subdigrafo de um digrafo G é qualquer digrafo G0tal que V (G0) ⊆ V (G)e E(G0) ⊆ E(G). Se V (G0) = V (G), dizemos que G0 é um subdigrafo gerador (= spanning). Dado um subconjunto V0 de V (G), se E0 é o conjunto de todos os arcos de G que têm ambas

as pontas em V0, dizemos que o subdigrafo (V0, E0) é induzido por V0. Dado um subconjunto E0 de E(G), se V0 é o conjunto de todos os nós de G que incidem em arcos de E0, dizemos que subdigrafo (V0, E0)é induzido por E0.

Para qualquer nó v de G, denotamos por G − v o subdigrafo induzido por V (G) r {v}. Para qualquer arco e, denotamos por G − e o subdigrafo que tem conjunto de nós V (G) e conjunto de arcos E(G) r {e}. Para qualquer par (i, j) de nós, denotamos por G + ij o digrafo que tem conjunto de nós V (G) e conjunto de arcos E(G) ∪ {ij}.

Matrizes. A matriz de adjacências de um digrafo tem linhas e colunas indexadas pelos nós. A componente da matriz na posição (v, w) vale 1 se vw é um arco e vale 0 em caso contrário.

A matriz de incidências tem linhas indexadas pelos nós e colunas indexadas pelos arcos. A coluna que corresponde a um arco vw tem um −1 na posição v e um +1 na posição w, sendo o resto da coluna igual a 0. Portanto, a linha da matriz que corresponde ao nó v tem um +1 na coluna correspondente a cada arco que entra em v, um −1 na posição correspondente a cada arco que sai de v, e 0 em todas as demais posições.

EXEMPLO1: O digrafo com nós u v w z e arcos uw vw zu uz zw tem a matriz de adjacências

representada à esquerda (com “−” no lugar de “0”) e a matriz de incidências representada à direita: u v w z u − − 1 1 v − − 1 − w − − − − z 1 − 1 − uw vw zu uz zw u −1 0 +1 −1 0 v 0 −1 0 0 0 w +1 +1 0 0 +1 z 0 0 −1 +1 −1

Caminhos. Um caminho (= path) num digrafo é qualquer sequência alternante (v0, e1,

v1, e2, . . . , ep, vp)de nós e arcos tal que cada arco ektem pontas vk−1e vk. Se ek= vk−1vk,

o arco ek é direto; se ek = vkvk−1, o arco ek é inverso. O nó v0 é a origem do caminho

e vp é o término. Dizemos que o caminho vai de v0 a vp. O conjunto de nós de um

caminho P é denotado por V (P ) e o conjunto de arcos por E(P ).

O comprimento de um caminho (v0, e1, v1, . . . , ep, vp)é o número p, ou seja, o número

de termos da sequência que são arcos. O comprimento de um caminho P é pelo menos |E(P )|, valendo a igualdade somente se P não tem arcos repetidos.

(11)

Um caminho (v0, e1, v1, e2, . . . , ep, vp)pode ser indicado pela sequência (v0, v1, . . . , vp)de

seus nós, embora essa abreviatura seja ambígua quando o digrafo tem arcos antipara-lelos.

Se o término de um caminho (v0, v1, . . . , vp) é igual à origem de um caminho (w0,

w1, . . . , wq), os dois caminhos podem ser concatenados. O resultado da concatenação

é o caminho (v0, v1, . . . , vp, w1, w2, . . . , wq). A concatenação de dois caminhos P e Q é

denotada por P · Q.

Um caminho é simples se não tem nós repetidos (e portanto não tem arcos repetidos). Se um caminho P é simples, seu comprimento é |E(P )|. Se Q é um caminho com origem r e término s então alguma subsequência2de Q é um caminho simples de r a s. Por exemplo, se (u, v, w, x, v, w, z) é um caminho então (u, v, w, z) é o correspondente caminho simples.

Dicaminhos. Um caminho é dirigido se todos os seus arcos são diretos. Caminhos dirigidos também são chamados dicaminhos (= dipaths). (O neologismo “dicaminho” é feio, mas cômodo em texto escrito.)

Dizemos que um nó v de um digrafo está ao alcance de um nó r se existe um dicaminho de r a v.

Componentes conexas. Um digrafo é conexo se, para cada par (r, s) de nós, existe um caminho (não necessariamente dirigido) de r a s (e portanto também um caminho de s a r). Uma componente conexa de um digrafo G é um subdigrafo conexo maximal de G.

Um digrafo é fortemente conexo se, para cada par (r, s) de nós, existe um dicaminho de r a s e um dicaminho de s a r.

Circuitos e DAGs. Um circuito (= circuit) é um caminho (v0, e1, v1, . . . , ep−1, vp−1,

ep, vp)que satisfaz quatro condições: p ≥ 2, o caminho (v0, e1, v1, . . . , ep−1, vp−1)é

sim-ples, vp = v0e ep 6= ep−1. (A última condição é redundante se p > 2.)

Um circuito é dirigido se todos os seus arcos são diretos. Um circuito dirigido também pode ser chamado de dicircuito (= dicircuit).

Um digrafo é acíclico se não tem dicircuitos. Digrafos acíclicos também são conhecidos pela abreviatura DAG de directed acyclic graph.

Florestas e árvores. Uma floresta (= forest) é um digrafo sem circuitos (em particular, sem dicircuitos). Toda floresta é um DAG, mas nem todo DAG é uma floresta. Uma árvore3 (= tree) é uma floresta conexa. Para quaisquer dois nós r e s de uma árvore,

2Da mesma forma, por exemplo, que (b, c, e, h) é subsequência de (a, b, c, d, e, f, g, h) mas (c, a) não é

subsequência de (a, b, c, d).

(12)

existe um e um só caminho simples de r a s. Para todo arco e de uma árvore T , o digrafo T − e é uma floresta com exatamente duas componentes conexas.

Uma arborescência, ou árvore divergente, é uma árvore T dotada de um nó r que tem a seguinte propriedade: para cada nó v, o único caminho simples de r a v é dirigido. O nó r é a raiz da arborescência.

EXEMPLO2: Veja à esquerda a matriz de adjacências de uma árvore com nós a b c d e f . À direita, uma árvore divergente com o mesmo conjunto de nós e raiz c. (Faça figuras.)

a b c d e f a − − − − − − b − − 1 − − − c 1 − − 1 − − d − − − − 1 − e − − − − − − f − − − 1 − − a b c d e f a − − − − − − b − − − − − − c 1 1 − 1 − − d − − − − 1 1 e − − − − − − f − − − − − −

Digrafos bipartidos. Um digrafo G é bipartido se estiver acompanhado de uma bi-partição4 {P, Q} de V (G) tal que todo arco tem uma ponta (a inicial ou a final) em P e outra em Q.

Um digrafo é bipartido se e somente se não tem circuito de comprimento ímpar.

Arcos que entram e arcos que saem. Dado um digrafo G := (V, E) e um subconjunto Rde V , denotamos por R o conjunto V r R. Dizemos que um arco vw entra em R se v ∈ Re w ∈ R. Dizemos que vw sai de R se v ∈ R e w ∈ R. O conjunto de todos os arcos que entram em R é denotado por

∂+

(R) . Analogamente, ∂−

(R) é o conjunto de todos os arcos que saem de R.5 É claro que ∂+(R) = ∂

(R). É claro também que ∂+(∅) = ∂+(V ) = ∂

(∅) = ∂− (V ) = ∅. Se v é um nó, usamos a abreviatura ∂+ (v)para ∂+ ({v}). Um nó v é fonte (= source) se ∂+(v) = ∅ e sorvedouro (= sink) se ∂(v) = ∅ . O número |∂+(v)| é o grau de entrada (= indegree) de v e o número |∂−

(v)| é o grau de saída (= outdegree) de v. É claro que |∂+

(v)| ≤ n − 1 e |∂−

(v)| ≤ n − 1. É claro também que P (|∂+

(v)| : v ∈ V ) = m e P (|∂−(v)| : v ∈ V ) = m

.

Cortes. Um corte (= cut) em um digrafo G é o conjunto de todos os arcos que saem de algum conjunto de nós. Em outras palavras, um corte é qualquer conjunto da forma

4 Uma bipartição de um conjunto V é um par {P, Q} de subconjuntos de V tal que P ∪ Q = V e

P ∩ Q = ∅. A expressão “P é uma das partições” está errada; diga “P é um dos blocos da partição”.

5CCPS escreve “δ(R)” e “δ(R)” no lugar dos meus “∂+(R)” e “∂(R)” respectivamente. Acho que

minha notação é mais sugestiva. Para justificar os superscritos “+” e “−”, você pode imaginar que os nós são contas bancárias e os arcos representam movimentação de dinheiro. Tudo que entra em uma conta é somado ao saldo e tudo que sai é subtraído.

(13)

∂−

(R), com R ⊆ V (G). (À primeira vista pode parecer que um corte deveria ser defi-nido como ∂+(R) ∪ ∂(R)

, mas a definição que adotamos é mais útil.) O conjunto R é a margem negativa do corte e R é a margem positiva. (No lugar de margem do corte poderíamos também dizer argumento do corte.)

Redes. O conceito de rede (= network) é propositalmente vago e informal. Uma rede é um digrafo juntamente com uma ou mais funções que atribuem números aos arcos e/ou aos nós do digrafo. Às vezes, a especificação de uma rede também inclui um ou dois nós “especiais” do digrafo.

Por exemplo, se G é um digrafo e c é uma função de E(G) em Q, podemos dizer que (G, c)é uma rede. Da mesma forma, se b é uma função de V (G) em Q, podemos dizer que (G, b, c) é uma rede.

Exercícios

1.1 Seja v um nó de um digrafo. Mostre queP (|∂+(v)| : v ∈ V ) = meP (|∂(v)| : v ∈ V ) = m.

1.2 Seja R um conjunto de nós de um digrafo G. Mostre que não existe dicaminho em G − ∂−(R)

que começa em R e termina em R.

1.2

Grafos não-dirigidos

Um grafo não-dirigido6 (= undirected graph) é um par (V, E) em que V é um conjunto finito e E é um conjunto de pares não ordenados de elementos de V . Os elementos de E são chamados arestas (= edges). Uma aresta {v, w} pode ser denotada por vw ou por wv. Os nós v e w são as pontas da aresta.

Quando o contexto permite, podemos dizer simplesmente “grafo”, deixando o “não-dirigido” subentendido.

Um grafo é essencialmente o mesmo que um digrafo simétrico: basta trocar cada aresta por dois arcos antiparalelos com as mesmas pontas. Assim, as definições de caminho, circuito, grau de nó, subgrafo, bipartição, etc. em grafos são análogas às corresponden-tes definições para digrafos. É claro que não há distinção entre caminhos e dicaminhos, circuitos e dicircuitos, grau de entrada e grau de saída, etc. Tipos de grafos — como árvores não-dirigidas, por exemplo — também são definidos por analogia com os cor-respondentes tipos de digrafos.

A matriz de incidências de um grafo é binária, ou seja, suas componentes estão em {0, 1}. As linhas da matriz são indexadas pelos nós e as colunas são indexadas pelas arestas; a coluna que corresponde a uma aresta vw tem um 1 na linha v e um 1 na linha w, sendo o resto da coluna igual a 0. Portanto, a linha da matriz que corresponde ao nó v tem um 1 na coluna correspondente a cada aresta que incide em v e 0 em todas as demais colunas.

(14)

EXEMPLO3: O grafo que tem nós u v w z e arestas uw vw zu uz zw tem a seguinte matriz de incidências: uw vw zu uz zw u 1 − 1 1 − v − 1 − − − w 1 1 − − 1 z − − 1 1 1

1.3

Programação linear

Programação linear é uma importante ferramenta em otimização combinatória. Consi-dere o seguinte exemplo de programa linear: encontrar números x1, x2, x3, x4, x5 que

maximizem o valor da combinação linear

51x1+ 52x2 + 53x3+ 54x4+ 55x5

enquanto satisfazem as restrições lineares

11x1+ 12x2+ 13x3+ 14x4+ 15x5 = 16

21x1+ 22x2+ 23x3+ 24x4+ 25x5 = 26

31x1+ 32x2+ 33x3+ 34x4+ 35x5 = 36

41x1+ 42x2+ 43x3+ 44x4+ 45x5 = 46

e as restrições de sinal x1 ≥ 0, x2 ≥ 0, x3 ≥ 0, x4 ≥ 0 e x5 ≥ 0. O valor ótimo desse

programa linear é o valor máximo de 51x1 + 52x2+ 53x3+ 54x4+ 55x5 respeitadas as

restrições.

Os valores dos coeficientes nesse exemplo nada têm de especial: os coeficientes po-deriam ser quaisquer números racionais, positivos, negativos, ou nulos. O número de variáveis poderia ser diferente de 5, o número de restrições poderia ser maior ou menor, e as restrições poderiam ter “≥” ou “≤” no lugar de um ou mais dos “=”. Também poderíamos ter “minimize” no lugar de “maximize”.

O problema que exibimos acima pode ser reescrito em notação matricial: encontrar um vetor x que

maximize cx sob as restrições Ax = b e x ≥ 0 .

(1) Nesse exemplo, A é a matriz representada abaixo, b é o vetor representado na vertical à direita de A e c é o vetor representado na horizontal abaixo de A:

11 12 13 14 15 16 21 22 23 24 25 26 31 32 33 34 35 36 41 42 43 44 45 46 51 52 53 54 55

A expressão cx representa a soma c1x1+ . . . + c5x5. Muita gente escreve “cTx” no lugar

(15)

Ocasionalmente usamos a expressão “pl” como abreviatura de “programa linear” (ou “problema de programação linear”). Uma solução viável do pl (1) é qualquer vetor x que satisfaça as restrições Ax = b e x ≥ 0. Uma solução ótima do pl (1) é qualquer solução viável x que maximize cx.7

O pl (1) é viável se tem uma solução viável e inviável no caso contrário. O pl é ilimi-tadose for viável mas não tiver solução ótima, ou seja, se existirem soluções viáveis x para as quais cx é tão grande quanto se queira.

Dualidade

O dual do programa linear (1) consiste em encontrar um vetor y que minimize yb

sob as restrições yA ≥ c.

(2)

A expressão yA representa a combinação linear das linhas de A com coeficientes y1, y2, . . ., da mesma forma que a expressão Ax representa a combinação linear das

colunas de A com coeficientes x1, x2, . . . Muita gente escreve “yTA” ou “ATy” no lugar

do meu “yA”, mas eu prefiro a expressão mais simples! Na minha notação, o produto de vetor por matriz não é comutativo: yA não é o mesmo que Ay (em geral, um deles nem faz sentido).

Os conceitos de solução viável, solução ótima, viável e ilimitado para o pl dual (2) são análogos aos do pl “primal” (1).

A relação básica entre os pl’s (1) e (2) é conhecida como teorema fraco da dualidade. Esse teorema dá uma delimitação superior para a expressão que queremos maximizar e, ao mesmo tempo, uma delimitação inferior para expressão que queremos minimizar: para qualquer solução viável x do problema primal e qualquer solução viável y do dual, tem-se

cx ≤ yb . (3)

A prova dessa desigualdade tem apenas uma linha, mas é muito instrutiva. Ela en-volve todas as restrições dos dois pl’s (e a associatividade do produto de vetor por matriz):

cx ≤ (yA)x = y(Ax) = yb . (4)

Se cx = yb então, em virtude de (3), x é solução ótima do pl primal e y é solução ótima do pl dual.

Portanto, para mostrar que uma solução viável x do primal é ótima, basta exibir uma solução viável y do dual tal que cx = yb. A recíproca dessa observação é garantida pelo teorema forte da dualidade:

7 Essa terminologia tradicional é um tanto ilógica, pois a definição do pl (1) inclui a maximização

de cx e portanto o “ótima” da expressão “solução ótima” é redundante. Por outro lado, uma “solução viável” não é, a rigor, uma solução pois não maximiza cx.

(16)

Teorema 1.1 Se os programas lineares (1) e (2) são viáveis então existe uma solução viável x do primeiro e uma solução viável y do segundo tais que cx = yb.

A prova do teorema é algorítmica: o algoritmo Simplex recebe A, b e c, decide se os dois pl’s são viáveis e, em caso afirmativo, devolve x e y tais que cx = yb. (Veja o livro de Chvátal [Chv83].)

Folgas complementares

Suponha que x é uma solução viável de (1) e y é uma solução viável de (2). Para cada índice j, dizemos que x é justo em j se xj = 0e folgado em j se xj > 0. Analogamente,

yé justo em j se (yA)j = cj e folgado em j se (yA)j > cj. (Nesse par dual de pl’s, as

folgas envolvem apenas os índices das colunas de A. Em outros pl’s, as folgas podem envolver também os índices das linhas de A.)

Se x é justo sempre que y é folgado (ou, equivalentemente, y é justo sempre que x é folgado), dizemos que as folgas de x e y são complementares. No caso dos pl’s (1) e (2), as folgas de x e y são complementares se, para cada índice j,

(yA)j > cj implica em xj = 0 . (5)

Para apresentar essas condições de forma mais simétrica, você pode dizer “(yA)j = cj

ou xj = 0”. (Aqui, o “ou” não é exclusivo, pois podemos ter (yA)j = cj e xj = 0para

algum j.) É fácil deduzir de (4) que, para qualquer x viável em (1) e qualquer y viável em (2),

cx = yb se e somente se as folgas de x e y são complementares (6) (veja o exercício1.5). Esse é o teorema das folgas complementares.

Um exemplo importante

Considere novamente o programa linear que consiste em maximizar cx sob as restri-ções Ax = b e x ≥ 0. Suponha que cada coluna de A tem exatamente uma componente igual a −1, exatamente uma componente igual a +1, e todas as demais componentes nulas, como no exemplo a seguir.

−1 0 +1 −1 0

0 −1 0 0 0

+1 +1 0 0 +1 0 0 −1 +1 −1

Então A é a matriz de incidências de um digrafo, digamos G. As linhas de A e o vetor b são indexados por V (G); as colunas de A e o vetor c são indexados por E(G). As restrições Ax = b podem ser entendidas assim: para cada nó v,

P (xuv: uv ∈ E(G)) − P (xvw : vw ∈ E(G)) = bv,

ou seja, a soma das componentes de x que correspondem aos arcos que entram em v menos a soma das componentes que correspondem aos arcos que saem de v deve ser igual a bv.

(17)

Programas lineares inteiros

Um programa linear é inteiro se, além das restrições usuais de um pl, tiver restrições de integralidade, ou seja, se exigir que os valores das variáveis sejam números inteiros. Por exemplo, se acrescentarmos as restrições

xi ∈ Z para cada i

ao pl (1), teremos um programa linear inteiro.

A relaxação linear de um programa linear inteiro é o pl que se obtém quando as restri-ções de integralidade são removidas.

Exercícios

1.3 Seja A a matriz representada abaixo, b o vetor representado à direita de A e c o vetor representado sob A. Escreva por extenso o seguinte pl: maximize cx sujeito às restrições Ax ≤ b. Escreva por extenso o seguinte pl: maximize yb sujeito às restrições yA ≤ c.

11 12 13 14 15 21 22 23 24 25 31 32 33 34 35 41 42 43 44

1.4 Encontrar x que maximize x1+ 2x2+ 3x3sob as restrições x1≥ 0, x2≥ 0, x3≥ 0,

x1+ x2+ x3 = −10 e

x1+ 4x3 = −20 .

Esse pl é viável? inviável? ilimitado? O dual desse pl é viável? inviável? ilimitado?

1.5 Suponha que a1b1+ a2b2+ · · · + ambm = 0 sendo a1, a2, . . . , am e b1, b2, . . . , bmnúmeros

não-negativos. Mostre que, para cada j, aj = 0ou bj= 0.

1.6 O enunciado do teorema1.1tem como hipótese a viabilidade dos pl’s primal e dual. Complete o enunciado de modo a cuidar dos pl’s inviáveis e dos ilimitados.

1.7 Considere o seguinte pl: minimizar cx sob as restrições Ax = b e x ≥ 0. Enuncie o pl dual. Prove o teorema fraco da dualidade para esse par de pl’s. Enuncie as condições de folgas complementares. Enuncie o teorema forte da dualidade.

1.8 Considere o seguinte pl: maximizar cx sujeito às restrições Ax ≤ b e x ≥ 0. Enuncie o pl dual. Prove o teorema fraco da dualidade para esse par de pl’s. Enuncie as condições de folgas complementares. Enuncie o teorema forte da dualidade.

1.4

Complexidade de algoritmos

Adotaremos um modelo de computação em que o consumo de tempo de cada operação aritmética entre dois números consome apenas O(1) unidades de tempo, ou seja, não depende do tamanho dos números.8

8 Para problemas que precisam lidar com números muito grandes é mais apropriado supor que a

(18)

Suponha que A é um algoritmo que opera sobre uma rede (G, c) em que c é uma função de E(G) em Q. A delimitação superior do consumo de tempo de A depende, em geral, do número C := max (|ce| : e ∈ E(G)). O número de iterações que A executa pode, por

exemplo, ser proporcional a C ou talvez a log C.

Dizemos que A é pseudopolinomial se consome O(npmqC)unidades de tempo para

algum p em Z+e algum q em Z+.

Dizemos que A é polinomial se consome O(npmq log C) unidades de tempo. (Note

que log C é, essencialmente, o número de dígitos decimais de C.)

Dizemos que A é fortemente polinomial se consome O(npmq)unidades de tempo para

algum p em Z+e algum q em Z+. O consumo de tempo não depende de c nesse caso.

1.5

Comparação assintótica de funções

Suponha que T e f são funções reais de uma variável inteira n. Dizemos que T é O(f ) se existe uma constante k e um número n0tais que 0 ≤ T (n) ≤ k f (n) para todo n ≥ n0.

Assim, a expressão “T é O(f )” tem o sabor de “T ≤ f ”.

Dizemos que T é Ω(f ) se existe uma constante k e um número n0tais que 0 ≤ k f (n) ≤

T (n)para todo n ≥ n0. Assim, a expressão “T é Ω(f )” tem o sabor de “T ≥ f ”.

Dizemos que T é Θ(f ) se T é O(f ) e Ω(f ). Portanto, a expressão “T é Θ(f )” tem o sabor de “T = f ”.

Exercícios

1.9 Um grafo bipartido G é completo se existe uma bipartição (P, Q) de V (G) tal que pq ∈ E(G) para cada p em P e q em Q. Escreva um algoritmo que receba um grafo bipartido completo G e calcule a bipartição (P, Q). O algoritmo deve consumir O(n) unidades de tempo, sendo n o número de nós de G.

1.6

Convenções gerais de notação e terminologia

Dizemos que um número r é positivo se r > 0 e negativo se r < 0.9 Portanto, a expres-são “estritamente positivo” tem o mesmo significado que “positivo” e “estritamente negativo” tem o mesmo significado que “negativo”. Um número r é não-negativo se r ≥ 0e não-positivo10se r ≤ 0.

O conjunto dos números reais é denotado por R e o conjunto dos reais não-negativos por R+.11 O conjunto dos números racionais é denotado por Q e o conjunto dos

9Alguns livros preferem dizer que r é positivo se r ≥ 0 e negativo se r ≤ 0.

10Estou contrariando a regra de ortografia que manda escrever “não negativo” sem hífen. 11Essa notação é um tanto inconsistente com nossa definição de positivo.

(19)

racionais não-negativos por Q+. O conjunto dos inteiros e o conjunto dos

in-teiros não-negativos são denotados por Z e Z+ respectivamente. Portanto, Z =

{. . . , −2, −1, 0, +1, +2, . . .} e Z+ = {0, 1, 2, . . .}.

Convém lembrar que computadores não sabem o que são números irracionas (como √

2, por exemplo); eles conhecem apenas um pequeno conjunto de racionais. Os núme-ros conhecidos como reais no mundo da computação são do tipo float ou double, e todos esses números são racionais.

Um vetor é o mesmo que uma função. Um vetor indexado por um conjunto (finito) V é o mesmo que uma função com domínio V . O conjunto de tais funções e vetores com valores racionais pode ser denotado por QV. Um vetor c indexado por V pode ser

denotado por (cv : v ∈ V ).

Um vetor é inteiro se todos as suas componentes pertencem a Z. Um vetor é binário, ou booleano, se todas as suas componentes estão em {0, 1}. Da mesma forma, uma matriz é binária, ou booleana, se todas as suas componentes estão em {0, 1}.

O vetor característico de um subconjunto S de um conjunto V é o vetor binário (xv :

v ∈ V ) tal que xv = 1 se v ∈ S e xv = 0 se v ∈ V r S. Reciprocamente, todo vetor

binário x indexado por V representa o subconjunto {v : xv = 1}de V .

Para qualquer vetor (ci : i ∈ V )e qualquer subconjunto S de V , denotamos por c(S) a

soma de todos os ci em S:12

c(S) :=P (ci : i ∈ S) .

Essa soma também pode ser representada por P

i∈Sci. Para quaisquer vetores c e x

indexados por um mesmo conjunto V , denotamos por cx a soma de todos os produtos cixi para i em S:

cx :=P (cixi : i ∈ V ) .

Se x é um vetor binário e S é o conjunto representado por x então cx = c(S).

(20)
(21)

Caminhos dirigidos de custo mínimo

Este capítulo discute o problema dos dicaminhos de custo mínimo numa rede. Al-goritmos para esse problema são usados como ferramenta na resolução de muitos problemas de otimização combinatória.

A rede consiste em um digrafo G e uma função c que atribui um número racional — positivo, negativo,ou nulo — a cada arco de G. Dizemos que c é uma função-custo. Para cada arco e, o número ceé o custo do arco.

2.1

O problema

O custo de um dicaminho P = (v0, e1, v1, e2, . . . , ep, vp)na rede (G, c) é o número c(P ) :=

ce1 + ce2 + · · · + cep. Cada arco contribui para essa soma tantas vezes quantas aparece

em P . Por exemplo, se todos os arcos têm custo 1 e P é um dicaminho simples então c(P )é número de arcos do dicaminho.

Um dicaminho P tem custo mínimo se c(P ) ≤ c(P0)para todo dicaminho P0que tenha a mesma origem e o mesmo término que P .

Problema 2.1 (dos dicaminhos mínimos) Dada uma rede (G, c) com função-custo c e um nó r em V (G), encontrar, para cada nó v, um dicaminho de r a v que tenha custo mínimo.

O nó r pode ser chamado nó inicial da rede. Podemos incorporar r à definição da rede e dizer “rede (G, c, r)”. Além disso, adotaremos a abreviatura “dicaminho mínimo” para a expressão “dicaminho de custo mínimo”.

Convém lembrar que dicaminhos não são necessariamente simples. Entretanto, todo dicaminho mínimo é essencialmente simples, conforme o exercício2.3.

Para que uma instância1do problema tenha solução, é necessário que todos os nós da rede estejam ao alcance do nó inicial r. É fácil de verificar algoritmicamente se essa condição está satisfeita.

1Uma instância de um problema é um exemplo do problema, com dados específicos.

(22)

Uma segunda condição necessária para a existência de solução é mais difícil de ve-rificar: é preciso que todos os dicircuitos tenham custo não-negativo. (Lembre-se de que dicircuitos são um tipo especial de dicaminhos.) Se uma instância do problema tem um dicircuito de custo negativo então não há dicaminho mínimo de r até algum nó v pois, dado qualquer número (negativo) α, algum dicaminho de r até v tem custo menor que α. (Poderíamos dizer, talvez, que o custo mínimo é −∞, ou que “o poço não tem fundo.”)

Cabe perguntar: é verdade que toda instância do problema 2.1 que satisfaz as duas condições necessárias que acabamos de apontar tem solução? Mostraremos adiante que a resposta é afirmativa.

EXEMPLO1: Considere o digrafo representado pela matriz de adjacências abaixo. (Use o gabarito

de posição dos nós para fazer uma figura.) Um dicaminho mínimo de r a u tem sequência de nós (r, v, w, u). É um bom exercício encontrar os demais dicaminhos mínimos. Há mais de um dicaminho mínimo de r a w, mas esse fato é irrelevante.

r s u v w r − 1 − 1 1 s − − 1 − − u − − − − − v − − − − 1 w − − 1 − − rs su rw wu rv vw c 2 −2 4 −3 3 −1 r s v w u

EXEMPLO 2: No digrafo descrito abaixo não há dicaminho algum de r a s. Qualquer que seja a função-custo, essa instância do problema2.1não tem solução.

r s t r − − 1 s − − 1 t − − −

EXEMPLO3: Considere o digrafo com custos representado pela matriz abaixo. Essa instância do problema2.1não tem solução porque não existe dicaminho mínimo de r a w. (É um bom exercício exibir todos os dicaminhos simples de custo mínimo com origem r.)

r s u v w r − 1 − − − s − − 1 − 1 u − − − 1 − v − 1 − − − w − − − − − rs su uv vs sw c 1 1 −3 1 1 r s w v u

Exercícios

2.1 Esboce um algoritmo que decida se todos os nós de um digrafo estão ao alcance de um dado nó r. 2.2 ? Subcaminhos de dicaminhos mínimos. Prove que qualquer subcaminho de um dicaminho mínimo é mínimo. Mostre que essa propriedade deixa de valer se nos restringirmos a dicaminhos simples.

[CCPS 2.19]

2.3 ? Dicaminhos mínimos são essencialmente simples. Seja P um dicaminho mínimo. Mostre que existe um dicaminho mínimo P0que é subcaminho de P , tem a mesma origem e o mesmo término de P ,

(23)

2.4 Árvores. Calcule um dicaminho mínimo de r a v numa rede (G, c) em que G é uma árvore divergente (veja seção1.1). Calcule um caminho mínimo de r a v numa rede (G, c) em que G é uma árvore não-dirigida.

2.5 No enunciado do problema 2.1, por que não restringir a atenção aos dicaminhos simples? Se fizermos isso, dicircuitos de custo negativo deixarão de ser um empecilho para a existência de solução.

2.6 Dada uma rede (G, c) e subconjuntos disjuntos R e S de V (G) queremos encontrar um dicaminho mínimo dentre os que vão de algum nó de R a algum nó de S. Mostre como esse problema pode ser reduzido ao problema2.1.[CCPS 2.22]

2.7 No problema2.1, podemos supor que o grau de entrada de r é 0?

2.2

Potencial viável

Como certificar a minimalidade de um dicaminho? Dados nós r e v, como provar que nenhum dicaminho de r a v tem custo menor que um dado número, digamos 99? Um potencial numa rede (G, c) é qualquer função que atribui um número racional a cada nó da rede.2 (Você também pode dizer que um potencial é um vetor indexado pelos nós da rede.) Usamos a seguinte terminologia para descrever a relação entre um potencial y e um arco vw:

se yv+ cvw ≥ yw então vw está relaxado,

se yv+ cvw = yw então vw é justo,

se yv+ cvw < yw então vw está tenso.3

Um potencial y é viável (= feasible) se deixa todos os arcos relaxados, ou seja, se yv + cvw ≥ yw para cada arco vw.

EXEMPLO4: Se c ≥ 0 e y tem o mesmo valor em todos os nós então y é um potencial viável. EXEMPLO5: Suponha que uma instância do problema2.1(dos dicaminhos mínimos) tem solução. Para cada nó v, seja dv o custo de um dicaminho mínimo de r a v. Então d é um potencial viável.

Com efeito, se tivéssemos dv + cvw < dwpara algum arco vw, um dicaminho de r a w passando

por v teria custo menor que dw, o que é contraditório.

Potenciais viáveis têm a seguinte propriedade básica: o custo de qualquer dicaminho é limitado inferiormente pela diferença de potencial entre seu término e sua origem: Proposição 2.2 (delimitação inferior) Se y é um potencial viável e P é um dicaminho com origem v e término w então c(P ) ≥ yw− yv.

PROVA: Seja v0, v1, . . . , vk−1, vka sequência de nós de P . Adote as abreviaturas c(i, j) :=

cvivj e y(i) := yvi. Então c(P ) = c(0, 1) + c(1, 2) + · · · + c(k − 1, k) ≥ y(1) − y(0) + y(2) −

y(1) + · · · + y(k) − y(k − 1) = y(k) − y(k − 1) + · · · + y(2) − y(1) + y(1) − y(0) = y(k) − y(0).

2O conceito de potencial não depende de um nó inicial.

3 Para justificar as palavras “tenso” e “relaxado”, você pode imaginar que cada nó v é o ponto de

ordenada yv de uma reta e cada arco vw é um barbante de comprimento cvw. Ignore as direções dos

(24)

A proposição é elementar, ou seja, segue imediatamente das definições, sem qualquer raciocínio sofisticado. Observe que a conclusão da proposição tem a mesma forma que a desigualdade yv+ cvw≥ yw: basta trocar “cvw” por “c(P )”.

A proposição tem a seguinte consequência imediata: para qualquer dicaminho P de v a w, se c(P ) = yw− yv então P é mínimo! Portanto, temos a seguinte caracterização das

soluções do problema2.1:

Teorema 2.3 Dada uma coleção (Ps : s ∈ V (G)) de dicaminhos em que cada Ps tem

origem r e término s, se existe um potencial viável y tal que yv+cvw = yw para cada

arco vw de cada Ps, então cada Psé um dicaminho de custo mínimo.

É claro que se y é um potencial com as propriedades descritas no teorema então a diferença ys− yr é o custo de um dicaminho mínimo de r a s.

Exercícios

2.8 Árvores. Calcule um potencial viável numa rede (G, c) em que G é uma árvore divergente (veja seção1.1). Calcule um potencial viável numa rede (G, c) em que G é uma árvore não-dirigida. 2.9 Seja y um potencial viável e α um número. Mostre que y − α é um potencial viável.

2.10 ? Potencial versus dicircuito negativo. Suponha que y é um potencial viável numa rede. Deduza da proposição2.2que a rede não tem dicircuitos de custo negativo.

2.3

Algoritmo de Ford

Um algoritmo ideal para o problema2.1 deveria receber uma instância arbitrária do problema e devolver uma solução da instância ou explicar por que ela não tem solução. Nosso primeiro algoritmo fica aquém do ideal pois só se aplica a digrafos sem dicir-cuitos de custo negativo. (Se o digrafo tiver um circuito de custo negativo, o algoritmo pode não parar.)

O algoritmo recebe uma rede (G, c, r) sem dicircuitos de custo negativo e produz uma coleção de dicaminhos mínimos com origem r: um dicaminho Pw, com término w,

para cada w que esteja ao alcance de r. Para certificar a minimalidade dos dicaminhos, o algoritmo também produz um potencial viável y tal que c(Pw) = yw− yrpara cada w.

O algoritmo foi proposto por L.R. Ford (em 1956).

FORD(G, c, r)  (G, c) não tem dicircuitos de custo negativo 1 para cada w em V (G) faça yw ← ∞

2 yr ← 0

3 enquanto o potencial y não é viável faça

4 escolha vw em E(G) tal que yv+ cvw < yw  vw está tenso

5 yw ← yv + cvw  relaxação de vw

6 p(w) ← v

(25)

O vetor p representa caminhos com origem r: para cada w diferente de r, p(w) é o nó anterior a w em um dicaminho de r a w. Portanto, a sequência (w, p(w), p(p(w)), . . . , r) é o inverso de um dicaminho de r até w. Dizemos que p é um vetor de predecessores. O subdigrafo de G induzido pelo conjunto de arcos da forma (p(w), w) é uma árvore divergente com raiz r (veja a seção1.1).

A ideia do algoritmo é simples: relaxar os arcos tensos, em qualquer ordem, até que todos fiquem relaxados. A operação de relaxação de um arco tenso (linha 5 do código) consiste em baixar o potencial da ponta final do arco. (Ao decidir se um arco está tenso, a linha 4 do código adota a convenção ∞ + λ = ∞ qualquer que seja λ.)

A relaxação de um arco tenso vw pode tornar tenso outro arco wz que estava relaxado. Com isso, pode ser necessário relaxar um mesmo arco várias vezes. Não é claro, por-tanto, que a execução do algoritmo termina depois de um número finito de iterações.

EXEMPLO6: Aplique o algoritmo de Ford à rede que tem nós r s u v w e os arcos e custos indicados na tabela. (Use o gabarito de posição dos nós para fazer uma figura.)

rs su rw wu rv vw 2 −2 4 −3 3 −1

r s v w u

Veja os valores de y e p no início de sucessivas iterações. A terceira coluna registra o arco que é relaxado no fim da iteração:

r s u v w 0 ∞ ∞ ∞ ∞ 0 2 ∞ ∞ ∞ 0 2 ∞ 3 ∞ 0 2 ∞ 3 4 0 2 1 3 4 0 2 0 3 4 0 2 0 3 2 0 2 −1 3 2 r s u v w − − − − − − r − − − − r − r − − r − r r − r w r r − r s r r − r s r v − r w r v rs rv rw wu su vw wu

No fim da última iteração, y é um potencial viável e p descreve dicaminhos mínimos a partir de r.

O primeiro passo da análise do algoritmo de Ford estabelece os invariantes do processo iterativo descrito nas linhas 3 a 6:

Proposição 2.4 Se a rede (G, c, r) não tem dicircuito de custo negativo então, no início de cada iteração,

(i1) cada arco do digrafo Gp está justo ou tenso,

(i2) se ij é arco de G e existe dicaminho de j a i em Gpentão ij não está tenso,

(i3) para cada i em V∗, existe um dicaminho de r a i em G p,

(i4) yi ≤ |V∗| C para cada i em V∗,

sendo Gp o subdigrafo de G induzido pelo conjunto de arcos da forma (p(j), j), V∗ o

conjunto dos nós i para os quais yi < ∞, e C := max (|cij| : ij ∈ E(G)).

ESBOÇO DE PROVA: A relaxação de um arco tenso vw na linha 5 do código pode fazer com que outro arco iw, que era justo ou tenso, perca essa propriedade. Como a linha 6 retira iw de Gp, o invariante (i1) é preservado.

(26)

Para provar o invariante (i2), suponha que P é um dicaminho simples de j a i em Gp.

Um raciocício análogo ao da prova da proposição 2.2, combinado com (i1), mostra então que yj+ c(P ) ≤ yi. Como P · (i, j) é um dicircuito e e c(P ) + cij ≥ 0, o arco ij não

é tenso.

Para provar o invariante (i3), considere o arco vw que será relaxado durante a iteração. No início da iteração, seja P um dicaminho de r a v em Gp. Em virtude de (i2), w não

pertence a P . Logo, no fim da iteração, P · (v, w) será um caminho de r a w em Gp.

A proposição2.4é a base da prova da correção do algoritmo de Ford:

Teorema 2.5 Se a rede (G, c, r) não tem dicircuito de custo negativo, o algoritmo de Ford termina depois de um número finito de iterações. Se, além disso, todos os nós estão ao alcance de r, o algoritmo produz um potencial viável y e um vetor de pre-decessores p tais que, para cada nó w, o dicaminho de r a w definido por p tem custo yw− yr.

ESBOÇO DA PROVA: Considere os invariantes (i1) a (i4) discutidos na proposição 2.4. No início de cada iteração temos yi ≤ nC para cada i em V∗. Por outro lado, se Pi é

o dicaminho simples de r a i em Gp então yr+ c(Pi) ≤ yi por um raciocínio análogo

ao da prova da proposição 2.2. Como yr = 0 e Pi tem menos que n arcos, temos

yi ≥ c(Pi) ≥ −nC. Em suma, −nC ≤ yi ≤ nC para cada i em V∗.

Estamos supondo que ce∈ Q para cada arco e. Portanto, existe ζ em Z+tal que ζce ∈ Z

para cada e. Podemos supor então que todo número cetem a forma α/ζ para algum α

em Z. Assim, ao longo da execução do algoritmo, cada componente de y tem a forma β/ζ, com β em Z, e cada iteração subtrai pelo menos 1/ζ de yw. Como −nC ≤ yw ≤ nC,

cada nó da rede pode fazer o papel de w na linha 6 no máximo 2Cnζ vezes. Como y tem ncomponentes, o número de iterações não passa de 2Cn2ζ. Isso mostra, em particular,

que a execução do algoritmo termina depois de um número finito de iterações.

Quando a execução do algoritmo termina, todos os arcos estão relaxados, ou seja, o potencial y é viável. Em particular, não existe arco vw tal que yv < ∞ mas yw = ∞.

Como todos os nós estão ao alcance de r por hipótese, temos yw < ∞para todo w, ou

seja, V∗ = V (G). O invariante (i3) garante que, para cada w, há um dicaminho Pw de r

a w em Gp. O invariante (i1) garante que c(Pw) ≤ yw−yr. Por outro lado, c(Pw) ≥ yw−yr

pela proposição2.2, pois o potencial y é viável. Assim, c(Pw) = yw− yr.

A prova do teorema mostra que o algoritmo executa no máximo 2Cnζ iterações e por-tanto é pseudopolinomial. A próxima seção introduz uma variante do algoritmo que organiza a ordem em que os arcos são relaxados, o que torna o algoritmo fortemente polinomial.

Exercícios

2.11 Complete a prova da proposição2.4. Deduza de (i2) e (i3) que yr= 0no início de cada iteração.

(27)

2.13 Considere uma instância do problema2.1em que os custos são não-negativos e todos os nós estão ao alcance de r. Deduza do teorema2.5que essa instância tem solução.

2.14 Considere uma instância do problema 2.1em que o digrafo é acíclico e todos os nós estão ao alcance de r. Deduza do teorema2.5que essa instância tem solução.

2.15 Árvores. Aplique o algoritmo de Ford a uma rede (G, c, r) em que G é uma árvore divergente (veja a seção1.1). Aplique o algoritmo de Ford a uma rede (G, c, r) em que G é uma árvore não-dirigida. 2.16 Dicircuitos negativos versus potencial. Conforme o exercício 2.10, se uma rede tem um potencial

viável então não tem dicircuito de custo negativo. Use o teorema2.5para provar a recíproca. 2.17 Submeta ao algoritmo de Ford uma rede sem dicircuitos de custo negativo em que nem todos os

nós estão ao alcance de r. Como interpretar o resultado do algoritmo?

2.18 Potencial finito. Mostre que na linha 1 do algoritmo FORD o ∞ pode ser substituído pelo nú-mero nC, onde C := 1 + max (|ce| : e ∈ E(G)). (Dica: Qualquer dicaminho simples na rede tem

custo ≤ (n−1)C < nC. Se essa substituição for feita, será preciso adotar a convenção nC +λ = nC qualquer que seja λ.)

2.19 Número de iterações sob custos inteiros. Seja (G, c, r) uma rede sem dicircuitos de custo negativo em que todas as componentes de c são inteiras. Seja C := max (|ce| : e ∈ E(G)). Mostre que a

execução o algoritmo de Ford termina em no máximo 2Cn2iterações.[CCPS 2.27]

2.4

Algoritmo de Ford-Bellman

Seja S := (a1, a2, a3, . . . , aL) uma sequência de arcos em que cada arco do digrafo

aparece pelo menos uma vez. Imagine executar a parte central do algoritmo de Ford examinando os arcos na ordem dada por S:

para j = 1, . . . , L faça se aj está tenso

então relaxe aj

Dizemos então que S é a sequência de varredura usada pelo algoritmo. Que condições uma sequência de varredura deve satisfazer para que esse processo relaxe todos os arcos do digrafo?

Para discutir essa questão, é preciso introduzir o seguinte conceito: um dicaminho está imerso na sequência de varredura S se tiver origem r e a sequência de seus arcos for uma subsequência de S. (Suponha, por exemplo, que S = (a, c, d, a, b, d, e, c, b, a, d, b). Um dicaminho com origem r e sequência de arcos (c, a, d, e, b) está imerso em S. Já um dicaminho com origem r e sequência de arcos (c, e, d, a) não está imerso em S.) Proposição 2.6 Depois que a sequência S tiver sido processada, tem-se yv ≤ c(P ) para

cada nó v e para todo dicaminho P imerso em S que termina em v.

PROVA: Seja (v0, e1, v1, e2, v2, . . . , ek, vk) o dicaminho em discussão. Imediatamente

depois da primeira ocorrência de e1 em S temos yv1 ≤ yr + ce1 = ce1 pois yr = 0.

Desse momento em diante, a desigualdade yv1 ≤ ce1 continua valendo pois o valor de

yv1 não aumenta. Depois da primeira ocorrência de e2 em S subsequente à primeira

(28)

primeira ocorrência de ek em S subsequente às ocorrências de e1, e2, . . . , ek−1, temos

yvk ≤ ce1 + · · · + cek = c(P ).

Digamos que uma sequência de varredura S é boa se todo dicaminho simples com origem r estiver imerso em S. Como todo dicaminho mínimo é simples, ao final do processamento de uma sequência boa teremos yv ≤ c(P ) para todo dicaminho

mí-nimo P de r a v. Por outro lado, existe um dicaminho de r a v de custo yv (veja a

proposição2.4). Logo, o vetor y representa os custos de todos os dicaminhos mínimos com origem r (a menos, é claro, que a rede tenha um dicircuito de custo negativo). Segue daí que a execução do algoritmo termina assim que uma sequência boa de arcos for examinada.

Um tipo natural de sequência de varredura boa para uma rede com n nós é o que resulta da concatenação de sequências S1, S2, . . . , Sn−1sendo cada Siuma permutação4

do conjunto de arcos da rede. Essa ideia leva ao algoritmo proposto por R.E. Bellman em 1958:

FORDBELLMAN(G, c, r)

1 para cada w em V (G) faça yw ← ∞

2 yr ← 0

3 repita |V (G)| − 1 vezes

4 para cada arco vw em E(G) faça 5 se yv+ cvw < yw  vw está tenso

6 então yw ← yv+ cvw  relaxação de vw

7 p(w) ← v

8 devolva y e p

No fim da execução do algoritmo, se o potencial y é viável então p define dicaminhos mínimos de r a cada um dos demais nós e ywé o custo do dicaminho que termina em w;

senão, a rede tem um dicircuito de custo negativo.

Consumo de tempo. O algoritmo de Ford-Bellman5executa no máximo nm iterações. Como cada iteração consome tempo O(1), o algoritmo todo consome

O(nm)

unidades de tempo. Portanto, o algoritmo de Ford-Bellman é fortemente polinomial. Não se conhece uma versão do algoritmo de Ford que seja assintoticamente mais rá-pida. Para redes com certas propriedade favoráveis, entretanto, há versões bem mais rápidas do algoritmo. Discutiremos isso nas próximas seções.

Exercícios

4Uma permutação de um conjunto é uma sequência em que cada elemento do conjunto aparece uma

e uma só vez.

(29)

2.20 Aplique o algoritmo de Ford-Bellman ao digrafo com nós r s t u v w e arcos rs st tu uv vw . Todos os arcos têm custo 1 e o nó inicial é r. Examine o conjunto de arcos sempre na ordem (vw, uv, tu, st, rs).

2.21 Prove a afirmação feita depois da prova da proposição2.6: se a rede não tem dicircuitos de custo negativo e a sequência de varredura S é boa então o potencial y torna-se viável assim que o algoritmo de Ford tiver examinado S.

2.22 No algoritmo de Ford-Bellman, não basta repetir o bloco de linha 4–7 até que y se “estabilize”? Discuta essa ideia.

2.23 Como interpretar o resultado (y, p) do algoritmo de Ford-Bellman no caso em que nem todos os nós da rede estão ao alcance de r?

2.24 Árvores. Escreva uma versão especializada de FORDBELLMANpara redes (G, c) em que G é uma árvore divergente. Escreva uma versão especializada de FORDBELLMANpara redes (G, c) em que Gé uma árvore não-dirigida.

2.25 Aplique o algoritmo de Ford-Bellman à rede cujos nós são r a b f g h j k e cujos arcos e custos são dados pela tabela.[CCPS 2.21]

ra rk rb ad af bk bf dh f g f j gh gj jh kd kh kg kf 2 7 5 8 4 3 2 5 3 7 4 3 3 2 9 6 1

2.5

Dicircuitos negativos

O algoritmo de Ford-Bellman pode ser adaptado para procurar dicircuitos negativos. Se a execução do algoritmo terminar com um potencial y não-viável, o vetor de prede-cessores p registra um dicircuito de custo negativo a partir de qualquer arco que não esteja relaxado.

Exercícios

2.26 Acrescente código ao algoritmo de Ford-Bellman para que ele devolva um dicircuito de custo negativo se tal existir.

2.6

Programas lineares

O teorema 2.5, que prova a finitude e correção do algoritmo de Ford, tem a seguinte consequência:

Teorema 2.7 (min-max) Dados dois nós r e s de uma rede (G, c), se existe um dicami-nho mínimo de r a s então

min

P c(P ) = maxy (ys− yr) ,

sendo minP tomado sobre todos os dicaminhos P de r a s e maxy tomado sobre todos

(30)

A determinação de um potencial viável y que maximize ys− yré facilmente formulada

como um programa linear: encontrar um vetor (yv : v ∈ V (G))que

maximize ys− yr

sob as restrições

yw − yv ≤ cvw para cada vw em E(G) .

(1)

Esse programa linear pode ser escrito em termos da matriz de incidências A do digrafo e de um vetor (bv : v ∈ V (G)). A coluna vw de A tem um −1 na linha v, um +1 na

linha w, e 0 em todas as demais linhas. O vetor b é definido assim: br = −1, bs = +1, e

bv = 0para todo v diferente de r e de s. O pl (1) pode ser escrito assim:

maximize yb sob as restrições

yA ≤ c.

O dual desse programa linear consiste em encontrar um vetor (xe : e ∈ E(G))que

minimize cx sob as restrições Ax = b e x ≥ 0 .

(Para verificar que esse é de fato o dual, tome qualquer solução viável y do primal, qualquer solução viável x do dual, e observe que a dedução yb = y(Ax) = (yA)x ≤ cx do teorema fraco da dualidade envolve todas restrições dos dois pl’s.)

A linha de A que corresponde ao nó v tem um +1 na coluna de cada arco que entra em v, um −1 na coluna de cada arco que sai de v, e 0 em todas as demais colunas. Portanto, o pl pode ser reescrito assim: encontrar um vetor x que

minimize P (cexe: e ∈ E(G)) sob as restrições x+ (r) − x− (r) = −1 x+ (v) − x− (v) = 0 para cada v em V (G) r {r, s} x+(s) − x(s) = +1

xe ≥ 0 para cada e em E(G)

(2)

sendo x+(v)

a soma do que entra em v e x−

(v)a soma do que sai de v, isto é, x+(v) :=

P (xuv : uv ∈ E(G))e x−(v) := P (xvw : vw ∈ E(G)). Esse pl é o dual de (1).

Que interessante! O pl (2) descreve o problema do dicaminho mínimo de r a s! Para todo dicaminho simples P de r a s, o vetor característico x do conjunto de arcos de P é uma solução viável do pl. Reciprocamente, toda solução viável x do pl que tenha componentes em {0, 1} representa um dicaminho simples de r a s.

As condições de folgas complementares para o par dual de programas lineares são as seguintes: para cada arco vw, xvw > 0 implica yw − yv = cvw. Essas condições

(31)

equivalem à minimalidade de cx e à maximalidade de ys− yr. Em termos do problema

dos dicaminhos mínimos, isso corresponde à seguinte afirmação: todos os arcos de qualquer dicaminho mínimo de r a s são justos.

Exercícios

2.27 Prove o teorema min-max2.7a partir do teorema2.5e da proposição2.2.

2.28 Mostre que a hipótese “existe um dicaminho mínimo de r a s” no teorema min-max2.7é lente à seguinte: “existe um dicaminho de r a s e existe um potencial viável”. Também é equiva-lente à seguinte: “existe um dicaminho de r a s mas não existe dicircuito de custo negativo.” 2.29 Dê um exemplo para mostrar que o pl (2) pode ter uma solução ótima x que não é vetor

caracte-rístico de um dicaminho de r a s.

2.30 ? Prove que todo dicaminho mínimo de r a s descreve uma solução ótima do pl (2). (Dica: Para cada arco e, seja xeo número de ocorrências do arco e no dicaminho. Use o teorema

min-max2.7para obter uma solução ótima do pl (1). Depois, aplique o teorema forte da dualidade da programação linear ao par de pl’s.)

2.31 Dual inviável ou ilimitado. Mostre que o pl (1) pode ser inviável. Mostre que o pl (1) pode ser ilimitado.

2.32 Primal inviável ou ilimitado. Mostre que o pl (2) pode ser inviável. Mostre que o pl (2) pode ser ilimitado.

2.7

Algoritmo especial para redes acíclicas

Um digrafo é acíclico se não tem dicircuitos dirigidos. Como se sabe, um digrafo é ací-clico se e somente se tem uma permutação topológica. Uma permutação v1, v2, . . . , vn

dos nós de um digrafo é topológica se i < j para cada arco vivj, isto é, se todos os arcos

apontam da esquerda para a direita.

Quando restrito a redes acíclicas, o algoritmo de Ford-Bellman pode ser organizado de modo a examinar cada arco uma só vez: partindo de uma permutação topológica v1, v2, . . . , vn dos nós, examine os arcos que saem de v1, depois os que saem de v2, e

assim por diante.

Como não tem dicircuitos, uma rede acíclica satisfaz uma das condições necessárias para que o problema 2.1 (dos dicaminhos mínimos) tenha solução. Para que a outra condição — todos os nós ao alcance do nó inicial r — esteja satisfeita é necessário (mas não suficiente) que tenhamos r = v1.

Digrafos acíclicos são conhecidos pela abreviatura DAG de directed acyclic graph. A ver-são do algoritmo de Ford-Bellman especializado em DAGs recebe uma permutação topológica v1, v2, . . . , vn dos nós de uma rede acíclica e procura resolver o problema

dos dicaminhos mínimos a partir do nó inicial v1:

FORDBELLMANDAG (G, c, (v1, . . . , vn))

1 para cada w em V (G) faça yw ← ∞

(32)

3 para i ← 1 até n − 1 faça 4 para cada vw em ∂− (vi)faça 5 se yv+ cvw < yw 6 então yw ← yv+ cvw 7 p(w) ← v 8 devolva y e p (Na linha 4, ∂−

(vi) é o conjunto de todos os arcos que saem de vi.) A análise do

algoritmo usa a ideia de sequências de varredura boas da seção2.4. Seja S a sequência em que o algoritmo examina os arcos. Essa sequência tem a seguinte propriedade: se i < jentão todos os arcos em ∂−

(vi)aparecem em S antes de todos os arcos em ∂−(vj).

Portanto, todo dicaminho com origem r está imerso em S. De acordo com a proposi-ção2.6, o potencial y fica viável tão logo o algoritmo termina de percorrer S.

Consumo de tempo. Como cada arco aparece apenas uma vez em S, o algoritmo consome apenas O(m) unidades de tempo.

No fim da execução do algoritmo, p define dicaminhos mínimos de v1 a cada nó que

esteja ao alcance de v1. Portanto, essa instância do problema 2.1 está resolvida se e

somente se o algoritmo terminar com yw < ∞para todo w.

Exercícios

2.33 Permutação topológica. Prove que todo digrafo acíclico tem uma permutação topológica. Escreva um algoritmo que receba um digrafo e devolva uma permutação topológica ou um dicircuito. O consumo de tempo do seu algorimo deve ser O(m).[CCPS 2.33]

2.34 Árvores divergentes. Escreva uma versão especial do algoritmo FORDBELLMANDAG para tratar de árvores divergentes.

2.35 Aplique o algoritmo FORDBELLMANDAG à rede acíclica (G, c, r) com V (G) = {r, s, t, u, v} e E(G) e c definidos abaixo. Adote a permutação topológica (r, s, t, u, v).

rs rt su st tv uv 2 2 4 3 1 −4

2.36 Suponha que uma rede tem uma permutação topológica v1, v2, . . . , vndos nós. Quero encontrar

dicaminhos mínimos a partir de um nó vh, com h > 1. Modifique o algoritmo FORDBELLMAN

-DAG para resolver o problema.

2.37 Aplique o algoritmo FORDBELLMANDAG à rede do exercício2.25.[CCPS 2.21]

2.38 ? Segmento de soma mínima. Dados números a1, . . . , an, queremos encontrar i e j, 1 ≤ i ≤ j ≤ n+1,

tais que ai+ · · · + aj−1seja mínimo. Dê um algoritmo que resolva o problema em O(n) unidades

de tempo.[CCPS 2.34]

2.39 ? Escalonamento de tarefas. Suponha dadas tarefas t1, . . . , tk. A execução de cada tarefa tiexige um

tempo pi. Para certos pares (i, j), a execução de tideve preceder a execução de tj(ou seja, o

pro-cessamento de tjsó pode começar depois que o processamento de titiver terminado). Queremos

planejar a execução das tarefas de modo que as restrições de precedência sejam respeitadas e cada tarefa seja concluída tão cedo quanto possível (note que várias tarefas podem ser executadas ao mesmo tempo). Reduza esse problema ao cálculo de um potencial viável máximo em um DAG.

(33)

2.8

Algoritmo especial para custos não-negativos

Para redes sem arcos de custo negativo (e portanto sem dicircuitos de custo negativo) é possível acelerar o algoritmo de Ford-Bellman. Para fazer isso, é preciso examinar os nós numa determinada ordem, à maneira do que fizemos com redes acíclicas. Mas a permutação dos nós não pode ser estabelecida de antemão nesse caso, devendo ser calculada à medida que o algoritmo é executado: no começo de cada iteração, o próximo nó da permutação é um nó v que tem potencial mínimo dentre os nós que ainda não foram examinados. Essa é a ideia do algoritmo que E.W. Dijkstra descobriu em 1959.

O algoritmo de Dijkstra recebe uma rede (G, c, r) com c ≥ 0 e produz uma função-predecessor p e um potencial viável y. Se todos os nós estiverem ao alcance de r, a função p define um dicaminho Pv de r a v tal que c(Pv) = yv− yr.

DIJKSTRA(G, c, r)  c ≥ 0

01 para cada w em V (G) faça yw ← ∞

02 yr ← 0

03 Q ← V (G) r {r} 04 enquanto Q 6= ∅ faça

05 escolha v em Q tal que yv é mínimo

06 Q ← Q r {v} 07 para cada vw em ∂−(v) faça 08 se yv+ cvw< yw  vw está tenso 09 então yw ← yv+ cvw  relaxação de vw 10 p(w) ← v 11 devolva p e y

Para provar que o algoritmo está correto, basta verificar que no início de cada iteração temos (i1) yu ≤ yq para cada u em V (G) r Q e cada q em Q e (i2) para cada u em

V (G) r Q, todos os arcos em ∂−(u)

estão relaxados. Assim, no fim da execução do algoritmo, todos os arcos estarão relaxados e portanto o potencial y terá a propriedade desejada.

O algoritmo consome tempo O(m) + O(n2). O termo O(m) reflete o fato de que cada

arco é processado no máximo uma só vez. O termo O(n2)é uma delimitação do tempo

total dispendido em todas as execuções de linha 05 (que escolhe v em Q). Portanto, o algoritmo consome O(n2)unidades de tempo.

Exercícios

2.40 Mostre que o algoritmo de Dijkstra pode dar resultados errados se a rede tiver dicircuitos de custo negativo.[CCPS 2.36]

2.41 Prove os invariantes (i1) e (i2) do algoritmo de Dijkstra. 2.42 Prove que w ∈ Q sempre que o arco vw está tenso na linha 08.

(34)

na i-ésima iteração. Agora considere a sequência S = (a1, a2, . . . , am)de arcos que o algoritmo

examina nas sucessivas passagens pela linha 07: primeiro todos os arcos que saem de v0, depois

todos os arcos que saem de v1, e assim por diante. Mostre que no fim da execução do algoritmo

todos os dicaminhos mínimos que começam em r estão imersos em S. 2.44 Aplique o algoritmo de Dijkstra à rede do exercício2.25.[CCPS 2.21]

2.45 Translação de custos. Suponha que a função-custo c de uma rede tem valores negativos. Eis uma ideia simples para eliminar os custos negativos. Seja µ := min(ce : e ∈ E(G))e subtraia µ do

custo de cada arco. Agora todos os custos são não-negativos. Aplique o algoritmo de Dijkstra usando os novos custos. Os dicaminhos mínimos produzidos pelo algoritmo têm custo mínimo em relação à função c original?[AMO 5.21]

2.46 Redes não-dirigidas. Considere a variante do problema2.1que procura por caminhos não-dirigidos mínimos em grafos não-dirigidos com custos não-negativos nas arestas. Mostre como reduzir esse problema ao problema 2.1. Qual a dificuldade de fazer a mesma coisa no caso de custos arbitrários?[CCPS 2.37]

2.9

Custos unitários e busca em largura

A versão especializada do algoritmo de Dijkstra para os caso em que c = 1 é particular-mente simples. O conjunto Q do algoritmo de Dijkstra pode ser inicializado com {r} e tratado como uma fila.

BUSCAEMLARGURA(G, r)

01 para cada w em V (G) faça yw ← ∞

02 yr ← 0

03 Q ← INICIALIZAFILA(r)

04 enquanto FILANÃOVAZIA(Q)faça 05 v ←TIRADAFILA(Q) 06 para cada vw em ∂− (v)faça 07 se yv+ cvw < yw  vw está tenso 08 então yw ← yv+ cvw  relaxação de vw 09 p(w) ← v 10 PÕENAFILA(Q, w) 11 devolva p e y

Essa versão do algoritmo de Dijkstra é conhecida como busca em largura. Ela consome O(m)unidades de tempo.

Exercícios

2.47 Árvores. Escreva uma versão especial de BUSCAEMLARGURApara árvores divergentes Escreva uma versão especial de BUSCAEMLARGURApara árvores não-dirigidas.

(35)

2.10

Exercícios adicionais

2.48 Suponha dada uma rede (G, c, r) e um nó w que incide em exatamente dois arcos (ou seja, ape-nas dois arcos têm w como ponta inicial ou ponta final). Mostre como reduzir o problema dos dicaminhos mínimos nessa rede a uma rede menor.[CCPS 2.23]

2.49 Suponha que (G, c, r) é uma rede em que todos os arcos têm o mesmo custo. Qual o algoritmo assintoticamente mais rápido para resolver o problema dos dicaminhos mínimos nesse rede? 2.50 Arbitragem cambial. Seja (G, c, r) uma rede com custos positivos. Para cada nó v, queremos

encon-trar um dicaminho de r a v que maximize o produto dos custos dos arcos do dicaminho. Como resolver o problema? (Aplicação: Cada nó é uma moeda, como dólar, real, yen, etc., e o custo de um arco vw é a taxa de câmbio na conversão de v em w.)

2.51 Capacidade mínima. Digamos que a capacidade de um dicaminho é o mínimo dos custos de seus arcos. Problema: Determine um dicaminho de capacidade mínima dentre os que vão de r a s. 2.52 Custos diretos e custos inversos. Suponha que cada arco e de uma rede tem dois custos, c0

e e c00e,

ambos em Q. O custo de um caminho P , não necessariamente dirigido, éP c0

e+P c00e, onde a

primeira soma se estende a todos os arcos diretos de P e a segunda a todos os arcos inversos de P . Problema: Determinar um caminho de custo mínimo dentre os que vão de um nó r a um nó s. Enuncie uma condição de otimalidade apropriada.

2.53 ? Árvores. Seja (T, c) uma rede em que T é uma árvore não-dirigida (veja a seção1.1) e c uma função-custo. Escreva um algoritmo que receba T , c, e um nó r e calcule, para cada nó v, um caminho (não necessariamente dirigido!) de custo mínimo de r a v em T .

2.54 Análise de sensibilidade. Seja (G, c, r) uma rede sem dicircuitos de custo negativo. Para cada nó v, digamos que dv é a distância de r a v, ou seja, o custo de um dicaminho mínimo de r a v. De

(36)
(37)

Fluxo máximo e corte mínimo

O problema do fluxo máximo entre dois nós de uma rede com restrições de capacidade nos arcos é um modelo fundamental em otimização combinatória.

3.1

Fluxo

Um fluxo em um digrafo G é qualquer função de E(G) em Q+. Em outras palavras,

um fluxo é uma função que atribui um número racional não-negativo a cada arco do digrafo. (Note que um fluxo não precisa ter valores inteiros, ainda que algumas aplicações tenham especial interesse em fluxos inteiros.)

Se x é um fluxo e R é um conjunto de nós do digrafo, denotamos por x+

(R)a soma dos valores de x nos arcos que entram em R:

x+(R) :=P (x

uv: uv ∈ ∂+(R)) .1

(Já usamos essa notação na seção2.6.) Analogamente, x−

(R)é a soma dos valores de x nos arcos que saem de R:2

x−

(R) :=P (xvw : vw ∈ ∂−(R)) .

É claro que x−

(R) = x+(R)

, sendo R := V (G) r R. O excesso, ou acúmulo, ou saldo (= net flow) de x em R é a “quantidade” de fluxo que fica “retida” em R. O excesso é denotado por x+ −(R): x+ −(R) := x + (R) − x− (R) . Para qualquer nó v, escrevemos x+

(v), x− (v) e x+ −(v) no lugar de x + ({v}), x− ({v}) e x+ −({v})respectivamente.

1Eu deveria escrever “x(∂+(R))”, mas a abreviatura “x+(R)” é perfeitamente razoável.

2Para justificar os superscritos “+” e “−”, você pode imaginar que os nós são contas bancárias e os

arcos representam movimentação de dinheiro: tudo que entra numa conta é somado ao saldo e tudo que sai é subtraído.

Referências

Documentos relacionados

Figura A53 - Produção e consumo de resinas termoplásticas 2000 - 2009 Fonte: Perfil da Indústria de Transformação de Material Plástico - Edição de 2009.. A Figura A54 exibe

A participação foi observada durante todas as fases do roadmap (Alinhamento, Prova de Conceito, Piloto e Expansão), promovendo a utilização do sistema implementado e a

Anne Teresa De Keersmaeker e Jean-Guihen Queyras (o violoncelista que vai acompanhar ao vivo os bailarinos, tocando as suites de seguida, em tours de force de mais de duas

Código Descrição Atributo Saldo Anterior D/C Débito Crédito Saldo Final D/C. Este demonstrativo apresenta os dados consolidados da(s)

Mediante o impacto do paciente com o ambiente do centro cirúrgico, a equipe de enfermagem deve estar voltada para o aspecto humano do atendimento, centrando suas

c.4) Não ocorrerá o cancelamento do contrato de seguro cujo prêmio tenha sido pago a vista, mediante financiamento obtido junto a instituições financeiras, no

Os autores relatam a primeira ocorrência de Lymnaea columella (Say, 1817) no Estado de Goiás, ressaltando a importância da espécie como hospedeiro intermediário de vários parasitos

As abraçadeiras tipo TUCHO SIMPLES INOX , foram desenvolvidas para aplicações que necessitam alto torque de aperto e condições severas de temperatura, permitin- do assim,