renatowerneck.files.wordpress.com · tos agradecimen os a professores marcus oggi p de aragão,...

154

Upload: others

Post on 20-Sep-2020

0 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Renato Fonseca Furquim Werneck

Problema de Steiner em Grafos: Algoritmos Primais,

Duais e Exatos

DISSERTAÇÃO DE MESTRADO

DEPARTAMENTO DE INFORMÁTICA

Rio de Janeiro, Agosto de 2001

Page 2: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Renato Fonseca Furquim Werneck

Problema de Steiner em Grafos: Algoritmos Primais,

Duais e Exatos

Dissertação apresentada ao Departamento de

Informática da PUC-Rio como parte dos re-

quisitos para a obtenção do título de Mestre

em Ciências em Informática.

Orientador: Prof. Marcus Poggi de Aragão

Departamento de Informática

Pontifícia Universidade Católica do Rio de Janeiro

Rio de Janeiro, Agosto de 2001

Page 3: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

A meus pais

Page 4: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Agradecimentos

Aos Professores Marcus Poggi de Aragão, Eduardo Uchoa e Celso Ribeiro, por não me

deixarem esquecer de que sempre é possível trabalhar um pouco mais.

Aos amigos (incluindo o trio acima), por tentarem me convencer de que é possível trabalhar

um pouco menos.

Aos professores Cid de Souza, Luiz Satoru Ochi, Ruy Milidiú e Eduardo Laber, pela

participação na banca examinadora.

À CAPES, pelo apoio �nanceiro.

Page 5: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

RESUMO

O problema de Steiner em grafos é um dos mais importantes problemas NP-difíceis de

otimização combinatória, com aplicações em áreas como projeto de circuitos VLSI, redes,

logística e biologia computacional. Esta dissertação apresenta um estudo computacional

de diversas estratégias para lidar na prática com instâncias desse problema. Discutem-se

métodos de várias categorias: heurísticas construtivas, métodos de busca local, metaeurís-

ticas, heurísticas duais e algoritmos exatos. Cada categoria representa uma maneira

particular de se lidar com o problema: variam os tempos de execução, a qualidade das

soluções obtidas e as garantias fornecidas. Em cada caso, faz-se uma análise dos principais

algoritmos disponíveis na literatura e propõem-se novos procedimentos. O resultado é um

conjunto de ferramentas que representa o estado-da-arte da pesquisa na área. Com isso,

muitas das instâncias em aberto da literatura foram resolvidas ou tiveram as melhores

soluções conhecidas encontradas pelos métodos apresentados.

Palavras-chaves: problema de Steiner em grafos, algoritmos, otimização combinatória,

heurísticas construtivas, busca local, metaeurísticas, heurísticas duais, branch-and-bound.

Page 6: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

ABSTRACT

The Steiner problem in graphs is one of the most important NP-hard problems in combi-

natorial optimization, with applications in VLSI design, networks, logistics and computa-

tional biology, among others. We present a computational assessment of several strategies

to deal with this problem in practice. The methods are divided into a number of classes:

constructive heuristics, local search procedures, metaheuristics, dual heuristics and exact

algorithms. Each class has its own way of dealing with the problem: running times, solu-

tion qualities and guarantees provided di�er among them. We discuss the most relevant

algorithms described in the literature and propose new ones. The result is a collection of

tools that represent the state-of-the-art in practical algorithms for the Steiner problem in

graphs. Several open instances in the literature were solved or had their bounds improved

by these methods.

Keywords: Steiner problem in graphs, algorithms, combinatorial optimization, construc-

tive heuristics, local search, metaheuristics, dual heuristics, branch-and-bound.

Page 7: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Sumário

1 Introdução 1

2 Aspectos Gerais 4

2.1 Notação e De�nições Relevantes . . . . . . . . . . . . . . . . . . . . . . . . 4

2.2 Estruturas de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2.1 Heaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.2.2 Union-Find . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.3 Algoritmos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.3.1 Árvore Geradora de Custo Mínimo . . . . . . . . . . . . . . . . . . 6

2.3.2 Caminhos Mínimos . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.4 Experimentos Computacionais . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.4.1 Ambiente de Teste . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.4.2 Instâncias de Teste . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.5 Pré-processamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3 Heurísticas Construtivas 14

3.1 Distance Network Heuristic (DNH) . . . . . . . . . . . . . . . . . . . . . . 15

3.1.1 Diagrama de Voronoi . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3.1.2 Implementação da Heurística DNH (DNH-Prim) . . . . . . . . . . . 17

3.1.3 Implementação Alternativa (DNH-Bor·vka) . . . . . . . . . . . . . 18

3.1.4 Variante DNHz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

3.2 Bor·vka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

3.3 Prim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3.3.1 Implementação em Duas Fases (Prim-T) . . . . . . . . . . . . . . . 21

3.3.2 Implementação Direta (Prim-D) . . . . . . . . . . . . . . . . . . . . 22

3.4 Kruskal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

3.4.1 Implementação Básica (Kruskal-B) . . . . . . . . . . . . . . . . . . 24

3.4.2 Implementação com Heap de Arestas (Kruskal-E) . . . . . . . . . . 25

3.4.3 Implementação com Heap de Vértices (Kruskal-V) . . . . . . . . . . 27

3.5 Multispan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

3.6 Análise Comparativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

3.6.1 Qualidade das Soluções . . . . . . . . . . . . . . . . . . . . . . . . . 30

3.6.2 Tempos de Execução . . . . . . . . . . . . . . . . . . . . . . . . . . 34

vii

Page 8: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

3.7 Conclusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

4 Busca Local 44

4.1 Representação da Solução . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

4.2 Vizinhanças . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

4.2.1 Vértices de Steiner . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

4.2.2 Caminhos-chaves . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4.2.3 Vértices-chaves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4.3 Implementação da Busca Local . . . . . . . . . . . . . . . . . . . . . . . . 48

4.3.1 Estratégia Geral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

4.3.2 Busca por Vértices de Steiner . . . . . . . . . . . . . . . . . . . . . 49

4.3.3 Busca por Caminhos-chaves . . . . . . . . . . . . . . . . . . . . . . 50

4.3.4 Busca por Vértices-chaves . . . . . . . . . . . . . . . . . . . . . . . 53

4.3.5 Estratégias Híbridas . . . . . . . . . . . . . . . . . . . . . . . . . . 55

4.4 Resultados Experimentais . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

4.5 Conclusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

5 Metaeurísticas 63

5.1 HGP+PR: Estrutura Básica . . . . . . . . . . . . . . . . . . . . . . . . . . 63

5.2 Heurísticas Construtivas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

5.3 Busca Local . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

5.4 Estratégias de Perturbação . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

5.5 Religamento (Path-relinking) . . . . . . . . . . . . . . . . . . . . . . . . . 68

5.5.1 Soluções de Elite . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

5.5.2 Estratégias de Religamento . . . . . . . . . . . . . . . . . . . . . . 69

5.5.3 Critérios de Parada . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

5.6 Resultados Experimentais . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

5.6.1 Implementação com Parâmetros de Referência . . . . . . . . . . . . 73

5.6.2 Escalabilidade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

5.7 Conclusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

6 Algoritmos Duais 82

6.1 Formulação e Dualidade . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

6.1.1 Formulação Primal . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

6.1.2 Formulação Dual . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84

6.1.3 Complementaridade de Folga . . . . . . . . . . . . . . . . . . . . . 85

6.1.4 Fixação por Custos Reduzidos . . . . . . . . . . . . . . . . . . . . . 86

6.2 Dual Ascent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92

6.2.1 Soluções Primais . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

6.2.2 Implementação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

6.2.3 Seleção da Componente-raiz . . . . . . . . . . . . . . . . . . . . . . 95

6.2.4 Resultados Experimentais . . . . . . . . . . . . . . . . . . . . . . . 96

6.3 Outras Heurísticas Duais . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

viii

Page 9: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

6.3.1 Dual Scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

6.3.2 Dual Adjustment . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

6.3.3 Fixação Ativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

6.3.4 Resultados Experimentais . . . . . . . . . . . . . . . . . . . . . . . 104

6.4 Conclusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105

7 Algoritmos Exatos 107

7.1 Branch-and-bound e Enumeração Implícita . . . . . . . . . . . . . . . . . . 107

7.2 Branch-and-Cut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

7.2.1 Limites Inferiores . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108

7.2.2 Soluções Primais . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109

7.2.3 Branching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

7.3 Branch-and-Ascent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

7.3.1 Método de Resolução de um Nó . . . . . . . . . . . . . . . . . . . . 111

7.3.2 Branching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

7.4 Resultados Experimentais . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

7.4.1 Incidência . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

7.4.2 OR-Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

7.4.3 VLSI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120

7.5 Conclusão . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122

8 Conclusão 125

A Resultados do Pré-processamento 128

ix

Page 10: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Lista de Figuras

3.1 Tempos de execução em função do número de terminais . . . . . . . . . . . 40

3.2 Tempos de execução em função do número de terminais (métodos mais

rápidos) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

4.1 Comparação entre a heurística de Prim e árvore geradora do grafo de dis-

tâncias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

5.1 Pseudocódigo do GRASP híbrido com perturbações e religamento . . . . . 65

6.1 Condição para a �xação de (u; v) por custo reduzido . . . . . . . . . . . . . 87

6.2 Dual Ascent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

6.3 Dual Scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

6.4 Dual Adjustment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102

6.5 Fixação Ativa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

7.1 Solução ótima da instância alue7080 . . . . . . . . . . . . . . . . . . . . . . 123

x

Page 11: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Lista de Tabelas

3.1 Qualidade relativa das diversas heurísticas estudadas . . . . . . . . . . . . 32

3.2 Desvios percentuais médios em relação às melhores soluções primais conhe-

cidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

3.3 Complexidade dos algoritmos construtivos estudados . . . . . . . . . . . . 34

3.4 Tempos médios de execução (absolutos) dos métodos construtivos . . . . . 35

3.5 Tempos médios de execução das heurísticas construtivas em relação a DNH-

Prim . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

3.6 Piores tempos de execução dos métodos construtivos em relação a DNH-Prim 37

4.1 Estratégias formadas pelas buscas por nós de Steiner e caminhos-chaves . . 57

4.2 Estratégias que utilizam a busca por nós-chaves . . . . . . . . . . . . . . . 58

4.3 Desvios percentuais médios em relação às melhores soluções conhecidas . . 59

4.4 Tempos médios de execução . . . . . . . . . . . . . . . . . . . . . . . . . . 60

5.1 Coe�cientes máximos para aleatorização . . . . . . . . . . . . . . . . . . . 67

5.2 Qualidade das soluções obtidas ao longo da execução da implementação de

referência . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

5.3 Tempos médios de execução da implementação de referência . . . . . . . . 75

5.4 Metaeurísticas: desvios relativos percentuais médios . . . . . . . . . . . . . 76

5.5 Metaeurísticas: número de soluções ótimas encontradas . . . . . . . . . . . 76

5.6 Metaeurísticas: tempos de execução em segundos (com diferentes máquinas) 77

5.7 Execuções �longas� para instâncias de incidência (256 iterações, 32 soluções

de elite e religamento por perturbações com critério de parada ABW ) . . . 78

6.1 Critérios para escolha da componente-raiz por classe . . . . . . . . . . . . . 97

6.2 Critérios para escolha da componente-raiz (todas as instâncias testadas) . . 98

6.3 Resultados obtidos pelas heurísticas duais . . . . . . . . . . . . . . . . . . 105

7.1 Resultados do branch-and-ascent nas séries i080 e i160 e comparação de

tempos (em segundos) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114

7.2 Resultados do branch-and-ascent nas séries i320 e i640 e comparação de

tempos (em segundos) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115

7.3 Comparação entre o branch-and-ascent (B&A) e o branch-and-cut (B&C) . 116

7.4 Resultados do branch-and-ascent com strong-branching nas 24 instâncias

da série i320 não resolvidas até janeiro de 2001, segundo a SteinLib . . . . 117

xi

Page 12: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

1

7.5 Resultados do branch-and-cut para a classe OR-Library . . . . . . . . . . . 119

7.6 Branch-and-ascent com strong branching para a classe OR-Library . . . . . 119

7.7 Resultados obtidos para instâncias VLSI . . . . . . . . . . . . . . . . . . . 121

8.1 Resultados para a instância i320-311 (jV j = 320; jEj = 1845; jT j = 80) . . . 126

8.2 Resultados para a instância alue7080 (jV j = 9272; jEj = 16019; jT j = 1402) 126

A.1 OR-Library � Série C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

A.2 OR-Library � Séries D e E . . . . . . . . . . . . . . . . . . . . . . . . . . 130

A.3 VLSI � Séries alue e alut . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

A.4 VLSI � Séries diw e taq . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132

A.5 VLSI � Séries dmxa e gap . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

A.6 VLSI � Série msm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

Page 13: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Capítulo 1

Introdução

Esta dissertação apresenta um estudo algorítmico do problema de Steiner em grafos, que

pode ser de�nido da seguinte forma:

Dados um grafo não-orientado G = (V;E) com pesos positivos associados às

arestas e um conjunto de terminais T � V , encontrar um subgrafo conexo de

G de custo mínimo que contenha todos os vértices de T .

Como os pesos são positivos, a solução ótima será sempre uma árvore, a árvore de Steiner

mínima. Esse problema tem aplicações práticas em diversas áreas, como:

� Projeto de Redes. Árvores de Steiner representam em geral a solução de menor

custo para o projeto de diversos tipos de redes, como telefônica, ferroviária ou de

águas pluviais. O objetivo é sempre o mesmo: ligar da maneira mais e�ciente

possível o conjunto dos pontos que devem ser servidos (os terminais), utilizando

outros pontos se necessário.

� Roteamento de Pacotes em Redes comMulticast . Nesse caso, os nós do grafo

representam máquinas e as arestas, os links entre elas. O peso de uma aresta é uma

medida de sua velocidade ou capacidade; os terminais representam as máquinas que

devem receber o pacote.

� Projeto de Circuitos Integrados. Um problema comum no projeto de circuitos

integrados é decidir como levar um mesmo sinal a diferentes terminais. Como uma

árvore de Steiner ótima representa a ligação que requer a menor quantidade de

material condutor, encontrar uma boa solução para esse problema pode contribuir

signi�cativamente para a redução do custo de fabricação da peça.

Trata-se de um problema muito estudado na literatura. Levantamentos sobre os mais

importantes resultados (à época) disponíveis para o problema são feitos, por exemplo, em

[28, 36, 62].

1

Page 14: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 1. INTRODUÇÃO 2

O problema de Steiner em grafos é NP-difícil [31], o que signi�ca que provavelmente

não existe um algoritmo polinomial capaz de resolvê-lo. Dada a sua importância prática,

no entanto, é plenamente justi�cável que se tente resolver o problema da melhor possível,

seja através de algoritmos aproximados, seja através de algoritmos exatos (ainda que, no

pior caso, tenham tempo de execução superpolinomial).

É exatamente disso que trata esta dissertação: algoritmos para o problema de Steiner

em grafos que sejam úteis na prática. Faz-se um estudo teórico dos algoritmos apresen-

tados, mas a ênfase é na análise empírica de seu comportamento. Extensos experimentos

computacionais sobre centenas de instâncias disponíveis na literatura permitem uma avali-

ação precisa das vantagens e desvantagens de cada método.

Na dissertação são apresentados algoritmos de três diferentes categorias: heurísticas

primais, heurísticas duais e algoritmos exatos. As heurísticas primais foram divididas em

três subcategorias: heurísticas construtivas, métodos de busca local e metaeurísticas.

Heurísticas construtivas são métodos que criam soluções viáveis para o problema de

forma gulosa. São procedimentos normalmente muito rápidos, executados em frações de

segundo para as instâncias testadas. O Capítulo 3 trata desses métodos, concentrando-se

principalmente nos baseados no problema da árvore geradora de peso mínimo. Propõem-

se tanto novas heurísticas quanto implementações mais e�cientes para algumas das já

existentes.

Quando a qualidade de uma solução construtiva deixa a desejar, pode-se utilizar um

método de busca local. A partir da solução inicial, ele procura obter soluções similares, mas

de melhor qualidade. Trata-se de um procedimento um pouco mais custoso, tipicamente

executado em alguns segundos, às vezes minutos, para as instâncias testadas. O Capítulo 4

apresenta um estudo comparativo de três procedimentos de busca local.

O Capítulo 5 trata de metaeurísticas, termo que se caracteriza algoritmos mais ela-

borados para a obtenção de soluções primais de boa qualidade. Em geral, resultam da

combinação de elementos mais simples, como heurísticas construtivas e métodos de bus-

ca local. A dissertação introduz a metaeurística HGP+PR, um algoritmo extremamente

robusto, capaz de obter excelentes resultados para as mais diversas classes de instâncias.

No Capítulo 6, apresentam-se algumas heurísticas duais, algoritmos que têm como

principal objetivo fornecer limites inferiores para o valor da solução ótima (ao contrário

das heurísticas primais, que, ao encontrar soluções viáveis, fornecem limites superiores

para o problema). Os limites inferiores permitem que se avalie a qualidade das soluções

viáveis encontradas (e, em alguns casos, provam sua otimalidade).

A partir de algoritmos para a obtenção de limites superiores e inferiores, é possível criar

algoritmos exatos para o problema de Steiner. O Capítulo 7 introduz as rotinas de branch-

and-cut e branch-and-ascent, métodos de enumeração implícita baseados na construção

de árvores de resolução, técnica freqüentemente utilizada na resolução de problemas NP-

difíceis. Conforme se verá, os algoritmos propostos são extremamente competitivos, tendo

sido capazes de resolver à otimalidade pela primeira vez diversas instâncias da literatura.

Page 15: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 1. INTRODUÇÃO 3

Entre os algoritmos propostos, há desde os que são capazes de fornecer soluções viáveis

em frações de segundo até os que podem levar dias (ou mais) para tratar a mesma instân-

cia. Evidentemente, a qualidade das soluções obtidas tende a aumentar signi�cativamente

com o tempo de execução. O Capítulo 8 analisa essas diferenças com base em alguns casos

particulares.

Page 16: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Capítulo 2

Aspectos Gerais

Antes de se iniciar o estudo de algoritmos especí�cos para o problema de Steiner em grafos,

é conveniente introduzir algumas noções básicas e de�nir a metodologia a ser utilizada.

A Seção 2.1 de�ne a notação básica utilizada ao longo da dissertação e introduz alguns

conceitos essenciais associados ao problema de Steiner em grafos. A Seção 2.2 apresenta

as estruturas de dados genéricas mais importantes utilizadas neste trabalho: heaps e

estruturas union-�nd. A Seção 2.3 trata de algoritmos para a determinação de árvores

geradoras de custo mínimo e de caminhos mínimos em grafos, problemas freqüentemente

mencionados ao longo desta dissertação. A Seção 2.4 trata de aspectos relevantes para os

experimentos computacionais realizados: o ambiente de teste e as instâncias utilizadas.

Por �m, a Seção 2.5 discute as rotinas utilizadas para o pré-processamento de algumas

das instâncias testadas ao longo da dissertação.

2.1 Notação e De�nições Relevantes

Esta seção trata de algumas notações e de�nições utilizadas ao longo de toda a dissertação.

Conceitos mais especí�cos serão apresentados no contexto em que se �zerem necessários.

O problema básico de que trata essa tese é o problema de Steiner em grafos, de�nido

na Introdução (Capítulo 1). Em algumas situações, será utilizada a sigla SPG (do inglês

Steiner problem in graphs) para representar o problema. Considera-se sempre que a

entrada do problema é constituída por um grafo não-orientado G = (V;E) (sendo V o

conjunto de vértices � também chamados de nós � e E o de arestas) e por um conjunto T

de terminais, sendo T � V . O grafo é positivamente ponderado, o que signi�ca que a toda

aresta e 2 E está associado um custo (ou peso) c(e) maior que zero. Nesta dissertação,

considera-se que os custos são sempre inteiros. Para indicar que as extremidades de uma

aresta e são os vértices u e v, utiliza-se a notação e = (u; v). Nesse caso, o custo de e

pode ser representado também por c(u; v).

4

Page 17: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 2. ASPECTOS GERAIS 5

2.2 Estruturas de Dados

2.2.1 Heaps

Um heap é uma estrutura de dados que implementa uma �la de prioridades. Ele contém

diversos elementos, cada um associado a um valor, sua chave. Em todos os casos estudados

nesta dissertação, considera-se maior a prioridade dos elementos de menor chave. Um heap

provê as seguintes operações básicas:

� insert(x,k): insere no heap o elemento x com chave k;

� removeFirst(): retorna o elemento mais prioritário e o remove do heap;

� decreaseKey(x,k): reduz para k o valor da chave associada ao elemento x, aumen-

tando a sua prioridade.

Há na literatura diversas implementações diferentes desse tipo abstrato de dados. Nesta

dissertação, utilizou-se uma das mais simples, o heap binário. Ele permite realizar qual-

quer das operações acima em tempo O(logn), sendo n o número total de elementos. Há

implementações teoricamente mais e�cientes, como o heap de Fibonacci [20], que permite

realizar as operações insert e decreaseKey em tempo amortizado O(1) (removeFirst

continua tendo a mesma complexidade, O(logn)). Na prática, contudo, o heap binário,

de implementação muito mais simples, não tem desempenho signi�cativamente inferior

(sendo muitas vezes até mais rápido), já que as constantes associadas à sua implemen-

tação são menores (veja [23, 41], por exemplo). Discussões a respeito das duas variantes

podem ser encontradas em [9], entre outros.

2.2.2 Union-Find

Em muitos dos algoritmos apresentados ao longo dessa dissertação, é necessário manter

informações a respeito de conjuntos disjuntos. Utiliza-se para isso uma estrutura de

union-�nd [9, 56]. Essa estrutura de dados provê apenas três operações básicas:

� makeset(x): cria um conjunto unitário contendo o elemento x;

� unite(x,y): une o conjunto que contém o elemento x ao conjunto que contém o

elemento y;

� find(x): retorna o conjunto que contém o elemento x (para decidir se dois elementos

x e y pertencem ao mesmo conjunto, basta testar se find(x) = find(y)).

Repare que essa estrutura não permite a partição de conjuntos em conjuntos menores,

o que limita as situações em que ela pode ser utilizada, mas lhe permite ser mais e�ciente.

Page 18: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 2. ASPECTOS GERAIS 6

Em [55], Tarjan prova que é possível realizar qualquer seqüência de m operações, sendo n

do tipo makeset (criação de conjuntos), em tempo total O(m�(m;n)). Nessa expressão,

�(�; �) denota a inversa da função de Ackermann, uma função cujo valor é menor que 4 em

qualquer aplicação prática (portanto, para todos os efeitos, cada operação pode ser reali-

zada em tempo amortizado constante). A implementação que garante essa complexidade

foi a utilizada nesta dissertação.

2.3 Algoritmos

2.3.1 Árvore Geradora de Custo Mínimo

O problema da árvore geradora de custo mínimo (MST, por seu nome em inglês � min-

imum spanning tree) pode ser de�nido da seguinte forma: dado um grafo não-orientado,

conexo e positivamente ponderado G = (V;E), determinar um subgrafo de G de peso mí-

nimo que contenha todos os vértices de V . Como os pesos são positivos, o resultado será

sempre uma árvore, considerada geradora porque contém todos os vértices do grafo ori-

ginal. Trata-se de um dos problemas mais estudados em otimização combinatória, o que

explica a existência de diversos algoritmos e�cientes para resolvê-lo. Nesta dissertação,

apenas três algoritmos serão analisados: os algoritmos de Prim, Kruskal e Bor·vka. A

descrição desses algoritmos pode ser encontrada em, entre outros, em [2, 9, 56]. Abaixo,

discute-se brevemente cada um deles.

Prim No algoritmo de Prim [48], a solução cresce a partir de um único vértice inicial

r, a raiz. Em cada etapa do algoritmo, adiciona-se à solução o vértice que se liga a ela

pela aresta de menor custo (a aresta também é adicionada à solução). Para determinar de

forma e�ciente qual vértice deve ser inserido em cada iteração, as distâncias dos vértices

à árvore são normalmente mantidas em um heap. Se for utilizado um heap binário,

pode-se provar que o algoritmo é executado em tempo O(jEj log jV j). Se o heap for de

Fibonacci, a complexidade de pior caso é O(jEj+ jV j log jV j). O algoritmo pode também

ser implementado sem um heap, em tempo O(jV j

2

) (essa implementação só é competitiva

para grafos muito densos).

Kruskal O algoritmo de Kruskal [34] é executado em duas etapas. Na primeira, todas

as arestas de E são ordenadas em ordem crescente de peso. Na segunda etapa, percorre-se

a lista em ordem, adicionando-se uma aresta à solução (inicialmente vazia) sempre que

ela não formar um ciclo. A primeira fase pode ser executada em tempo O(jEj log jEj);

a segunda, em tempo O(jEj�(jEj; jV j)), utilizando-se uma estrutura do tipo union-�nd

para controlar a formação de ciclos.

Page 19: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 2. ASPECTOS GERAIS 7

Bor·vka O algoritmo de Bor·vka [6], também conhecido como algoritmo de Sollin,

1

pode ser entendido como uma versão híbrida dos algoritmos de Kruskal e Prim. No

início, o algoritmo mantém jV j componentes conexas, cada uma composta por um úni-

co vértice. Em cada iteração, o algoritmo adiciona à árvore geradora mínima a aresta

de custo mínimo incidente em cada componente, criando componentes maiores. Como

uma mesma aresta pode ser a mínima incidente em duas componentes, pode-se garantir

apenas que o número de componentes é será reduzido à metade (no mínimo) em cada ite-

ração. Portanto, o número de iterações é limitado a log jV j. Como cada iteração pode ser

executada trivialmente em tempo O(jEj), o algoritmo como um todo tem complexidade

O(jEj log jV j). Com uma implementação mais elaborada, discutida em [56], o algoritmo

pode ser executado em tempo O(jEj log log jV j).

2.3.2 Caminhos Mínimos

Outro problema que freqüentemente aparece associado ao problema de Steiner em grafos

e o problema do caminho mínimo em grafos. Dado um grafo ponderado G = (V;E), o

problema consiste em determinar o caminho mínimo entre dois subconjuntos de V : S

(as fontes) e T (os alvos ou destinos). No caso em que as arestas têm pesos positivos, o

algoritmo normalmente utilizado para isso é o algoritmo de Dijkstra [10]. Uma discussão

sobre diferentes implementações é apresentada em [2], por exemplo.

O algoritmo se baseia na atribuição de potenciais aos vértices. O potencial p

v

de um

vértice v é um limite superior para a distância de v a S. No início do algoritmo, todos

os vértices em S têm potencial nulo e os demais, in�nito. Na implementação mais usual,

utiliza-se um heap para manter os vértices ainda não processados (todos, no início); os

vértices de menor potencial são prioritários. Em cada iteração do algoritmo, retira-se do

heap o vértice v mais prioritário: seu potencial no momento da retirada é justamente a

distância de v a S. Para todo vizinho w de v, atualiza-se o potencial p

w

se necessário

(se p

w

< p

v

+ c(v; w), faz-se p

w

p

v

+ c(v; w)). O algoritmo termina quando todos os

vértices de T forem retirados do heap.

A complexidade dessa implementação depende do tipo de heap utilizado: com um heap

de Fibonacci, é O(jEj+ jV j log jV j); com heap binário, O(jEj log jV j). Nesta dissertação,

foi utilizada a segunda implementação, mais simples que a primeira e com desempenho

satisfatório na prática [23]. Como no caso do algoritmo de Prim, seria possível também

utilizar uma implementação sem heaps, com tempo de execução O(jV j

2

). Isso não foi

feito porque a classe de instâncias para as quais essa implementação é e�ciente (grafos

extremamente densos) é muito restrita.

1

Para uma discussão a respeito do nome dado ao algoritmo, veja [2], por exemplo.

Page 20: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 2. ASPECTOS GERAIS 8

2.4 Experimentos Computacionais

2.4.1 Ambiente de Teste

Parte importante desta dissertação são os resultados computacionais obtidos. Toda a

implementação dos algoritmos foi feita em C++, sendo gcc o compilador utilizado (com

opção -O3, otimização máxima).

Os testes foram feitos em três diferentes máquinas: um AMD K6-2 de 350 MHz

e 128 MB de RAM, um Intel Pentium II de 400 MHz e 64 MB de RAM e uma Sun

UltraSparc 1 de 167 MHz e 64 MB de memória (em cada capítulo, �cará claro qual

máquina foi utilizada para os experimentos relatados). Nas duas primeiras máquinas foi

utilizado o sistema operacional Linux; na terceira, Solaris. Os dois PCs têm desempenho

muito próximo (o PC é ligeiramente mais rápido, mas não mais que 20%), mas a Sun é

signi�cativamente mais lenta (os tempos de execução nessa máquina são de 2.5 a 3 vezes

maiores). No entanto, como era essa a única máquina disponível com um resolvedor de

programas lineares (CPLEX 5.0 [29]), foi ela a utilizada no branch-and-cut apresentado

no Capítulo 7.

Os tempos de execução forammedidos com a função getrusage, que computa apenas o

tempo de CPU efetivamente utilizado pelo processo. Esse método tem precisão de 1/60 de

segundo. Para muitos dos algoritmos testados, especialmente as heurísticas construtivas

(Capítulo 3) e os métodos de busca local (Capítulo 4), essa precisão é insu�ciente para

permitir uma análise adequada, já que os tempos de execução são muito pequenos, às

vezes inferiores a um milésimo de segundo. Assim sendo, nesses casos fez-se necessário

executar cada método mais de uma vez sobre cada instância testada: os algoritmos foram

executados repetidas vezes até que se completassem cinco segundos. Em cada caso, apenas

o tempo total foi medido pela função getrusage; o tempo de cada execução foi calculado

pela divisão do tempo total pelo número de execuções.

No caso dos dos métodos de busca local (apresentados no Capítulo 4), a mesma semente

para o gerador de números aleatórios foi utilizada em todas as execuções. Já para as

heurísticas construtivas, a semente foi aleatoriamente determinada em cada execução. Na

comparação entre os métodos, considerou-se a média das soluções obtidas.

2.4.2 Instâncias de Teste

Instâncias para o problema de Steiner são muito dependentes da aplicação a que se rela-

cionam. Para o projeto de circuitos VLSI, por exemplo, normalmente as instâncias são

retilineares, com um número relativamente grande de nós (e às vezes de terminais) e baixa

densidade (o grau dos nós é limitado a quatro). Em outros casos, o número de nós é me-

nor, mas o número de arestas pode se multiplicar. Quando se desenvolve um algoritmo

de propósito geral, é interessante que seja testado em um conjunto de instâncias que seja

tão diversi�cado quanto possível.

Page 21: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 2. ASPECTOS GERAIS 9

Sendo o problema de Steiner em grafos um dos mais extensivamente estudados, há

uma multiplicidade de instâncias de teste disponíveis na literatura. São duas as princi-

pais vantagens de se utilizarem instâncias conhecidas em lugar de gerá-las aleatoriamente.

Em primeiro lugar, parte delas representa grafos encontrados em situações reais. Nem

sempre um algoritmo adequado para instâncias aleatórias tem desempenho satisfatório

para os casos encontrados na prática (e vice-versa). Em segundo lugar, não só são co-

nhecidas soluções exatas para um grande número dessas instâncias [32, 46, 44, 58], mas

também estão disponíveis os resultados obtidos por diversas heurísticas e metaeurísticas

de qualidade previamente desenvolvidas [3, 15, 16, 21, 38, 49]. Com isso, é possível com-

parar os novos algoritmos, como alguns dos apresentados nesta dissertação, com alguns

dos mais e�ciente códigos já publicados.

Em algumas situações, por outro lado, serão utilizadas instâncias aleatórias, construí-

das �sob medida� para testar aspectos especí�cos dos algoritmos implementados. No

Capítulo 3, por exemplo, faz-se isso para estudar de forma precisa a in�uência do número

de terminais sobre o tempo total de execução de diversos algoritmos.

Nas subseções se seguem, serão descritas as instâncias de teste utilizadas ao longo do

algoritmo. São ao todo quatro classes: OR-Library, Incidência, VLSI e PUC. As três

primeiras séries estão disponíveis na Internet no repositório SteinLib [33]. A classe PUC,

criada por Rosseti et al. [51], estará disponível no mesmo repositório a partir de agosto

de 2001. As quatro classes constituem um conjunto bastante heterogêneo de instâncias,

o que é muito útil para avaliar a robustez dos diversos algoritmos apresentados.

2.4.2.1 OR-Library

As instâncias da classe OR-Library, introduzidas por Beasley [4], baseiam-se em grafos

aleatórios com pesos inteiros uniformemente distribuídos no intervalo [1; 10]. Serão tes-

tadas três séries distintas, caracterizadas pelo número de vértices (n): c (500 vértices), d

(1000 vértices) e e (2500 vértices). Cada série tem 20 instâncias, resultado da combinação

de quatro diferentes números de arestas (1:25n, 2n, 5n, 25n) e cinco diferentes números de

terminais (5, 10, n=6, n=4, n=2) (os valores são arredondados para o inteiro mais próximo

quando necessário). Soluções ótimas são conhecidas para todas as instâncias dessa série

[32].

2.4.2.2 Incidência

Propostas por Duin e Volgenant [12, 14], estas instâncias são construídas sobre grafos

aleatórios e têm como principal propriedade o fato de que suas arestas têm pesos de

incidência. O peso de uma aresta é um inteiro escolhido em uma distribuição normal cuja

média depende do número de terminais em que a aresta é incidente (0, 1 ou 2). Se ambas

as extremidades da aresta forem não-terminais, a média é 100; se a aresta for incidente

em exatamente um terminal, a média será 200; se for incidente em dois terminais, a

Page 22: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 2. ASPECTOS GERAIS 10

média será 300. Essa escolha de pesos tem a �nalidade de tornar pouco e�cazes os testes

de redução (pré-processamento) normalmente utilizados (veja Seção 2.5). Na prática, é

realmente isso o que ocorre.

A classe das instâncias de incidência está dividida em quatro séries, de acordo com

o número de vértices (n): i080, i160, i320 e i640. Em cada série, há 20 diferentes com-

binações de números de terminais e números de arestas. Em uma série com n vértices,

há cinco diferentes números de arestas (3n=2, bn lognc, n(n � 1)=2, 2n, n(n � 1)=10) e

quatro diferentes números de terminais (blognc, b

p

nc, b2

p

nc, n=4). Para cada combi-

nação de arestas se terminais há cinco instâncias distintas. Cada série tem, portanto, 100

instâncias.

2

A nomenclatura utilizada na SteinLib é ivvv-xyz, sendo:

vvv: número de três dígitos indicando a quantidade de vértices (080, 160, 320 ou 640);

x: um dígito entre 0 e 3 identi�cando o número de terminais (0 signi�ca blognc, 1

signi�ca b

p

nc, etc.);

y: um dígito entre 0 e 4, numa referência ao número de arestas (0 signi�ca 3n=2, 1

signi�ca bn lognc, etc.);

z: um número de 1 a 5, numa referência à semente aleatória utilizada

Alguns dos algoritmos serão testados com apenas 20 instâncias de cada série (apenas uma

para cada combinação de dimensões). Seguindo o que foi feito [32], serão consideradas as

instâncias terminadas em �1�.

São conhecidas as soluções ótimas para todas as instâncias das séries i080 e i160 [32, 33].

Para a série i320, o primeiro algoritmo capaz de resolver à otimalidade todas as instâncias

é o branch-and-ascent apresentado na Seção 7.3, cuja primeira versão foi apresentada em

[44]. Da série i640, uma signi�cativa parcela dos problemas permanece em aberto.

2.4.2.3 VLSI

Ao contrário das duas classes anteriores, as instâncias VLSI originam-se de um problema

prático, o projeto de circuitos integrados. Introduzidas por Koch e Martin [32], correspon-

dem a grafos em grade com buracos (regiões retangulares cujos vértices foram eliminados).

O número de terminais varia entre 10 e 2344. O número de vértices e arestas varia de

poucas centenas até jV j = 36711 e jEj = 68117 (instância alut2625). A nomenclatura

adotada por Koch e Martin divide a classe VLSI em sete séries: alue, alut, dmxa, diw,

gap, msm e taq. Para todas as instâncias, o ótimo é conhecido [32, 44, 46, 58]. As quatro

maiores instâncias (alue7065, alue7080, alut2610 e alut2625) foram resolvidas pela primeira

2

Para a série i640, só foi possível utilizar 97 instâncias, uma vez que os arquivos da SteinLib represen-

tando as instâncias i640-022, i640-023 e i640-024 apresentavam erros.

Page 23: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 2. ASPECTOS GERAIS 11

vez usando o algoritmo descrito na Seção 7.2, apresentado em versão preliminar em [44].

A Figura 7.1 (página 123) mostra a instância alue7080 e sua solução ótima.

2.4.2.4 PUC

As instâncias da classe PUC foram criadas por Rosseti et al. em [51] com o objetivo

de testar os limites tanto de heurísticas quanto de algoritmos exatos para o problema de

Steiner em grafos. Apesar de terem dimensões semelhantes às das instâncias previamente

disponíveis na SteinLib, as instâncias da classe PUC são consideravelmente mais difíceis.

A classe se subdivide em três séries:

1. hc: Correspondem a hipercubos, com número de vértices variando entre 128 e 4096.

Em todos os casos, o número de arestas é (jV j log jV j)=2 e o de terminais, jV j=2.

No total, a série é composta por 14 instâncias.

2. cc: Instâncias derivadas do problema de cobertura de códigos, com número de

vértices variando entre 64 e 4096, jEj variando entre 192 e 24574 e jT j entre 8 e 473.

Esta série contém 26 instâncias.

3. bip: Instâncias sobre grafos bipartidos derivados de instâncias para o problema de

cobertura de conjuntos disponíveis na OR-Library [4]. O número de vértices nessa

série varia entre 550 e 3140; o de arestas, entre 5013 e 18073; e o de terminais, entre

50 e 300. A série contém 10 instâncias.

Cada uma das séries acima está dividida em duas subséries de igual tamanho: nas subséries

do tipo u (hc-u, cc-u, bip-u), os pesos das arestas são inteiros pequenos (1, 2, ou 3);

nas subséries do tipo p, os pesos são multiplicados por 100 e a eles é adicionada uma

perturbação aleatória. Instâncias do tipo p tendem a ser mais desa�adoras para heurísticas

primais.

2.4.2.5 Valores de Referência

Em muitas situações ao longo desta dissertação, faz-se necessário medir a qualidade das

soluções fornecidas pelos métodos estudados. Normalmente, basta utilizar como referência

a solução ótima de cada instância. Entretanto, para boa parte da classe PUC e da série

i640, as soluções ótimas não são conhecidas. Nesses casos, utilizam-se como referência as

melhores soluções primais encontradas na literatura até o momento. Para a classe PUC,

tais soluções são apresentadas em [51] e foram obtidos por longas execuções (chegando

a dias) da metaeurística HGP+PR, descrita no Capítulo 5. Para a série i640, foram

utilizados os limites superiores disponíveis na SteinLib em 1

o

de julho de 2001 (parte

dessas soluções também foi obtida por longas execuções do método HGP+PR).

Page 24: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 2. ASPECTOS GERAIS 12

2.5 Pré-processamento

Um importante elemento utilizado na prática para a resolução de instâncias do problema

de Steiner em grafos é o pré-processamento. Executados em tempo polinomial, algoritmos

de pré-processamento utilizam implicações lógicas para reduzir as dimensões do grafo

(jV j, jEj e jT j).

Há situações em que se pode concluir que existe pelo menos uma solução ótima que

não contém determinada aresta. Essa aresta pode ser removida do grafo. O exemplo mais

simples em que isso ocorre é o seguinte [14]:

Todo vértice não-terminal v de grau unitário em G, assim como a aresta que

nele incide, pode ser eliminado. (Motivo: a partir de qualquer solução válida

que contenha esse vértice, pode-se criar uma solução de valor menor, também

válida, se v e a aresta associada forem removidos.)

Em outros casos, ocorre o contrário: pode-se determinar que existe pelo menos uma

solução ótima que contém uma aresta. Essa aresta pode ser �contraída� sem prejuízo da

solução. Um exemplo simples [14]:

Se uma aresta e for a única incidente em um determinado terminal t e se

jT j � 2, então e obrigatoriamente estará em qualquer solução ótima. (Motivo:

o terminal deve fazer parte de toda solução, e a única maneira de conectá-lo

ao restante do grafo é através de e.)

Em situações extremas, o pré-processamento pode ser su�ciente para encontrar a

solução ótima para uma instância. Evidentemente, nem sempre é esse o caso, já que

os procedimentos de pré-processamento podem ser executados em tempo polinomial e o

problema de Steiner em grafos é NP-completo. No entanto, o pré-processamento pode

ser útil mesmo quando não encontra a solução ótima. A execução de um algoritmo exato

para o problema tende a ser mais rápida no grafo pré-processado que no grafo original,

devido à redução em suas dimensões. Da mesma forma, ele pode contribuir para a ace-

leração das heurísticas (e especialmente metaeurísticas) utilizadas. Outro efeito positivo

do pré-processamento é o fato de que ele pode melhorar a qualidade das soluções obtidas

pelos métodos aproximados. Não há, no entanto, garantia de que isso ocorra; em alguns

casos, as soluções encontradas podem piorar.

Um estudo mais aprofundado de métodos de pré-processamento não é o objetivo desta

tese. No entanto, para que fosse possível comparar as técnicas sugeridas aqui com outras

existentes, foram implementados os testes de redução apresentados em [58], que, além de

sugerir métodos de redução especialmente úteis para instâncias VLSI, descreve também

testes anteriormente descritos por outros autores [12, 14, 63]. Mais recentemente, em [46],

Polzin e Daneshmand sugerem novas implementações, signi�cativamente mais rápidas,

para alguns dos métodos introduzidos em [12, 14]. Tendo em vista que o estudo de

Page 25: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 2. ASPECTOS GERAIS 13

métodos de pré-processamento não é a prioridade desta dissertação, os métodos não foram

reimplementados para os estudos aqui apresentados.

Os métodos de pré-processamento foram aplicados sobre os grafos das classes OR-

Library e VLSI. O Apêndice A apresenta, para cada instância, o tempo necessário para

a execução dos testes e as dimensões da instância resultante. Para instâncias das classes

Incidência e PUC, não foi utilizada nenhuma técnica de pré-processamento, já que o efeito

dos métodos conhecidos sobre essas instâncias é desprezível.

Exceto no caso das heurísticas construtivas, todos os algoritmos (métodos de bus-

ca local, metaeurísticas, heurísticas duais e métodos exatos) discutidos nesta dissertação

foram executados sobre as instâncias pré-processadas (no caso das classes OR-Library

e VLSI). Os tempos de execução apresentados para os algoritmos não incluem o tem-

po de pré-processamento, a não ser que o contrário seja explicitamente indicado. Para

que seja recuperado o tempo total de execução, basta somar os tempos apresentados no

Apêndice A.

Page 26: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Capítulo 3

Heurísticas Construtivas

Heurísticas construtivas são métodos gulosos utilizados para a obtenção de soluções viáveis

para um problema. Além de úteis por si só, são elementos importantes de métodos de

busca local e metaeurísticas, conforme se verá nos Capítulos 4 e 5. Para o problema de

Steiner em grafos, a literatura apresenta um grande número de métodos construtivos (veja

[28, 61] para comparações entre as mais importantes).

Este capítulo se restringe a heurísticas baseadas em algoritmos para o problema da

árvore geradora de peso mínimo: DNH (descrita na Seção 3.1), Bor·vka (Seção 3.2), Prim

(3.3), Kruskal (3.4) e Multispan (3.5). Para cada método, são discutidas as possíveis

implementações e eventuais variantes. Na Seção 3.6, os métodos são comparados quanto

à qualidade das soluções fornecidas e aos tempos de execução.

Dois dos métodos aqui propostos não foram descritos anteriormente na literatura pes-

quisada: DNHz (uma variante de DNH apresentada na Seção 3.1.4) e (Bor·vka). Ambos

são extensões muito simples de heurísticas previamente existentes.

A principal contribuição deste capítulo, no entanto, está relacionada os métodos de

Prim e Kruskal, introduzidos em [54] e muito utilizadas na prática. São propostas novas

implementações que os tornam extremamente competitivos com heurísticas antes consi-

deradas muito mais rápidas. Utilizam-se técnicas elaboradas para evitar que se realizem

operações redundantes ao longo da execução dos algoritmos; na prática, isso resultou

em ganhos assintóticos nos tempos de execução dos algoritmos para todas as classes de

instâncias testadas. No pior caso, o tempo de execução das implementações propostas

é O(jT jjEj log jV j), mas essa complexidade só se �manifesta� em casos muito especiais.

Para as instâncias da literatura, os algoritmos comportam-se como se não dependessem

de jT j, tendo complexidade �aparente� O(jEj log jV j).

14

Page 27: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 15

3.1 Distance Network Heuristic (DNH)

A heurística DNH, como o próprio nome indica, baseia-se no grafo de distâncias, uma

importante ferramenta auxiliar também para outros algoritmos apresentados ao longo

desta dissertação. O grafo de distâncias, representado por D(G), tem os mesmos vértices

do grafo original, mas é completo. Cada aresta (u; v) em D(G) tem custo igual à distância

entre os vértices u e v em G; portanto, (u; v) é uma superaresta que representa o caminho

mínimo entre u e v no grafo original. Dado um subconjunto de vértices X � V , denota-se

por D

X

(G) o subgrafo de D(G) induzido por X.

A Distance Network Heuristic consiste simplesmente no cálculo da árvore geradora mí-

nima de D

T

(G) (o subgrafo induzido por T do grafo de distâncias de G) e na substituição

de cada superaresta pelas arestas correspondentes do grafo original (G). É importante

observar que não necessariamente as arestas do grafo de distâncias representam caminhos

disjuntos no grafo original; portanto, é comum que o custo da solução no grafo original

seja menor que o custo dessa árvore geradora mínima (maior não pode ser).

A implementação trivial desse método consiste em determinar explicitamente D

T

(G)

e calcular sua árvore geradora mínima. A determinação de D

T

(G) é feita executando-se

O(jT j) algoritmos de Dijkstra, o que pode ser feito em tempo O(jT j(jEj + jV j log jV j)).

Sua árvore geradora mínima de D

T

(G) pode ser calculada em tempo O(jT j

2

) utilizando-

se o algoritmo de Prim. A extração da árvore de Steiner correspondente (sobre o grafo

original) pode ser feita em tempo O(jEj). O tempo total de execução é dominado pela

construção do grafo: O(jT j(jEj+ jV j log jV j)). Essa implementação requer O(jV j+ jT j

2

)

posições de memória adicionais.

Em [39], Melhorn sugere uma implementação assintoticamente mais e�ciente para esse

algoritmo, com a vantagem adicional de utilizar apenas O(jV j) posições de memória adi-

cionais. Essa implementação baseia-se na construção do diagrama de Voronoi, apresentado

em detalhes a seguir.

3.1.1 Diagrama de Voronoi

O conceito de diagrama de Voronoi é freqüentemente usado na área de geometria com-

putacional [5, 47]. Considere um conjunto p

1

; p

2

; : : : ; p

n

de pontos no plano. O diagrama

de Voronoi é a subdivisão do plano em n regiões (vor(p

1

); vor(p

2

); : : : ; vor(p

n

)), sendo

vor(p

i

) a região de Voronoi associada a p

i

. Ela é de�nida como o conjunto de todos

os pontos p do plano mais próximos de p

i

que de qualquer outro ponto do conjunto

fp

1

; p

2

; : : : ; p

n

g (ou seja, d(p; p

i

) � d(p; p

j

), para todo 1 � j � n).

Esse conceito pode ser estendido de forma imediata para o problema de Steiner em

grafos. No caso geométrico, o diagrama de Voronoi associa qualquer ponto do plano a

um ponto do conjunto fp

1

; p

2

; : : : ; p

n

g. Para o problema de Steiner em grafos, o diagrama

associa qualquer vértice v 2 V (terminais e não-terminais) a um dos terminais t 2 T . Um

Page 28: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 16

vértice v pertence a vor(t

i

) se a distância de v a t

i

não for superior à distância de v a

qualquer outro terminal. Empates (casos em que um vértice é eqüidistante de diversos

terminais) são decididos de forma arbitrária.

1

O diagrama de Voronoi associado ao conjunto de terminais fornece as seguintes infor-

mações a respeito de cada vértice v:

� base(v): o terminal mais próximo de v;

� p(v; base(v)): o caminho mais curto de v à base;

� d(v): distância de v à sua base, ou seja, o comprimento de p(v; base(v)).

Em especial, para todo terminal t

i

vale que base(t

i

) = t

i

, d(t

i

) = 0. O caminho mais curto

de um terminal à sua base (ele próprio) não tem aresta alguma.

O diagrama de Voronoi é construído por uma versão ligeiramente modi�cada do al-

goritmo de Dijkstra com múltiplas fontes (todos os terminais). Ao longo da execução do

algoritmo, associam-se a cada vértice v três valores: base(v), d(v) e pred(v) (o predecessor

de v no caminho entre ele e sua base). Como a atualização desses valores não altera a

complexidade do algoritmo de Dijkstra, a construção do diagrama de Voronoi pode ser

feita em tempo O(jEj+ jV j log jV j).

Uma vez construído o diagrama de Voronoi, é possível determinar em tempo cons-

tante os valores de base(v) e d(v) para qualquer vértice v. O caminho mínimo entre v

e base(v) (que tem comprimento d(v), evidentemente) pode ser recuperado em tempo

proporcional ao número de arestas no caminho; basta para isso percorrer a lista formada

pelos apontadores pred que se inicia em pred(v).

A utilidade do diagrama de Voronoi para o problema de Steiner em grafos está no

fato de fornecer de forma simples importantes informações sobre a distância entre os

terminais. Muito importante para isso são as arestas de fronteira: arestas que ligam

duas diferentes regiões de Voronoi. Formalmente, uma aresta (u; v) é considerada de

fronteira se base(u) 6= base(v). Associa-se a toda aresta de fronteira (u; v) um caminho

entre dois terminais, base(u) e base(v). O comprimento desse caminho é justamente

d(u) + c(u; v) + d(v).

A seguir, apresenta-se uma propriedade muito simples, mas essencial para uma imple-

mentação e�ciente de vários dos algoritmos aqui propostos (Bor·vka, Prim e Kruskal).

Teorema 1 Dado um terminal t

a

, seja t

b

o terminal tal que d(t

a

; t

b

) < d(t

a

; t

c

) para todo

terminal t

c

. Então existe uma aresta de fronteira no diagrama de Voronoi que representa

o caminho mínimo entre t

a

e t

b

.

1

No caso geométrico, nas situações de empate a convenção adotada é considerar que o ponto pertence

a todas as regiões envolvidas; isso poderia também ser feito no caso do problema de Steiner em grafos,

mas é algoritmicamente mais interessante efetuar o desempate.

Page 29: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 17

Prova Seja p(t

a

; t

b

) o caminho mínimo entre os terminais. Seja u um vértice desse

caminho tal que ele e todos os seus antecessores pertecem a vor(t

a

) e seu sucessor (v) não

pertence a vor(t

a

). Existe um tal vértice, já que t

a

2 vor(t

a

) e t

b

62 vor(t

a

). Por de�nição,

a aresta (u; v) é uma aresta de fronteira. Resta provar que v 2 vor(t

b

). Suponha que isso

não seja verdade, ou seja, que exista um terminal t

c

(c 6= a) cuja distância a v (d

c

(v))

seja menor que a distância entre v e t

b

(d

b

(v)). Então existe um caminho entre t

a

e t

c

de

comprimento d

a

(u)+ c(u; v)+ d

c

(v), menor que o comprimento do caminho mínimo entre

t

a

e t

b

(d

a

(u) + c(u; v) + d

b

(v)), o que contradiz o fato de t

b

ser o terminal mais próximo

de t

a

. Portanto, conclui-se que (u; v) é uma aresta de fronteira que representa o caminho

mínimo entre t

a

e t

b

. 2

Por simplicidade, o teorema acima aplica-se ao caso em que o terminal mais próximo

de t

a

é único. Nos casos em que há empate, pode-se garantir que haverá uma aresta de

fronteira ligando t

a

a pelo menos um dos terminais mais próximos.

3.1.2 Implementação da Heurística DNH (DNH-Prim)

Com o auxílio do Diagrama de Voronoi, a árvore geradora mínima de D

T

(G) pode ser cal-

culada sem que seja necessário criar explicitamente o grafo D

T

(G). Para isso, é necessário

utilizar uma propriedade ainda mais forte que a apresentada no Teorema 1: existe uma

árvore geradora mínima de D

T

(G) formada apenas por caminhos associados a arestas de

fronteira do diagrama de Voronoi de G. A prova desse fato, apresentada em [39], é omitida

aqui.

Assim sendo, a solução da heurística DNH pode ser obtida calculando-se a árvore

geradora mínima do grafo G

0

, que tem exatamente as mesmas arestas de G, mas com

pesos alterados a partir das informações fornecidas pelo diagrama de Voronoi. Dada uma

aresta (u; v) de G, determina-se seu custo c

0

(u; v) em G

0

da seguinte forma:

� se base(u) = base(v), então c

0

(u; v) = 0;

� se base(u) 6= base(v), então c

0

(u; v) = d(u) + c(u; v) + d(v).

Dessa forma as arestas de fronteira concentram os pesos dos caminhos que representam.

Como todas as demais arestas têm peso zero, farão parte da árvore geradora de G

0

exa-

tamente jT j � 1 arestas de fronteira, necessárias para conectar as diferentes regiões de

Voronoi. Para obter a árvore de Steiner correspondente, basta fazer a expansão das

arestas de fronteira, extraindo delas os caminhos correspondentes. Se uma mesma ares-

ta do grafo G estiver contida em mais de uma aresta de fronteira selecionada, cópias

adicionais devem ser ignoradas.

Conforme já mencionado, o custo da primeira fase da heurística � a construção do

algoritmo de Voronoi � pode ser feita em tempo O(jEj + jV j log jV j). A segunda fase

� o cálculo da árvore geradora mínima � também pode ser implementada com essa

Page 30: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 18

complexidade se for utilizado o algoritmo de Prim. No restante desta dissertação, será

utilizada a denominação �DNH-Prim� nas referências a essa implementação.

3.1.3 Implementação Alternativa (DNH-Bor·vka)

A segunda fase da implementação DNH-Prim consiste no cálculo da árvore geradora de

peso mínimo do grafo com pesos modi�cados, da qual se extrai posteriormente a árvore

de Steiner. Considera-se aqui uma implementação alternativa, DNH-Bor·vka, em que na

segunda fase a árvore de Steiner é calculada diretamente.

Para isso, utiliza-se uma versão ligeiramente modi�cada do algoritmo de Bor·vka para

o problema da árvore geradora de peso mínimo (apresentado na Seção 2.3.1). Em sua

versão original, em cada iteração desse algoritmo cada vértice é ligado ao vértice mais

próximo. Na versão modi�cada, em cada etapa liga-se cada terminal ao terminal mais

próximo.

Para determinar o vizinho mais próximo de cada terminal, basta percorrer a lista de

arestas de fronteira no diagrama de Voronoi. Deve-se levar em conta não o custo original

da aresta, mas o custo modi�cado: conforme já mencionado, cada aresta (u; v) representa

um caminho de custo d(u) + c(u; v) + d(v) entre os terminais base(u) e base(v). Ao �nal

da primeira etapa, liga-se cada terminal ao terminal mais próximo. Na segunda etapa,

percorre-se novamente a lista de arestas de fronteira, tomando-se o cuidado de considerar

apenas as arestas (u; v) tais que base(u) e base(v) pertençam a diferentes componentes

conexas. Sucedem-se as etapas até que todos os terminais estejam conectados.

Como no algoritmo de Bor·vka original, cada iteração pode ser executada em tempo

O(jEj) e reduz o número de componentes pelo menos à metade. Diferentemente do al-

goritmo original, contudo, o número inicial de componentes é jT j, não jV j. Assim sendo,

são executadas no máximo O(log jT j) iterações, o que faz com que a segunda fase da

heurística DNH-Bor·vka tenha complexidade O(jEj log jT j). A complexidade de toda a

heurística, portanto, é O(jEj log jT j+ jV j log jV j). Se o número de terminais for relativa-

mente pequeno, essa implementação tende a ser mais rápida que DNH-Prim.

3.1.4 Variante DNHz

É possível fazer uma pequena alteração na implementação DNH-Bor·vka que contribui

para melhorar a qualidade das soluções obtidas sem alterar o tempo de execução do

algoritmo.

A alteração ocorre na segunda fase da heurística, em que o algoritmo de Bor·vka é

utilizado para encontrar a árvore de Steiner com base no diagrama de Voronoi previamente

construído. Após a primeira iteração do algoritmo de Bor·vka, vários pares de terminais

são unidos pelos caminhos mais curtos entre eles. Cada um desses caminhos pode ter

vértices intermediários, que passam a fazer parte da solução.

Page 31: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 19

Na implementação DNH-Bor·vka, esse fato não é levado em conta. Depois da adição

de um vértice não-terminal v a solução, iterações posteriores continuam utilizando o valor

original de d(v) (a distância de v ao terminal mais próximo), quando poderiam utilizar

d(v) = 0. Fazendo-se d(v) 0 após a adição de cada novo não-terminal v à solução,

algumas arestas de fronteira têm seus pesos reduzidos e podem passar a ser escolhidas em

virtude disso. Essa pequena alteração permite que se encontrem �atalhos� entre diferentes

componentes em iterações posteriores.

No restante desta dissertação, será utilizada a denominação DNHz para essa variante,

sendo o �z� referente à atribuição do valor zero. A complexidade de pior caso dessa

variante é idêntica à da implementação DNH-Bor·vka. De fato, conforme se verá na

Seção 3.6, ambos os algoritmos têm tempos de execução praticamente idênticos, mas o

método DNHz produz soluções de qualidade superior.

3.2 Bor·vka

Esta seção apresenta a heurística de Bor·vka para o problema de Steiner em grafos,

baseada no algoritmo homônimo para o problema da árvore geradora de peso mínimo

(MST) descrito na Seção 2.3.1.

O algoritmo original para o MST se inicia com jV j componentes conexas, cada uma

formada por um único vértice. Em cada iteração, cada componente é ligada à componente

que lhe é mais próxima, formando uma nova componente. O algoritmo prossegue até que

reste uma única componente conexa.

A heurística para o problema de Steiner em grafos é similar. Inicia-se o algoritmo com

jT j componentes conexas, todas compostas por um único terminal. Em cada iteração, toda

componente conexa é ligada à componente que lhe é mais próxima. Passam a fazer parte

da nova componente conexa não só os vértices das componentes originais, mas também os

do caminho entre elas. (Os novos vértices adicionados podem ser utilizados como bases

para a ligação de diferentes componentes em iterações posteriores.) O algoritmo termina

assim que todos os terminais estiverem conectados.

Tanto no caso do algoritmo para o problema da árvore geradora mínima quanto da

heurística para o problema de Steiner em grafos, em cada iteração o número de com-

ponentes reduz-se pelo menos à metade. Isso signi�ca que serão necessárias no máximo

log jV j iterações no algoritmo para o cálculo da árvore geradora de custo mínimo e log jT j

na heurística para o problema de Steiner em grafos (potencialmente menor, portanto).

Resta determinar o tempo necessário para executar cada iteração da heurística. Reca-

pitulando, a operação básica a ser feita é identi�car, para cada componente conexa, qual a

sua componente conexa mais próxima. Conforme mostra o Teorema 1, é justamente essa

a principal utilidade do diagrama de Voronoi. Uma vez construído o diagrama de Voronoi,

basta percorrer as arestas de fronteira para determinar os pares de componentes próximas,

de forma análoga ao que se fez nas heurísticas DNH-Bor·vka e DNHz. Naqueles casos,

Page 32: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 20

contudo, basta calcular o diagrama de Voronoi uma única vez, no início do algoritmo. Na

heurística de Bor·vka, o diagrama de Voronoi deve ser recalculado após cada iteração,

pois os novos não-terminais adicionados à solução também passam a ser bases de regiões

de Voronoi.

A complexidade de cada iteração da heurística de Bor·vka é dominada justamente

pelo cálculo do diagrama de Voronoi: O(jEj+ jV j log jV j). Como há no máximo log(jT j)

iterações, a complexidade da heurística como um todo é O((log jT j)(jEj+ jV j log jV j)).

Na prática, o número de iterações é freqüentemente menor que log jT j. Além disso, o

algoritmo pode ser acelerado se consideramos que não é necessário recalcular o diagrama

de Voronoi completo em cada iteração. O diagrama de Voronoi obtido numa iteração

pode ser simplesmente atualizado na iteração seguinte. A construção completa exige a

execução de um algoritmo de Dijkstra modi�cado tendo como origens todos os vértices

que fazem parte de alguma componente já coberta pela árvore de Steiner. Para a atua-

lização, basta preservar as informações de proximidade originais e usar como origem os

vértices adicionados à árvore na iteração anterior (i.e., os vértices intermediários nos ca-

minhos criados). Isso é possível porque a distância de cada vértice à sua base só pode

diminuir (ou permanecer inalterada) ao longo da execução do algoritmo, já que bases

nunca são removidas, apenas adicionadas. Na prática, a diferença entre a construção e a

atualização do diagrama de Voronoi é expressiva; as operações de atualização tendem a

ser extremamente �locais�, ou seja, normalmente exigem que apenas uma pequena parte

dos vértices e arestas do grafo seja analisada.

3.3 Prim

Em [54], Takahashi e Matsuyama analisam uma heurística baseada em caminhos míni-

mos, comumente conhecida como shortest path heuristic (SPH). Ela utiliza um princípio

semelhante ao algoritmo de Prim [48] para o problema da árvore geradora mínima em

grafos.

Inicia-se o algoritmo SPH com uma solução parcial S = frg, sendo r, a raiz, um vértice

qualquer (nas implementações realizadas, sempre um terminal). O algoritmo aumenta

progressivamente esse conjunto, preservando sempre a invariante de que o subgrafo de

G induzido por S seja conexo. Para isso, em cada iteração o algoritmo determina qual

terminal t

i

2 T n S tem distância mínima a S. Ao conjunto S são adicionados t

i

e os

demais vértices no caminho entre t

i

e S. Ao �nal de jT j iterações (ou jT j � 1, se r for um

terminal), o algoritmo terá encontrado o conjunto de vértices (terminais e não-terminais)

que devem compor da árvore de Steiner.

Page 33: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 21

3.3.1 Implementação em Duas Fases (Prim-T)

A implementação da heurística SPH na literatura (veja [46] e [28], por exemplo) é usual-

mente feita em duas fases.

Na primeira fase, determina-se o caminho mínimo de cada terminal a cada um dos

demais vértices. Isso pode ser feito, por exemplo, executando-se jT j algorimos de Dijkstra,

um a partir de cada terminal, o que requer O(jT j(jEj + jV j log jV j)) operações no pior

caso. Os dados obtidos na primeira fase são armazenados em uma tabela com jT jjV j

posições, da qual se podem extrair os caminhos e as distâncias correspondentes.

A segunda fase utiliza os dados obtidos na primeira fase para construir a solução. A

estrutura de dados básica utilizada nessa fase é um vetor (closest) de jT j posições, uma

associada a cada terminal. Em qualquer ponto da execução, closest [t] contém o vértice de

S (a solução parcial) cuja distância a t é mínima. Conforme já mencionado, o conjunto

S é inicializado com um vértice r qualquer, a raiz. Todas as posições do vetor closest são

inicializadas com r (o único vértice na solução). Em cada iteração do algoritmo, um novo

terminal é adicionado à solução, o que é feito em três passos:

1. Determinação do terminal t mais próximo de S. Para isso, basta percorrer o vetor

closest.

2. Atualização de S. Adiciona-se à solução parcial S tanto o vértice t quanto os vértices

do caminho ligando t à solução parcial anterior. O caminho pode ser obtido a partir

dos dados obtidos na primeira fase do algoritmo.

3. Atualização do vetor closest. Para todo terminal t

i

ainda não presente em S, veri�ca-

se (consultando-se a tabela construída na primeira fase) se a distância de t

i

a um

dos novos vértices adicionados a S no passo 2 é menor que closest [t

i

]. Se for, o valor

de closest [t

i

] é atualizado.

São ao todo O(jT j) iterações (o número exato depende do fato de r ser terminal ou

não). O passo 1 acima pode ser executado em tempo O(jT j) por iteração. Considerando-se

todo o algoritmo, o passo 2 requer O(jV j) operações, visto que cada vértice pode entrar em

S no máximo uma vez. O passo 3 é executado em tempo total O(jT jjV j), pois para cada

vértice adicionado a S é necessário fazer O(jT j) comparações (uma para cada terminal

ainda não inserido em S). Assim sendo, a segunda fase da heurística requer O(jT jjV j)

operações, o que signi�ca que a complexidade do algoritmo como um todo é dominada

pela primeira fase: O(jT j(jEj+ jV j log jV j).

Aceleração Em [46], Polzin e Daneshmand sugerem algumas acelerações para a im-

plementação acima. Na primeira fase do algoritmo, é possível limitar o alcance dos jT j

algoritmos de Dijkstra utilizados para construir a tabela de distâncias. A execução a partir

de um terminal t não precisa alcançar todos os demais vértices. Ela pode ser interrompida

assim que todos os vértices dos seguintes grupos forem alcançados:

Page 34: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 22

1. vértices da região de Voronoi de t;

2. todos os terminais em regiões de Voronoi vizinhas de t.

Alguns valores da tabela de distâncias permanecerão não preenchidos se esses critérios

de parada forem utilizados. Em [46], prova-se que esses valores não são necessários para

a segunda fase do algoritmo. Essas condições não garantem ganhos assintóticos no pior

caso, mas podem levar a menores tempos de execução na prática. Em geral, os efeitos

tendem a ser mais relevantes para instâncias pouco densas. Para instâncias mais densas,

o número de terminais em regiões vizinhas a t é maior.

Polzin e Daneshmand propõem também um método para acelerar a segunda fase do

algoritmo. Como o tempo de execução é claramente dominado pela primeira fase do

algoritmo, essa aceleração não foi implementada.

Ao longo desta dissertação, será utilizado o nome �Prim-T� em referências a essa

implementação da heurística de Prim (incluindo a aceleração). A letra �T� lembra o fato

de que o algoritmo baseia-se na construção de uma tabela de distâncias.

3.3.2 Implementação Direta (Prim-D)

Apresenta-se nesta seção Prim-D, uma implementação direta (em uma única fase) da

heurística de Prim.

O algoritmo se inicia pela criação da solução parcial inicial S = frg. Em cada iteração,

executa-se um algoritmo de Dijkstra com origem em todos os vértices que pertencem a

S. As execuções param assim que um terminal t que não pertence a S é alcançado.

Adicionam-se então a S o terminal t e os vértices do caminho que leva a ele. Após

jT j � 1 ou jT j iterações (dependendo do fato de r ser ou não raiz), o algoritmo estará

concluído. A complexidade dessa implementação é a de Prim-T, descrita na seção anterior:

O(jT j(jEj+ jV j log jV j)).

Por estar dividida em duas fases, a implementação Prim-T pode ser mais vantajosa

quando se deseja efetuar mais de uma execução do algoritmo. Depois de executada uma

única vez a primeira fase, podem ser efetuadas tantas execuções da segunda fase (com

diferentes raízes) quantas forem necessárias. Cada uma delas pode ser executada em

tempo O(jT jjV j). Por outro lado, a implementação direta requer apenas O(jV j) posições

de memória adicionais, enquanto a implementação em duas fases requer a construção de

uma tabela com O(jT jjV j) elementos. Para muitas instâncias, a execução do algoritmo

pode se tornar inviável (entre as instâncias apresentadas na Seção 2.4.2, há algumas com

dezenas de milhares de vértices e milhares de terminais).

Tanto a implementação baseada na construção da tabela de distâncias quanto a im-

plementação direta requerem O(jT j) execuções do algoritmo de Dijkstra. Na versão mais

simples da implementação em duas fases, as execuções são completas. Cada algoritmo

de Dijkstra é executado até que todos os vértices do grafo sejam alcançados. Com a

Page 35: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 23

aceleração proposta por Polzin e Vahdati [46], o �alcance� de cada execução é limitado

à região de Voronoi a que pertence a origem e aos terminais vizinhos. No caso da im-

plementação direta, cada execução do algoritmo de Dijkstra é ainda mais reduzida, pois

pode ser interrompida assim que um terminal que não está na solução for alcançado.

Re�namento O principal problema dessa implementação é o fato de que, à medida

que avança o algoritmo, o número de origens (do algoritmo de Dijkstra) aumenta, o que

não ocorre na implementação em duas fases. No entanto, é possível adotar medidas

para evitar, sempre que possível, que esse problema ocorra. Apesar de as medidas não

alterarem a complexidade de pior caso do algoritmo, na prática se observam acelerações

consideráveis.

As diversas aplicações do algoritmo de Dijkstra são muito semelhantes ao longo da

heurística. A única diferença entre uma iteração e a seguinte está no fato de que alguns

nós (os do novo caminho adicionado) passam a ter distância zero à solução parcial S. Os

nós que já tinham distância zero não são afetados e os pesos das arestas permanecem

inalterados. Como resultado, a distância de d

i

(v) de um vértice v à árvore existente no

inicio da iteração i jamais será maior que d

i+1

(v), a distância de v à árvore no início da

iteração i + 1. Isso signi�ca que os valores presentes no heap ao �nal da execução do

algoritmo de Dijkstra na iteração i representam limites superiores para as distâncias dos

nós à árvore na iteração i+ 1.

Conseqüentemente, entre uma iteração e outra não é necessário reinicializar o heap;

basta inserir (com distância zero) os vértices do novo caminho adicionado. Como os novos

vértices serão os primeiros a ser retirados, a execução normal do algoritmo de Dijkstra

fará com que os valores das distâncias associadas demais vértices presentes no heap (que,

conforme já discutido, representam limites superiores) sejam devidamente atualizadas.

A distância de um vértice v diminuirá se ele estiver mais próximo de um dos vértices

do caminho adicionado do que do restante da árvore (pode-se dizer que um �atalho� foi

encontrado). Se o novo caminho em nada contribuir para que o vértice seja alcançado a

partir da árvore, sua distância permanecerá inalterada (e correta).

Além da atualização das distâncias dos vértices já presentes no heap, outros vértices

poderão ser adicionados antes que outro terminal seja encontrado. Se forem vértices que

nunca passaram pelo heap, a inserção é inevitável. No entanto, se um vértice v já tiver

passado pelo heap em alguma iteração anterior, há casos em que a inserção é desnecessária.

Considere que, ao ser retirado do heap na iteração i do algoritmo, a distância de v à

árvore seja d

i

(v). O processamento de v consiste em percorrer sua vizinhança e atualizar

o heap se necessário. Mais especi�camente, seja w um vizinho de v ainda não inserido

na árvore e c(v; w) o peso da aresta que liga v a w. O heap só deve ser atualizado se

d

i

(v) + c(v; w) for menor que a menor distância calculada em iterações anteriores entre

w e a árvore. Considere agora o que ocorria se v fosse inserido novamente no heap numa

iteração posterior j com distância d

j

(v) � d

i

(v). Quando v for novamente retirado,

percorrer sua vizinhança será inútil: como os pesos das arestas não mudam, a distância

Page 36: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 24

obtida para cada um de seus vizinhos jamais será menor que a calculada na iteração

i. Conclusão: não é necessário inserir no heap um vértice cuja distância à árvore seja

superior àquela que possuía quando retirado do heap em alguma iteração anterior.

Esse procedimento evita que uma série de cálculos idênticos seja refeita em diferentes

iterações. Apesar de não alterar a complexidade assintótica do algoritmo no pior caso, em

termos práticos essas medidas normalmente levam a uma signi�cativa melhora de desem-

penho. Além disso, mesmo nas instâncias em que seu efeito é pequeno, a implementação

�re�nada� nunca precisará percorrer a vizinhança de mais vértices que a implementação

trivial. Depois de passar a fazer parte da solução, um vértice terá sua vizinhança percor-

rida exatamente uma vez na versão �re�nada�. A implementação trivial, por outro lado,

requer que ela seja inspecionada em todas as iterações até o �m do algoritmo.

Na Seção 3.6, foi testada apenas a versão �re�nada� da implementação Prim-D, visto

que ela é claramente superior à versão �trivial�.

3.4 Kruskal

Considera-se agora uma heurística construtiva para o problema de Steiner em grafos

baseada no algoritmo de Kruskal para árvores geradoras mínimas (MST). Conforme men-

cionado na Seção 2.3.1, o algoritmo de Kruskal para o MST consiste em (1) ordenar as

arestas em ordem não-decrescente de peso e (2) inseri-las nessa ordem até que se forme

uma árvore geradora. Arestas que formariam ciclos são descartadas.

Em sua versão heurística adaptada para o problema de Steiner, descrita por Takahashi

e Matsuyama [54], são adicionados caminhos no lugar das arestas. O algoritmo se inicia

com jT j componentes distintas, cada uma correspondendo a um dos terminais. A distância

entre duas componentes é de�nida como o comprimento do menor caminho entre dois

de seus vértices. Em cada iteração do algoritmo, as duas componentes mais próximas

são unidas, formando uma nova componente conexa, à qual se incorporam também os

vértices no caminho mínimo que liga as duas componentes. Como existem inicialmente

jT j componentes disjuntas, serão necessárias exatamente jT j � 1 iterações para que todos

os terminais estejam conectados e se crie uma árvore de Steiner.

3.4.1 Implementação Básica (Kruskal-B)

A operação básica realizada em cada iteração do algoritmo é determinar qual o par de

componentes mais próximas entre si. Na primeira iteração, executa-se um algoritmo de

Dijkstra a partir de cada terminal. Feito isso, pode-se determinar o par mais próximo

de componentes (terminais) em tempo O(jT j). Nas iterações seguintes, não é necessário

executar novamente o algoritmo de Dijkstra jT j vezes. Suponha que duas componentes,

a e b, sejam unidas na iteração i. No início dessa iteração era conhecida, para cada

componente, sua �vizinha� mais próxima. Depois da união de a e b, só poderá haver

Page 37: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 25

mudanças no conjunto de distâncias se a nova componente (formada por a e b) tornar-

se a mais próxima de alguma das demais componentes. Assim sendo, basta executar o

algoritmo de Dijkstra a partir dos vértices da componente ab, sem interrompê-lo antes

que todas as demais componentes sejam alcançadas. Dessa forma, é possível atualizar

tanto a componente ab quanto as demais. A primeira iteração do algoritmo requer O(jT j)

execuções do algortimo de Dijkstra, cada uma realizada em tempo O(jEj + jV j log jV j).

Cada uma das O(jT j) iterações posteriores requer apenas uma execução do algoritmo de

Dijkstra. A complexidade total do algoritmo, portanto, é O(jT j(jEj+ jV j log jV j)).

Essa implementação básica da heurística de Kruskal (que recebe a denominação de

Kruskal-B) tem uma de�ciência básica: ela exige que se execute um algoritmo de Dijkstra

completo em cada iteração, o que pode ser muito custoso. Nas subseções seguintes, serão

sugeridas implementações alternativas que aproveitam melhor as informações obtidas em

iterações passadas para acelerar iterações futuras.

3.4.2 Implementação com Heap de Arestas (Kruskal-E)

A implementação do algoritmo de Kruskal para o problema da árvore geradora mínima

(MST) é extremamente simples. Basta ordenar previamente todas as arestas e inseri-las

em ordem, evitando-se a inserção das arestas que formam ciclos. É possível implementar

a heurística de Kruskal para o problema de Steiner em grafos (SPG) seguindo-se o mes-

mo princípio, mas é necessário lidar com algumas di�culdades inexistentes no algoritmo

original.

Em primeiro lugar, é importante lembrar que, enquanto o algoritmo para o MST lida

com arestas, a heurística para o SPG lida com caminhos. Para contornar esse problema, o

primeiro passo da heurística é construir o diagrama de Voronoi e determinar suas arestas

de fronteira (veja Seção 3.1.1). A cada aresta (u; v) ligando diferentes regiões de Voronoi

associa-se o custo c

0

(u; v) = d(u) + c(u; v) + d(v), sendo d(u) e d(v) as distâncias de u

e v às respectivas bases no diagrama de Voronoi. Dessa forma, reduz-se cada caminho

relevante a uma única aresta que o representa.

No algoritmo para o MST, bastaria então ordenar as arestas assim obtidas e percorrer

a lista em ordem, adicionando-se as arestas que determinam caminhos que não formam

ciclos. Na heurística para o SPG, no entanto, o conjunto de arestas (caminhos) a ser

considerado é dinâmico, varia de uma iteração para outra. Após a adição de um cami-

nho à solução, cria-se uma nova componente, constituída não só pelos vértices das duas

componentes originais, mas também pelos vértices intermediários do caminho adicionado.

Caminhos que partem desses vértices devem ser considerados em iterações posteriores do

algoritmo, já que podem ser menores que outros anteriormente encontrados. Assim sendo,

de forma análoga ao que ocorre na heurística de Bor·vka (Seção 3.2, deve-se atualizar o di-

agrama de Voronoi depois de cada iteração, considerando os novos vértices intermediários

como possíveis bases. Com isso, arestas que estavam na fronteira entre duas regiões de

Voronoi podem deixar de estar e vice-versa. Além disso, uma aresta pode passar a repre-

Page 38: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 26

sentar um caminho de tamanho diferente (obrigatoriamente menor). Isso explica por que

a lista ordenada de arestas muda de uma iteração para outra.

É importante observar, contudo, que nem todas as arestas (caminhos) sofrem altera-

ções. São modi�cados apenas os caminhos associados a arestas que tiveram pelo menos

uma de suas extremidades atualizadas pelo diagrama de Voronoi: mudará o caminho asso-

ciado à aresta (u; v) se e somente se as distâncias de u ou v às respectivas bases mudarem.

Durante a atualização do diagrama de Voronoi é interessante criar uma lista dos vértices

modi�cados, já que apenas as arestas incidentes nesses vértices precisam ser veri�cadas.

No pior caso, o número de arestas analisadas pode ser comparável ao total de arestas, mas

na prática as alterações normalmente são �locais�, envolvendo poucos vértices e arestas.

Para que essa localidade se traduza em uma aceleração expressiva da heurística para o

SPG, ao invés de se fazer uma lista de arestas (como se faz no algoritmo para o problema

da árvore geradora mínima), é conveniente manter um heap em que cada aresta tem

associada a si o custo do caminho que representa (c

0

(u; v) = d(u) + c(u; v) + d(v)). Com

isso, é possível atualizar o conjunto de arestas sem que seja necessário percorrê-lo por

completo.

Com essa estrutura de dados, cada iteração do algoritmo resume-se aos seguintes

passos:

1. Escolha do caminho. Retira-se do heap a aresta (u; v) que representa o menor

caminho do grafo. No caso de base(u) e base(v) pertencerem à mesma componente

conexa, descarta-se a aresta. Repete-se o procedimento até que a aresta retirada de

fato represente um caminho entre duas componentes conexas.

2. Adição do caminho. Cria-se uma nova componente formada pela união das que

continham base(u) e base(v) e pelos vértices intermediários no caminho entre elas.

3. Atualização do Diagrama de Voronoi. Realiza-se um algoritmo de Dijkstra modi�-

cado tendo como origem os vértices intermediários do novo caminho adicionado.

4. Atualização do heap de arestas. Para todo vértice u modi�cado durante a atualiza-

ção do diagrama de Voronoi (ou seja, vértices que tiveram o valor d(u) reduzido),

percorre-se a sua vizinhança. Dada uma aresta (u; v) dessa vizinhança, são dois os

casos possíveis:

a. base(v) pertence a uma componente conexa diferente de base(u): nesse caso,

atualiza-se o custo c

0

(u; v) associado a (u; v) no heap (agora menor, pois d(u)

foi reduzido); se (u; v) não estiver no heap, deve ser inserido.

b. base(v) pertence à mesma componente conexa de base(u): nesse caso, nada

deve ser feito, mesmo que a aresta esteja no heap. O fato de que ela não mais

representa uma aresta de fronteira será tratado no passo 1 de iterações futuras.

Page 39: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 27

Toda aresta entra no heap como aresta de fronteira. Ao longo da execução do algorit-

mo, contudo, ela pode deixar de sê-lo. Basta que as bases de suas extremidades passem

a pertencer à mesma componente conexa. Depois disso, é possível que a aresta volte a

ser de fronteira (se uma de suas bases mudar). A estrutura do algoritmo garante que,

se a aresta for de fronteira, o valor associado a ela no heap estará correto. Se não for

de fronteira, nada se garante sobre ela, que pode estar no heap ou não. Se estiver, duas

situações podem ocorrer:

a. ela se tornará a aresta mais prioritária do heap em alguma iteração e será retirada

no passo 1; ou

b. ela se tornará novamente uma aresta de fronteira em alguma iteração futura do algo-

ritmo; como isso só pode resultar da expansão de uma região de Voronoi (passo 3),

ela obrigatoriamente terá o valor associado a si reduzido. A operação decreaseKey

executada no passo 4 do algoritmo a torna novamente �ativa�.

Complexidade O algoritmo é executado em O(jT j) iterações. Em cada uma delas, é

necessário atualizar o diagrama de Voronoi (passo 3), o que requer O(jEj + jV j log jV j)

operações. Os passos 1 e 4, que envolvem a manipulação do heap, podem ser realizadas em

tempo O(jEj log jEj) por iteração no pior caso. O passo 2 é executado em tempo O(jV j)

considerando-se toda a execução do algoritmo. A complexidade dessa implementação é,

portanto, O(jT jjEj log jEj).

Evidentemente, seria possível fazer com que a expressão da complexidade do algoritmo

fosse dominada pelas atualizações do diagrama de Voronoi: O(jT j(jEj + jV j log jV j)).

Bastaria substituir o heap de arestas por uma lista. Assim, o passo 1 passaria a ser

executado em tempo �(jEj) e o passo 4 simplesmente desapareceria. O problema dessa

implementação é dar pouca margem a acelerações expressivas na prática: seu melhor caso é

(jT jjEj). Quando se utiliza o heap, pode-se explorar melhor o fato de que as atualizações

do diagrama de Voronoi (e por conseguinte do próprio heap) são muito limitadas.

Por isso, preferiu-se a implementação que utiliza o heap de arestas. Deu-se o nome de

�Kruskal-E� a essa implementação (�E� é uma referência ao conjunto de arestas).

3.4.3 Implementação com Heap de Vértices (Kruskal-V)

Esta seção propõe uma implementação alternativa para a heurística de Kruskal que tem

desempenho comparável ao de Kruskal-E, mas utiliza um heap de vértices. Devido a

essa característica, essa implementação é denominada �Kruskal-V�. Como na implemen-

tação anterior, Kruskal-V baseia-se na construção e posterior atualização do diagrama

de Voronoi. A diferença principal é a maneira de se encontrar o par mais próximo de

componentes em cada iteração.

Page 40: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 28

Uma vez construído o diagrama de Voronoi, associa-se a cada vértice u uma única

aresta e(u), que representa o menor caminho que sai de base(u), tem u como último

vértice dentro da região de Voronoi de u e chega a alguma outra componente. Determinar

essa aresta é simples: basta percorrer a vizinhança de u e, para cada aresta de fronteira

(u; v), calcular o custo c

0

(u; v) = d(u) + c(u; v) + d(v) do caminho que ela representa.

A aresta escolhida é aquela para a qual esse valor é mínimo. Se não houver aresta de

fronteira incidente em u, o valor de e(u) é inde�nido.

Entre as O(jV j) arestas

2

escolhidas dessa forma (uma para cada vértice), está a aresta

que representa o menor caminho entre diferentes componentes do grafo. Assim, é su�ciente

usar um heap com O(jV j) elementos (vértices) para determinar o par mais próximo de

componentes em cada iteração do algoritmo. Basta associar a cada vértice v o custo do

caminho representado pela aresta e(v).

Depois de construído o heap, são executadas as jT j � 1 iterações do algoritmo, cada

uma constituída pelos seguintes passos:

1. Determinação do par mais próximo de componentes. Retira-se do heap o vértice

u mais prioritário. Se e(u) não mais for uma aresta de fronteira (ela pode deixar

de ser ao longo da execução do algoritmo), deve-se percorrer a vizinhança de u,

determinar o valor de e(u) e, se ele for de�nido, reinserir o vértice no heap. A

operação é repetida até que o vértice retirado esteja associado a uma aresta de

fronteira, que representará o caminho mínimo entre duas componentes do grafo.

2. Adição do caminho. Sendo (u; v) a aresta prioritária, adicionam-se à solução todos os

vértices do caminho entre base(u) e base(v). Esses novos vértices e as componentes

originais são unidos em uma só componente.

3. Atualização do diagrama de Voronoi. Para atualizar o diagrama de Voronoi, deve-

se executar um novo algoritmo de Dijkstra tendo como origens os novos vértices

adicionados à solução.

4. Atualização do heap. Veja discussão abaixo.

Dado um vértice u qualquer, seja e(u) = (u; v) a aresta associada a ele no heap. O valor

associado a u no heap pode �car desatualizado apenas se uma das seguintes situações

ocorrer:

a. o valor de d(u) diminui;

b. o valor de d(w) diminui, sendo w um vizinho de u (possivelmente o próprio v);

c. (u; v) deixa de ser uma aresta de fronteira.

2

Repare que nem todas as O(jV j) arestas são distintas. A mesma aresta (u; v) pode aparecer duas

vezes, uma associada ao vértice v, outra ao vértice u. Conforme se verá, isso não é um problema.

Page 41: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 29

No último caso, o valor associado ao vértice u só pode aumentar ou permanecer igual.

Portanto, não é necessário identi�cá-lo assim que ele ocorrer: pode-se manter o vértice

temporariamente no heap com valor desatualizado e tratar esse caso quando o elemento

for removido (passo 1 do algoritmo) ou quando ocorrer o caso (a.) ou o caso (b.) acima.

Esses dois casos devem ser identi�cados e tratados assim que ocorrerem, pois levam

a uma redução no valor associado ao vértice (i.e., um aumento na sua prioridade). É

simples fazer isso. Em cada iteração, os únicos vértices que têm sua distância à base

alterada podem ser identi�cados durante o algoritmo de Dijkstra executado no passo 3.

Basta percorrer a vizinhança desses vértices para atualizar tanto os valores associados a

eles próprios (caso (a.)) quanto os associados aos seus vizinhos (caso (b.)). O mesmo

deve ser feito também com o vértice removido do heap no passo 1 do algoritmo.

Complexidade Em cada iteração do algoritmo, é necessário atualizar o diagrama de

Voronoi (passo 3), o que requer O(jEj+ jV j log jV j) operações no pior caso. Os passos 1

e 4 podem ser executados em tempo O(jEj+ jV j log jV j), pois:

� no máximo jV j atualizações são feitas, cada uma em tempo O(log jV j);

� como a vizinhança de cada vértice é analisada no máximo uma vez no passo 1 e outra

no passo 4, o tempo total necessário para analisar todas as vizinhanças é O(jEj).

Todas as execuções do passo 2 podem ser feitas em tempoO(jV j). Assim, a implementação

Kruskal-V requer O(jT j(jEj+ jV j log jV j)) operações no pior caso.

3.5 Multispan

A última heurística apresentada, Multispan, tende a fornecer soluções de qualidade bem

inferior às anteriores. No entanto, pelo fato de se basear em um princípio diferente do das

demais heurísticas, ela pode ser útil em situações em que é necessário gerar soluções com

diversidade (é o caso da metaeurística apresentada no Capítulo 5).

Inicialmente, determina-se a árvore geradora mínima do grafo e faz-se a poda (pruning)

de todas as folhas que não são terminais (o processo é recursivo: se novas folhas não-

terminais surgirem, também serão podadas). Se pelo menos um vértice for eliminado,

calcula-se a árvore geradora mínima do subgrafo induzido pelos vértices restantes. O

procedimento se repete até que não seja possível fazer a poda da solução obtida.

Cada árvore geradora mínima pode ser determinada em tempo O(jEj + jV j log jV j)

utilizando o algoritmo de Prim. No pior caso, o algoritmo terá O(jV j � jT j) iterações, o

que signi�ca que sua complexidade assintótica é O(jV j(jEj + jV j log jV j)) (pois O(jV j �

jT j) = O(jV j)). Na prática, contudo, o número de iterações é tipicamente muito pequeno.

Normalmente, o número de folhas podadas é grande em algumas poucas iterações iniciais.

Page 42: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 30

O número de folhas podadas logo se reduz, o que quase sempre leva ao �m do algoritmo,

pois a árvore encontrada em uma iteração tende a ser muito semelhante à obtida na

iteração anterior (após a poda).

Uma implementação assintoticamente mais e�ciente do algoritmo (no pior caso) utiliza

o algoritmo de Kruskal para o cálculo da árvore geradora mínima (veja Seção 2.3.1).

Nesse caso, basta ordenar as arestas uma única vez, em tempo O(jEj log jEj). Feito isso,

o cálculo de cada árvore geradora mínima pode ser feito em tempo O(jEj�(jEj; jV j)).

Como cada solução intermediária pode ser podada em tempo O(jV j), são necessárias

O(jEj log jEj + jV jjEj�(jEj; jV j)) = O(jV jjEj�(jEj; jV j)) operações no pior caso para

executar todo o algoritmo.

Observações empíricas mostraram que a implementação baseada no algoritmo de Prim

tende a garantir soluções de melhor qualidade, desde que o algoritmo seja executado a par-

tir de uma raiz diferente em cada iteração. Isso aumenta a probabilidade de que se criem

novas folhas que são não-terminais e, portanto, podem ser podadas. A implementação

baseada no algoritmo de Prim foi a única testada na Seção 3.6.

3.6 Análise Comparativa

3.6.1 Qualidade das Soluções

Nesta seção, comparam-se as diversas heurísticas propostas quanto à qualidade das solu-

ções fornecidas. Para algumas das heurísticas, foram propostas diferentes implementações,

que, em princípio, podem levar a soluções distintas, já que casos de empate pode ser re-

solvidos de forma distinta. Observou-se experimentalmente que isso de fato ocorre, mas

as diferenças são muito pequenas e não indicam a superioridade de uma implementação

em relação às demais. Assim sendo, os resultados apresentados nesta seção referem-se a

uma única implementação de cada heurística:

� DNH: implementação que utiliza o algoritmo de Bor·vka (DNH-Bor·vka);

� Kruskal: implementação baseada no heap de arestas (Kruskal-E);

� Prim: implementação direta (Prim-D);

� DNHz, Bor·vka e Multispan: utilizou-se a única implementação proposta em cada

caso.

Para avaliar a qualidade das soluções fornecidas pelas heurísticas propostas, foram

testadas todas as instâncias das quatro classes apresentadas na Seção 2.4.2: Incidência,

OR-Library, PUC e VLSI. A Tabela 3.1 apresenta, para cada uma dessas classes, três me-

didas para a qualidade relativa das heurísticas (essas medidas são descritas, por exemplo,

em [24]):

Page 43: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 31

� Desvio relativo percentual médio (dr%): Dada uma instância, de�ne-se desvio

relativo percentual de um método M como a diferença percentual entre o valor da

solução obtida por M e o valor da melhor solução encontrada para a instância,

considerando-se todos métodos. O desvio relativo percentual médio é a média dos

desvios percentuais obtidos pelo método para todas as instâncias do grupo.

� Rank médio (rank): Para cada instância, os métodos são ordenados de acordo

com a qualidade das soluções fornecidas. O melhor método tem rank 1, o segundo

melhor tem rank 2 e assim sucessivamente. Em caso de empate, atribui-se a todos os

métodos envolvidos o mesmo rank, calculado como a média dos ranks individuais.

3

O rank médio de um método é a média dos ranks obtidos para todas as instâncias

do grupo.

� melhor: Número de instâncias para as quais o método obteve o melhor valor entre

todos os métodos, incluindo os casos de empate no primeiro lugar.

A comparação entre os métodos também pode ser feita de forma absoluta. Para

cada série de instâncias, a Tabela 3.2 mostra o desvio percentual médio das soluções

fornecidas pelas heurísticas em relação às melhores soluções primais conhecidas. Em

geral, os valores utilizados para comparação são comprovadamente ótimos. Em alguns

casos, porém, utilizam-se os valores obtidos heuristicamente, conforme mencionado na

Seção 2.4.2. Nas séries em que é esse o caso (i640, bip, cc e hc, todas marcadas com um

asterisco na tabela), os valores apresentados são limites superiores para o desvio percentual

em relação ao ótimo.

Tanto na Tabela 3.1 quanto na Tabela 3.2, os valores em negrito destacam o melhor

resultado obtido para cada grupo de instâncias.

Analisando-se as tabelas, merece destaque a (baixa) qualidade das soluções forneci-

das pelo algoritmo Multispan. Apenas para a classe PUC o método tem desempenho

relativo competitivo com alguns dos demais métodos. Não por acaso, as instâncias PUC

são aquelas em que o número de terminais é maior (em relação ao número de vértices),

principalmente na série hc. Em instâncias com poucos terminais, o desempenho da heurís-

tica Multispan tende a ser pior, pois, por ter uma característica global, ela normalmente

encontra soluções com um número de vértices maior que o utilizado por outros métodos.

Quando se comparam as demais heurísticas entre si, observa-se que a qualidade das

soluções fornecidas depende claramente da capacidade de cada método encontrar �atalhos�

nas soluções. Utilizar vértices não-terminais já inseridos na solução para efetuar ligações

em fases posteriores do algoritmo é essencial para garantir melhores resultados.

Nas heurísticas de Kruskal e Prim, as informações de proximidade entre as compo-

nentes do grafo são atualizadas logo após a adição de cada caminho à solução. Com

3

Exemplo: se os valores forem (1200, 1203, 1203, 1205, 1206, 1207), os respectivos ranks serão (1, 2.5,

2.5, 4, 5, 6).

Page 44: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 32

classe algoritmo dr% rank melhor

DNH 8.201 3.660 127

DNHz 4.686 2.888 142

Incidência Bor·vka 3.776 2.441 179

(397 instâncias) Kruskal 1.369 2.317 202

Prim 0.658 1.883 272

Multispan 69.194 5.987 0

DNH 4.697 4.400 4

DNHz 2.356 2.658 11

OR-Library Bor·vka 1.989 2.092 27

(60 instâncias) Kruskal 0.730 2.333 26

Prim 0.889 2.642 12

Multispan 51.679 5.833 1

DNH 28.125 5.120 0

DNHz 20.781 4.050 0

PUC Bor·vka 19.445 3.480 2

(50 instâncias) Kruskal 2.376 1.740 17

Prim 0.438 1.310 33

Multispan 29.494 4.070 0

DNH 3.556 3.599 6

DNHz 3.173 3.224 7

VLSI Bor·vka 1.647 2.250 21

(116 instâncias) Kruskal 0.553 1.573 58

Prim 0.726 1.586 50

Multispan 65.133 6.000 0

DNH 8.597 3.837 137

DNHz 5.472 3.022 160

Total Bor·vka 4.465 2.455 229

(623 instâncias) Kruskal 1.236 2.134 303

Prim 0.675 1.855 367

Multispan 63.565 5.821 1

Tabela 3.1: Qualidade relativa das diversas heurísticas estudadas

Page 45: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 33

série desvio percentual médio

DNH DNHz Bor·vka Kruskal Prim Multispan

i080 24.45 20.76 20.26 18.14 17.23 73.77

i160 26.93 23.29 22.35 20.42 19.32 91.27

i320 29.45 25.57 24.38 21.34 20.74 110.38

i640

30.73 26.41 25.10 22.14 21.41 125.18

c 6.51 4.18 4.06 3.27 3.10 43.77

d 7.04 5.16 4.91 3.71 3.69 58.16

e 9.80 6.69 5.93 4.09 4.70 67.34

bip

56.66 51.41 51.41 14.89 15.01 32.43

cc

38.53 26.02 23.30 11.02 8.67 55.40

hc

30.34 28.36 28.36 10.37 7.18 20.91

alue 5.13 4.57 3.25 2.77 2.67 78.94

alut 6.14 5.85 3.64 3.20 3.91 92.94

diw 5.65 5.43 3.27 1.89 2.54 79.32

dmxa 6.81 6.80 5.14 3.14 3.64 56.79

gap 6.29 5.12 4.03 2.82 3.53 56.23

msm 5.41 5.12 4.00 3.03 2.65 61.99

taq 6.77 6.37 4.52 3.33 3.10 66.14

Tabela 3.2: Desvios percentuais médios em relação às melhores soluções primais conheci-

das

isso, podem-se levar em conta os vértices adicionados em um passo para escolher da me-

lhor maneira possível o caminho a ser adicionado no passo seguinte. Já no algoritmo

de Bor·vka, vários caminhos são adicionados na mesma iteração, mas as informações de

proximidade entre as componentes são atualizadas apenas entre uma iteração e outra.

Na heurística DNHz, a atualização também se faz entre iterações, mas de forma muito

mais limitada. O método DNH não faz qualquer atualização ao longo da execução: as

informações fornecidas pelo diagrama de Voronoi construído no início do algoritmo são as

únicas utilizadas até o �m da execução.

A qualidade média das soluções fornecidas pelos diversos métodos re�ete esses fatos.

As heurísticas de Prim e Kruskal são as que apresentam os melhores resultados na média,

seguidos pelas heurísticas de Bor·vka, DNHz e, �nalmente, DNH.

Em termos absolutos, a qualidade das soluções fornecidas pelas heurísticas implemen-

tadas depende fortemente do tipo de instância testada, conforme deixa claro a Tabela 3.2.

Para as instâncias de Incidência, as soluções fornecidas pelas melhores heurísticas estão

em média a 20% do ótimo. Para a classe VLSI, os resultados são expressivamente me-

lhores: a diferença média entre os valores obtidos pelas heurísticas e os valores ótimos

é de cerca de 3% apenas. Essas qualidades podem ou não ser su�cientes; tudo depende

da aplicação às quais se destinam as soluções obtidas. Os Capítulos 4 e 5 apresentam

Page 46: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 34

métodos que podem ser utilizados para encontrar soluções de melhor qualidade se isso for

necessário.

3.6.2 Tempos de Execução

A qualidade das soluções fornecidas pelas heurísticas construtivas é muito importante,

mas é apenas um aspecto a ser levado em conta na sua análise. Outra característica a ser

considerada é o tempo de execução, discutido nesta seção.

Uma primeira estimativa para o tempo de execução de um algoritmo é sua comple-

xidade de pior caso. A Tabela 3.3 resume as expressões obtidas para as complexidades

das implementações descritas ao longo deste capítulo. A primeira coluna apresenta a

complexidade da implementação �ideal�, enquanto a segunda mostra a complexidade de

pior caso da implementação de fato realizada. Tipicamente, a diferença se deve ao uso

de heaps binários no lugar de heaps de Fibonacci (veja as seções anteriores neste capítulo

para uma discussão detalhada de cada caso).

algoritmo pior caso

teórico implementação

DNH-Prim O(jEj+ jV j log jV j) O(jEj log jV j)

DNH-Bor·vka O(jEj log jT j+ jV j log jV j) O(jEj log jV j)

DNHz O(jEj log jT j+ jV j log jV j) O(jEj log jV j)

Bor·vka O((log jT j)(jEj+ jV j log jV j)) O(jEj log jT j log jV j)

Kruskal-B O(jT j(jEj+ jV j log jV j)) O(jT jjEj log jV j)

Kruskal-E O(jT j(jEj+ jV j log jV j)) O(jT jjEj log jEj)

Kruskal-V O(jT j(jEj+ jV j log jV j)) O(jT jjEj log jV j)

Prim-T O(jT j(jEj+ jV j log jV j)) O(jT jjEj log jV j)

Prim-D O(jT j(jEj+ jV j log jV j)) O(jT jjEj log jV j)

Multispan O(jV jjEj�(jEj; jV j)) O(jV jjEj log jV j)

Tabela 3.3: Complexidade dos algoritmos construtivos estudados

Considerando-se as implementações de fato, a tabela revela quatro �categorias� de

algoritmos, determinadas pelos comportamentos assintóticos. Os três primeiros (DNH-

Prim, DNH-Bor·vka e DNHz) têm complexidade O(jEj log jV j). Na segunda categoria

está apenas o algoritmo de Bor·vka, com pior caso O(jEj log jT j log jV j). A terceira

categoria contém os métodos Kruskal e Prim, que têm complexidade O(jT jjEj log jV j) (o

fator log jEj na complexidade do algorimto Kruskal-E é assintoticamente equivalente a

log jV j para grafos simples). Na quarta categoria está o algoritmo Multispan.

A diferença básica entre os algoritmos, portanto, é sua dependência em relação ao

número de terminais do grafo: nula (primeira categoria), logarítmica (segunda) ou linear

(terceira). (O algoritmo Multispan pode ser considerado um caso à parte. A expressão

de pior caso desse algoritmo é na verdade O((jV j � jT j)jEj�(jEj; jV j)).)

Page 47: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 35

Essa dependência, no entanto, refere-se aos desempenhos de pior caso dos algorit-

mos. Conforme já se mencionou ao longo da descrição de cada um dos algoritmos, as

implementações sugeridas têm justamente o objetivo de serem e�cientes na prática.

Para testar essa e�ciência, cada implementação foi executada sobre todas as instâncias

mencionadas na Seção 2.4.2. A única exceção foi o método Prim-T: como ele exige a alo-

cação O(jT jjV j) posições de memória, não foi possível executá-lo sobre três das instâncias:

alue7065, alue7080 e alut2625. Os valores apresentados para esse algoritmo não incluem

essas instâncias.

Uma primeira medida da e�ciência relativa dos diversos métodos é fornecida na Tabela

3.4. Para cada série, apresentam-se os tempos médios necessários para a execução de cada

algoritmo em um AMD K6-2 com clock de 128 MHz. O símbolo � identi�ca as situações

em que nem todas as execuções puderam ser realizadas.

série tempo (milésimos de segundo)

D-P D-B Dz Bvk Kr-B Kr-E Kr-V Pr-T Pr-D Mltspn

i080 0.9 0.8 0.8 0.9 15.0 1.2 1.2 4.2 1.2 1.3

i160 3.4 3.4 3.4 3.6 102.3 5.2 4.0 25.8 4.7 5.2

i320 15.2 15.7 15.6 16.2 719.5 25.3 15.9 179.7 21.7 24.5

i640 74.4 80.5 80.7 82.2 6234.5 116.1 64.1 1447.6 101.4 124.2

c 6.9 6.2 6.2 6.6 142.4 11.2 9.0 144.4 4.8 16.1

d 15.7 14.7 14.2 15.3 459.0 28.8 22.8 632.7 11.7 42.5

e 49.6 49.6 48.8 55.4 3208.3 94.2 75.0 4485.5 40.2 156.3

bip 20.0 14.9 16.0 16.7 1403.2 19.0 21.8 106.9 16.0 44.6

cc 18.1 17.2 17.0 21.1 1456.1 36.0 28.2 521.2 25.7 41.5

hc 15.7 14.2 14.3 15.2 8628.2 22.1 26.7 512.1 15.9 103.6

alue 61.0 58.7 56.4 76.7 4058.1 73.0 95.2 �104.1 45.0 218.0

alut 90.1 92.2 92.4 126.1 2825.5 115.2 143.2 �320.6 64.7 529.7

diw 20.2 16.9 17.1 24.7 164.5 24.4 29.8 78.4 15.9 90.7

dmxa 5.0 3.9 3.9 5.7 44.8 5.6 7.2 15.9 4.0 15.5

gap 7.6 6.5 6.1 8.8 65.7 8.5 10.6 36.6 5.8 24.4

msm 7.4 5.7 5.7 8.3 63.7 8.1 10.0 24.0 5.8 20.7

taq 12.5 11.0 11.0 14.7 144.1 15.0 18.5 56.0 9.4 49.7

Tabela 3.4: Tempos médios de execução (absolutos) dos métodos construtivos

Essa forma de comparação tem uma de�ciência intrínseca. Como cada série é bastante

heterogênea (com instâncias de tamanhos e características diferentes), os tempos obtidos

por uma mesma implementação podem ser muito distintos dentro da mesma série. Assim

sendo, quando se considera o tempo médio de execução, dá-se um peso maior às instâncias

mais lentas, o que pode introduzir distorções. Para corrigir essa de�ciência, é conveniente

utilizar também o conceito de tempo relativo. Para cada instância, considera-se não o

valor absoluto do tempo de execução, mas a razão entre esse tempo e o de um algoritmo

Page 48: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 36

tomado como referência. Escolheu-se como referência a heurística DNH-Prim, a única

cujo desempenho é completamente independente do número de terminais (os métodos

DNH-Bor·vka e DNHz dependem de jT j, ainda que não assintoticamente). Essa escolha

permite avaliar o que mostra a Tabela 3.3, que a diferença básica entre as complexidades

dos algoritmos implementados está justamente na dependência em relação ao de número

de terminais.

A Tabela 3.5 apresenta, para cada classe, a média dos tempos relativos obtidos pelos

diversos métodos (considerando todas as instâncias testadas de cada classe).

algoritmo tempo relativo médio

Incidência OR-Library PUC VLSI Total

DNH-Prim 1.000 1.000 1.000 1.000 1.000

DNH-Bor·vka 0.847 0.837 0.849 0.779 0.829

DNHz 0.834 0.829 0.861 0.779 0.825

Bor·vka 0.978 0.967 0.972 1.068 0.993

Kruskal-B 25.736 42.668 101.642 8.898 30.324

Kruskal-E 1.518 1.561 1.482 1.071 1.437

Kruskal-V 1.583 1.640 1.469 1.373 1.541

Prim-T 9.664 34.368 15.096 �3.367 �11.345

Prim-D 1.400 0.851 1.162 0.761 1.210

Multispan 1.458 2.248 2.706 2.965 1.913

Tabela 3.5: Tempos médios de execução das heurísticas construtivas em relação a DNH-

Prim

As tabelas sugerem que, no caso das instâncias testadas (que formam um conjunto

bastante amplo e heterogêneo), o desempenho das heurísticas é na média muito mais

equilibrado do que sugerem as complexidades apresentadas na Tabela 3.3, exceção feita

às implementações Prim-T e Kruskal-B. Em relação aos tempos médios, observa-se que

nenhuma das heurísticas (exceto as duas já mencionadas) é duas vezes mais rápida ou

mais lenta que o método de referência.

Para uma melhor análise desse fenômeno, é interessante observar também a Tabela

3.6. Ela mostra, para cada classe de instâncias, os piores tempos relativos obtidos pelas

heurísticas. Ou seja, considerando-se todas as execuções individuais, seleciona-se aquela

cuja razão entre o tempo de execução da heurística em estudo e o da heurística de refe-

rência (DNH-Prim) é maior. Com isso, espera-se tornar mais evidente o pior caso de cada

algoritmo.

A tabela mostra que a implementação Kruskal-B pode ser até três ordens de grandeza

mais lenta que a implementação de referência. Tanto no pior caso quanto na média, esse

método é muito mais lento que todos os demais.

Também o método Prim-T pode ter tempos de execução ordens de grandeza maiores

que os de algoritmos cuja complexidade independe de jT j. No pior caso, esse método foi

Page 49: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 37

algoritmo pior tempo relativo

Incidência OR-Library PUC VLSI Total

DNH-Prim 1.000 1.000 1.000 1.000 1.000

DNH-Bor·vka 1.509 1.526 1.192 1.151 1.526

DNHz 1.509 1.478 1.233 1.164 1.509

Bor·vka 1.509 1.672 1.518 1.579 1.672

Kruskal-B 195.536 274.003 734.123 146.132 734.123

Kruskal-E 3.197 2.375 3.111 1.388 3.197

Kruskal-V 2.704 2.435 2.012 1.772 2.704

Prim-T 53.828 257.691 44.588 �6.890 �257.691

Prim-D 2.107 1.119 1.781 1.063 2.107

Multispan 2.857 7.421 8.567 7.490 8.567

Tabela 3.6: Piores tempos de execução dos métodos construtivos em relação a DNH-Prim

mais de 250 vezes mais lento que o algoritmo DNH-Prim. Esse valor se refere à instância

e20, que, não por acaso, possui um grande número de terminais: 1000. Nessa instância

(um grafo aleatório com distribuição uniforme dos pesos), o termo jT j na expressão da

complexidade da implementação Prim-T se manifesta claramente. Ainda de acordo com

a tabela, também as classes de Incidência e PUC possuem instâncias em que o método

Prim-T é signi�cativamente pior que os demais.

Para as instâncias VLSI, o desempenho do algoritmo é melhor, graças à aceleração

proposta por Polzin e Daneshmand descrita na Seção 3.3.1. A estrutura rígida das ins-

tâncias VLSI faz com que o tempo de cálculo dos caminhos mínimos na primeira fase do

algoritmo seja de fato reduzido. Leve-se em conta, no entanto, que os dados apresentados

não incluem justamente as três maiores instâncias da série, que não puderam ser avali-

adas devido a restrições de memória (o que, aliás, é um dos grandes problemas do método

Prim-T).

Entre os métodos que utilizam uma quantidade linear de memória adicional, o méto-

do mais lento é Multispan, justamente o que fornece soluções de pior qualidade. Deve-se

considerar, no entanto, que a implementação testada não foi a mais e�ciente. Conforme

mencionado na Seção 3.5, utilizou-se o algoritmo de Prim como sub-rotina, sendo o al-

goritmo de Kruskal uma alternativa melhor. Independentemente disso, as qualidades das

soluções fornecidas pela heurística são comparativamente tão ruins que não se justi�cam

maiores investimentos em sua implementação.

Para as instâncias testadas, os métodos com menores tempos de execução na média são

DNH-Bor·vka e DNHz. A comparação dos métodos entre si revela que praticamente não

há distinção entre eles. Isso não é uma surpresa, uma vez que DNHz é apenas uma ligeira

variação de DNH-Bor·vka; as etapas básicas dos algoritmos são as mesmas. Ambos são

normalmente mais rápidas que o método DNH-Prim. Conforme já mencionado, o uso do

algoritmo de Bor·vka para calcular a árvore de Steiner na segunda fase desses algoritmos

Page 50: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 38

é vantajoso porque explora o fato de que o número de terminais freqüentemente é muito

inferior ao de vértices. A Tabela 3.6 mostra que, mesmo nos casos em que o número de

terminais é grande, o desempenho desses métodos não é signi�cativamente inferior ao do

método DNH-Prim (é no máximo cerca de 50% pior).

A heurística de Bor·vka para o problema de Steiner em grafos surge como uma boa

alternativa à heurística DNH. Além de fornecer soluções de qualidade superior, conforme

mostrou a Seção 3.6.1, ela o faz sem requerer signi�cativos aumentos no tempo de execu-

ção. De fato, para as instâncias consideradas essa heurística é em média até mais rápida

que a implementação da heurística DNH usando o algoritmo de Prim. Evidentemente, é

mais lenta que os algoritmos DNH-Bor·vka e DNHz, até porque heurística de Bor·vka é

uma extensão (com iterações adicionais) desses métodos.

Conforme esperado, as duas heurísticas de melhor qualidade, Kruskal e Prim-D apre-

sentam tempos de execução piores que os dos métodos DNH e Bor·vka. Observe, no

entanto, que os tempos são perfeitamente aceitáveis. Considerando todas as 623 exe-

cuções, a heurística de Kruskal foi no máximo 3.2 vezes mais lenta que a heurística de

referência; a heurística Prim-D mostrou-se ainda mais estável, sendo não mais que 2.1

vezes mais lenta que DNH-Prim. Isso mostra que as novas implementações sugeridas são

muito robustas. Apesar de haver um fator jT j nas complexidades de pior caso dessas

heurísticas (veja Tabela 3.3), ele na prática não se manifestou: os tempos de execução

mantiveram-se sempre na mesma ordem de grandeza da heurística DNH-Prim, cujo de-

sempenho independe do número de terminais. Lembre-se de que muitas das instâncias

testadas têm centenas, algumas até milhares, de terminais.

É interessante observar que o algoritmo de Prim é especialmente e�ciente para as ins-

tâncias VLSI. A estrutura rígida dessas instâncias (planares e com uma métrica bem de�ni-

da) faz com que o algoritmo se comporte essencialmente como o algoritmo de Dijkstra.

O número de vezes em que a vizinhança de um vértice deve ser percorrida é relativa-

mente pequeno. Com isso, o algoritmo se torna, na média, até mais rápido as diversas

implementações da heurística DNH.

As duas novas implementações propostas para a heurística de Kruskal, apesar de muito

diferentes, têm desempenhos muito próximos na prática. A implementação baseada em

arestas tem a vantagem de ser mais simples e, nesse teste, mais rápida, ainda que não

muito (a diferença de desempenho só é mais expressiva no caso das instâncias VLSI,

justamente as mais esparsas, em que jV j = O(jEj)). A implementação baseada em nós

tem a vantagem de requerer menor quantidade de memória adicional: apenas O(jV j),

contra O(jEj) da heurística baseada em arestas. Como regra geral, pode-se dizer que a

implementação baseada em heap de nós é mais interessante para instâncias densas; para

as demais, a baseada em arestas parece ser mais interessante.

Comportamento Assintótico As Tabelas 3.5 e 3.6 indicam que, para as instâncias

testadas, as novas implementações propostas para as tradicionais heurísticas de Kruskal

e Prim têm desempenho praticamente independente de jT j para as instâncias testadas.

Page 51: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 39

Apresentam-se a seguir experimentos especí�cos para avaliar esse fato.

Utilizou-se um gerador de grafos aleatórios para construir uma nova série de instâncias

que mostrasse de forma clara a dependência dos algoritmos em relação a jT j. Todos os

grafos da série têm os mesmos números de vértices e arestas; varia apenas o número

de terminais. Escolheu-se arbitrariamente jV j = 1024 e jEj = 32768, o que signi�ca a

série tem densidade intermediária (jEj = jV j

q

jV j). O número de terminais varia entre

jT j = 2 e jT j = 1024, numa progressão geométrica de razão

p

2 (valores não inteiros são

arredondados para cima). Para cada valor de jT j foram criados 20 grafos, com diferentes

sementes para o gerador de números aleatórios. Os pesos das arestas foram aleatoriamente

escolhidos com distribuição uniforme no intervalo [1; 10], como nas instâncias da OR-

Library.

Repare que os limites inferior e superior para jT j representam dois importantes casos

especiais polinomiais do problema de Steiner: o problema do caminho mínimo entre dois

vértices (jT j = 2) e o problema da árvore geradora de peso mínimo (T = V ). A inclusão

desses valores na série tem o único objetivo de permitir uma melhor compreensão do

comportamento dos algoritmos; evidentemente, não se pretende que qualquer dos métodos

aqui propostos seja utilizado para resolver esses casos especiais.

A Figura 3.1 mostra o tempo de execução de cada um dos algoritmos implementados

em função do número de terminais. Cada ponto do grá�co representa a média dos tempos

de execução obtidos para todas as 20 instâncias que possuem a mesma quantidade de

terminais.

Na escala em que foi apresentado, o grá�co só permite uma análise detalhada dos

tempos de execução das implementações Kruskal-B e Prim-T, que, para essa série de

instâncias, dependem de jT j de forma muito mais signi�cativa que os demais métodos.

Para a comparação dos outros métodos entre si, deve-se utilizar a Figura 3.2, que apresenta

os mesmos dados em uma escala mais adequada.

Para analisar os algoritmos, é importante, antes de mais nada, compreender o signi�-

cado de cada curva observada. Uma reta horizontal indica que o tempo de execução do

algoritmo independe do número de terminais. Uma reta inclinada indica que o tempo de

execução do método é proporcional a log jT j, já que os grá�cos têm escala logarítmica.

Uma curva com inclinação crescente indica que uma dependência superlogarítmica em

relação a jT j. Em particular, se a curva for exponencial, a complexidade do algoritmo

será proporcional a jT j.

Apenas três das implementações têm partes relevantes de suas curvas com inclinação

crescente: Kruskal-B, Prim-T e Multispan. A curva que representa Kruskal-B é de�ni-

tivamente uma exponencial: pode-se perceber claramente que o algoritmo tem tempo

de execução proporcional a jT j. Já a curva que representa Prim-T é uma exponencial

apenas para valores de jT j até aproximadamente 256. Para valores mais altos, a taxa

de crescimento do tempo de execução diminui e passa �nalmente a ser negativa. Isso é

conseqüência dos métodos de aceleração propostos por Polzin e Daneshmand descritos

Page 52: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 40

0.00

2.00

4.00

6.00

8.00

10.00

12.00

14.00

16.00

18.00

20.00

2 4 8 16 32 64 128 256 512 1024

tem

po (

s)

terminais (escala log)

Kruskal-BPrim-T

Kruskal-VKruskal-EMultispan

Prim-DBoruvka

DNH-PrimDNH-Boruvka

DNHz

Figura 3.1: Tempos de execução em função do número de terminais

0.00

0.05

0.10

0.15

0.20

2 4 8 16 32 64 128 256 512 1024

tem

po (

s)

terminais (escala log)

Kruskal-BPrim-T

Kruskal-VKruskal-AMultispan

Prim-DBoruvka

DNH-PrimDNH-Boruvka

DNHz

Figura 3.2: Tempos de execução em função do número de terminais (métodos mais rápi-

dos)

Page 53: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 41

na Seção 3.3.1. Mantida a densidade do grafo �xa, a e�cácia desses métodos aumenta

sensivelmente quando o número de terminais é muito grande.

De acordo com a discussão apresentada na Seção 3.5, o número de iterações do algorit-

mo Multispan é proporcional a jV j� jT j no pior caso. No entanto, a curva que representa

esse algoritmo na Figura 3.2 mostra um crescimento superlinear (ainda que mais suave

que os de Prim-T e Kruskal) do tempo de execução em relação a jT j para praticamente

todos os valores de jT j. Isso mostra que, para essa classe de instâncias, o pior caso pouco

revela sobre o comportamento do algoritmo. Apenas no caso limite, em que jV j = jT j,

a expressão de pior caso se revela claramente: apenas uma iteração é executada, já que

o algoritmo reduz-se ao algoritmo de Prim para o problema da árvore geradora mínima.

Nesse caso extremo, Multispan é tão rápido quanto os demais métodos.

Conforme esperado, apenas um método, DNH-Prim, tem desempenho completamente

independente do número de terminais no grafo. A curva que o representa é perfeitamente

horizontal. Consultando a Tabela 3.3, observa-se que também os métodos DNH-Bor·vka

e DNHz têm expressões de pior caso independentes de jT j: O(jEj log jV j). Na verdade, no

entanto, essa expressão �esconde� um termo aditivo jEj log jT j. É a primeira fase dos algo-

ritmos (a construção do diagrama de Voronoi) que é executada em tempo O(jEj log jV j);

a segunda fase (construção da árvore de Steiner) tem complexidade O(jEj log jT j). Isso

explica por que as curvas na Figura 3.2 não são horizontais. Observe que, para essa classe

de instâncias, a implementação da heurística DNH usando o algoritmo de Prim é mais

vantajosa que a que utiliza o de Bor·vka para valores de jT j até aproximadamente 64.

A partir daí, a superioridade é do algoritmo DNH-Prim, ainda que por uma pequena

margem (cerca de 20% no pior caso).

Para essa classe de instâncias, a heurística de Bor·vka para o problema de Steiner

em grafos apresentou desempenho muito semelhante ao das implementações DNH-Prim

e DNHz. Lembre-se de que a diferença principal entre o método de Bor·vka e esses dois

algoritmos é o fato de que, na segunda fase, é necessário recalcular o diagrama de Vonoroi

após cada uma das O(log jT j) iterações. A Figura 3.2 mostra que esse custo adicional é

relevante apenas quando o número de terminais é pequeno. Quando o número é maior,

as alterações no diagrama de Voronoi tendem a ser mais locais e, conseqüentemente, mais

rápidas.

As duas implementações mais rápidas do algoritmo de Kruskal (Kruskal-V e Kruskal-

E) mostraram comportamento distinto para as instâncias testadas. A implementação

baseada em um heap de vértices (Kruskal-V) é mais rápida, especialmente para valores

pequenos de jT j. Para instâncias com poucos terminais, os caminhos escolhidos tendem a

ter um grande número de arestas, o que se traduz em modi�cações relevantes no diagrama

de Voronoi após cada iteração. Na implementação Kruskal-V, a alteração das propriedades

de um vértice v no diagrama de Voronoi se traduz em uma única operação de atualização

do heap. Na implementação Kruskal-E, diversas atualizações são necessárias, uma para

cada vértice de v. Isso explica por que o tempo de execução de Kruskal-E é maior. Repare

que, a partir de um certo ponto (jT j = 11, aproximadamente), um aumento no número de

Page 54: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 42

terminais se traduz em uma queda no tempo de execução desse algoritmo; ela é motivada

pelo fato de que as alterações do diagrama de Voronoi entre iterações tornam-se cada vez

mais limitadas.

Repare que as diferenças entre as novas implementações (Kruskal-V e Kruskal-E)

são pequenas quando se considera a implementação básica (Kruskal-B), que é ordens

de grandeza mais lenta. Nesse caso, está claro que a troca de uma implementação sim-

ples por outra mais elaborada é extremamente vantajosa, mesmo não havendo ganhos

assintóticos no pior caso.

O método que consistentemente obteve os menores tempo de execução foi a imple-

mentação direta do algoritmo de Prim, signi�cativamente mais rápida que as demais.

Para essa classe de instâncias, o tempo de execução do método Prim-D é praticamente

independente do número de terminais. Seus tempos de execução são em média de 30%

a 40% menores que os do algoritmo DNH-Prim, cuja complexidade de pior caso de fato

independe do valor de jT j. Há duas razões que permitem que Prim-D seja tão mais rápido

que as demais implementações para algumas instâncias (como as dessa série):

� Entre os algoritmos estudados, ele é o único capaz de encontrar uma solução sem

sequer percorrer todas as arestas do grafo. Isso explica por que o algoritmo é o mais

rápido para o caso jT j = 2: ele simplesmente se reduz ao algoritmo de Dijkstra.

� O algoritmo Prim-D faz uma única �passagem� pelo grafo. Todas as demais imple-

mentações (com exceção das lentas Multispan, Kruskal-B e Prim-T) se iniciam com

a construção do diagrama de Voronoi. É necessária pelo menos mais uma passagem

pelo grafo para determinar a árvore propriamente dita. É claro que, na sua �única

passagem�, Prim-D pode precisar percorrer a vizinhança de um mesmo vértice diver-

sas vezes: O(jT j) no pior caso. Claramente não é isso que ocorre para as instâncias

aqui testadas.

Como conclusão da análise das Figuras 3.1 e 3.2, é importante reiterar que ela tem �m

apenas ilustrativo. Trata-se de uma classe de instâncias muito especí�ca: grafos aleatórios

com densidade �xa, distribuição aleatória dos pesos das arestas, terminais aleatoriamente

escolhidos. Variações em quaisquer desses fatores podem se traduzir em curvas signi�ca-

tivamente diferentes. Algoritmos que se mostraram especialmente interessantes para essa

classe podem não sê-lo para outras. A análise de um caso especí�co é útil para melhor

compreender alguns aspectos do funcionamento de cada algoritmo. Não se deve tirar dela

qualquer conclusão de�nitiva sobre a qualidade relativa dos métodos.

3.7 Conclusão

Este capítulo apresentou apenas algumas dentre as diversas heurísticas construtivas exis-

tentes para o problema de Steiner. O ponto em comum entre todas as heurísticas é o fato

Page 55: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 3. HEURÍSTICAS CONSTRUTIVAS 43

de se basearem em algoritmos para o problema da árvore geradora de custo mínimo. É

muito simples, portanto, explicar em linhas gerais o funcionamento de cada uma delas,

embora nem sempre seja esse o caso quando se trata da implementação.

Entre as contribuições do capítulo estão duas novas heurísticas muito simples, DNHz

e Bor·vka, ambas extensões da implementação de Melhorn para a heurística DNH. Sem

aumentar de forma relevante os tempos de execução, ambas apresentam resultados em

geral melhores que os do método original, pois buscam ativamente encontrar �atalhos�

que levem a caminhos mais curtos. Ou seja: enquanto a heurística original busca ligar

sempre dois terminais, as variantes tentam, em menor ou maior grau, utilizar vértices não-

terminais previamente inseridos como �âncoras� para a ligação de diferentes componentes.

De fato, buscar atalhos parece ser a chave para garantir a qualidade das soluções

fornecidas. Os algoritmos que fazem isso de maneira mais cuidadosa, as heurísticas de

Prim e Kruskal, são os que levam aos melhores resultados. Depois da inserção de cada

novo caminho à solução, esses métodos reavaliam as informações de proximidade para

identi�car novos atalhos criados.

A principal contribuição deste capítulo talvez seja ter mostrado experimentalmente que

é possível fazer com que esses métodos sejam tão rápidos quanto os métodos anteriores,

apesar das expressões de suas complexidades sugerirem o contrário. Na prática, o que

se observou é que, para as instâncias da literatura, é possível executar os algoritmos de

Prim e Kruskal em tempos da mesma ordem de grandeza que a heurística DNH, que é

assintoticamente muito mais e�ciente no pior caso. Mais que isso, em muitos casos os

algoritmos mais elaborados foram até mais rápidos que o método DNH.

Isso foi conseguido graças às novas implementações das heurísticas de Prim e Kruskal

aqui apresentadas. Todas seguem o mesmo princípio: evitar o retrabalho. Ao longo de

sua execução, os algoritmos mantêm estruturas auxiliares que lhes permitem identi�car

exatamente quais medidas anteriormente calculadas podem estar desatualizadas e quais

não podem. Atuando só nos casos estritamente necessários, os ganhos em desempenho

são signi�cativos. Note que, no pior caso, as novas implementações não têm complexidade

melhor que as das normalmente utilizadas. Na prática, no entanto, o que se observou para

as instâncias testadas foi um ganho assintótico: o fator jT j nas expressões de complexidade

dos algoritmos simplesmente não se revelou.

Portanto, das experiências relatadas nesse capítulo deriva-se um princípio com apli-

cações muito mais amplas que o problema de Steiner. Uma implementação mais elaborada

de um algoritmo, mesmo quando não representa um ganho assintótico no pior caso, pode

levar a signi�cativos ganhos de desempenho. Dentro dos limites do razoável, deve-se fa-

zer o máximo para permitir ao o algoritmo ser melhor que seu pior caso, especialmente

quando o pior caso é muito raro.

Page 56: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Capítulo 4

Busca Local

Apesar de as soluções encontradas por heurísticas construtivas terem qualidade média

razoável, há situações em que é desejável obter soluções ainda melhores, mesmo que para

isso seja necessário executar rotinas computacionalmente mais custosas. Nesta seção,

serão discutidos diversos métodos de busca local, que têm exatamente esse �m: melhorar

a qualidade de soluções já existentes.

Essencial para algoritmos de busca local é a noção de vizinhança. Uma vizinhan-

ça de�ne, para qualquer solução S, um conjunto de outras soluções com características

�muito próximas�. Tipicamente, as soluções vizinhas de S podem ser obtidas por meio

de pequenas modi�cações em S, sendo a natureza dessas modi�cações justamente o que

caracteriza a vizinhança. Um método de busca local consiste simplesmente em percorrer

a vizinhança de uma solução (a solução corrente) em busca de outra que tenha menor

valor. Se for encontrada uma tal solução, ela se torna a nova solução corrente e o algorit-

mo continua. Se uma determinada solução não tiver nenhuma solução vizinha de melhor

qualidade, diz-se que ela é um ótimo local .

A Seção 4.1 apresenta três formas de representação de uma solução para o problema

de Steiner em grafos: por vértices de Steiner, por vértices-chaves e por caminhos-chaves.

A Seção 4.2 mostra como cada uma dessas representações de�ne uma vizinhança. A

implementação dos métodos de busca local em si é discutida na Seção 4.3. A Seção 4.4

apresenta uma análise comparativa experimental dos diferentes métodos de busca local,

incluindo estratégias híbridas baseadas na composição de diferentes algoritmos. Por �m,

a Seção 4.5 comenta os resultados obtidos.

Na literatura, encontram-se implementações anteriores de métodos de busca local

baseados em nós de Steiner [40, 60] e em caminhos-chaves [59]. Métodos híbridos utilizan-

do ambas as vizinhanças foram apresentados em [38] e [50], sendo essa última referência a

base do Capítulo 5. A noção de vértices-chaves também não é nova [15, 16]. No entanto,

não é de conhecimento do autor uma descrição prévia de um método formal de busca

local baseado em vértices-chaves. A primeira versão da rotina descrita nesta dissertação

foi apresentada em [43], artigo escrito em co-autoria com Marcus Poggi de Aragão, Celso

44

Page 57: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 45

C. Ribeiro e Eduardo Uchoa.

4.1 Representação da Solução

Uma solução S para o problema de Steiner em grafos é representada de forma completa

pelos conjuntos de vértices (V

S

) e arestas (E

S

) que a compõem. Há, no entanto, outras

formas de se representar uma solução. A partir de qualquer uma delas, os conjuntos V

S

e

E

S

podem ser facilmente derivados. Entre essas representações, destacam-se:

� Arestas. Uma solução pode ser representada simplesmente por E

S

, seu conjunto

de arestas. O conjunto de vértices (V

S

), é formado pelas extremidades das arestas

de E

S

.

� Vértices de Steiner. Os vértices não-terminais que pertencem a uma solução

recebem a denominação de vértices de Steiner. Se forem conhecidos apenas os

vértices de Steiner de uma solução S, basta adicionar a eles o conjunto de terminais

(T ) para restaurar V

S

. A partir de V

S

, determina-se E

S

calculando-se uma árvore

geradora mínima no subgrafo de G induzido por V

S

.

� Vértices-chaves. O conjunto K

S

de vértices-chaves (ou nós-chaves) de uma

solução S é formado por todos os não-terminais que têm grau maior que dois na

solução. A partir desse conjunto pode-se recuperar a solução S. Basta para isso

(1) calcular a árvore geradora mínima do subgrafo de D(G) (o grafo de distâncias,

de�nido na Seção 3.1) induzido por K

S

[ T (o conjunto de nós cruciais ou vértices

cruciais, seguindo a terminologia adotada em [16]) e (2) extrair de cada aresta dessa

árvore geradora, que representa um caminho, as arestas correspondentes do grafo

original.

� Caminhos-chaves. Caminhos-chaves são caminhos entre nós cruciais de um grafo.

Qualquer solução S pode completamente caracterizada pelo conjunto de caminhos-

chaves a compõem. A partir desse conjunto, podem-se determinar os vértices (V

S

)

e arestas (E

S

) de S de forma imediata: são os vértices e arestas que compõem os

caminhos. Observe que não é necessário armazenar todos os vértices ou arestas de

cada caminho-chave; basta que sejam conhecidas suas extremidades. O caminho

completo é reconstruído como o caminho mínimo entre elas.

A única das representações compactas propostas que permite a reconstrução exata da

solução armazenada é a representação por arestas. Em todos os demais casos, o processo

de �compactação� não é completamente reversível. A partir de um único conjunto de

vértices de Steiner V

S

, podem-se obter diversos conjuntos de arestas distintos; basta,

para isso, que a árvore geradora do subgrafo induzido por V

S

não seja única. Situações

semelhantes ocorrem para o conjunto de vértices-chaves e para o de caminhos-chaves

(quando representados apenas por suas extremidades).

Page 58: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 46

Na verdade, existe a possibilidade de que, após a compactação e a descompactação

de uma solução S, seja recuperada uma solução de valor ainda menor que o original.

Considere, por exemplo, a representação baseada em vértices de Steiner. Uma solução

S = (V

S

; E

S

) é comprimida simplesmente ignorando-se E

S

. A partir de V

S

, constrói-se

um conjunto E

S

0

calculando-se a árvore geradora mínima do subgrafo induzido por V

S

. O

conjunto de arestas encontrado terá o menor custo possível, dada a restrição de que todos

os vértices de V

S

devem ser utilizados. Contudo, pode ocorrer que o conjunto original de

arestas E

S

não fosse minimal, ou seja, que E

S

não representasse as arestas de uma árvore

geradora mínima de V

S

. Nesse caso, a solução S

0

recuperada seria ainda melhor que a

armazenada.

Para a maioria das aplicações, essa irreversibilidade do processo de compactação não

representa um problema. O fato de a solução recuperada ser melhor que a original pode

até ser uma vantagem. É esse o caso para todos os usos discutidos neste e nos próximos

capítulos.

4.2 Vizinhanças

A partir das representações introduzidas na seção anterior, podem-se de�nir vizinhanças

para o problema de Steiner em grafos. A vizinhança de uma solução S é constituída

por todas as soluções a que se pode chegar a partir de uma modi�cação em S, sendo a

natureza da modi�cação justamente o que caracteriza a vizinhança. Serão apresentadas

três vizinhanças, baseadas em vértices de Steiner (Seção 4.2.1), caminhos-chaves (4.2.2) e

vértices-chaves (4.2.3).

4.2.1 Vértices de Steiner

Considere a representação de uma solução como um vetor de incidência de vértices de

Steiner: se uma determinada posição tem valor 1, o vértice correspondente pertence à

solução; se tem valor 0, não pertence. Considera-se uma solução S

0

vizinha de uma

solução S se os vetores que as representam forem diferentes em no máximo uma posição.

Em outras palavras, se S

0

é obtida a partir da inserção ou da remoção de um único

nó de Steiner de S. Isso signi�ca que cada solução tem no máximo jV j � jT j vizinhos.

Possivelmente haverá menos, uma vez que, para que S

0

represente uma solução viável, o

subgrafo induzido pelos terminais e pelos vértices de Steiner deve ser conexo.

Utilizando-se essa vizinhança, todo o espaço de busca pode ser alcançado a partir de

qualquer solução inicial. O diâmetro do espaço é jV j � jT j. A solução mais distante de

uma solução qualquer é aquela em que todos os jV j � jT j bits que a representam estão

invertidos. Para chegar de uma a outra, basta inserir inicialmente os vértices de Steiner

da solução objetivo e em seguida remover os vértices de Steiner �supér�uos� da solução

inicial (como ambas as etapas são feitas passo a passo, deve-se ter o cuidado de escolher

Page 59: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 47

em cada momento um vértice que não desconecte o subgrafo induzido).

4.2.2 Caminhos-chaves

Seja S = fc

1

; c

2

; c

3

; : : : ; c

k

g uma solução para o problema de Steiner no grafo G, re-

presentada em termos dos caminhos-chaves que a compõem. Se for removido de S um

caminho-chave c

i

qualquer, restarão duas componentes conexas. Sejam C

a

e C

b

essas

componentes. A S

i

vizinha de S associada a c

i

é formada pelas componentes C

a

e C

b

e

por um caminho de comprimento mínimo que liga algum vértice de C

a

a outro de C

b

. De

acordo com essa de�nição, a solução S pode ser seu próprio vizinho.

O número de vizinhos de uma solução é igual ao número de caminhos-chaves que a

compõem. Em [59], prova-se que esse número é no máximo 2jT j � 3. Ao contrário da

vizinhança baseada em nós de Steiner, essa vizinhança não permite percorrer todo o espaço

de soluções a partir de qualquer solução factível. O contra-exemplo é simples: considere

o grafo planar formado por um triângulo eqüilátero em que os três pontos extremos são

terminais e o baricentro é um não-terminal ligado aos três terminais; se a solução inicial

for formada por dois lados do triângulo, essa estratégia de busca local jamais encontrará

uma solução que utilize o baricentro. Para que fosse possível percorrer todo o espaço de

busca a partir de qualquer ponto, não se poderia exigir a minimalidade do caminho que

religa as componentes formadas pela remoção de um caminho-chave.

4.2.3 Vértices-chaves

A vizinhança baseada em vértices-chaves (ou nós-chaves) assemelha-se à baseada em nós

de Steiner. Dada uma solução S, seus vizinhos são determinados a partir da inserção

ou da remoção de um único nó-chave. Entretanto, ao contrário do que ocorre com a

busca por nós de Steiner, o que se faz é uma tentativa de se mudar a solução de uma

determinada forma. Considere, por exemplo, o caso da inserção. Seja K

S

o conjunto de

nós-chaves da solução corrente S. A inserção de um novo nó-chave v é feita calculando-se

a árvore geradora mínima do subgrafo do grafo de distâncias induzido por T [K

S

[ fvg.

Com certeza v pertencerá à nova árvore obtida, mas nada garante que será de fato um

nó-chave, ou seja, que terá grau maior ou igual a três. Mais que isso, nada garante que o

conjunto de nós-chaves da solução obtida será de fato K

S

[fvg. Nós que antes pertenciam

a K

S

podem passar a ter grau menor que três e outros nós podem passar a ter grau maior.

O caso da remoção é similar: não se sabe ao certo quais serão os nós-chaves da solução

vizinha.

Assim, a de�nição da vizinhança baseada em nós-chaves é menos rígida que a baseada

em vértices de Steiner. Basicamente, o que se faz é �sugerir� uma modi�cação (tornar

um vértice crucial ou não-crucial), mas a sugestão pode levar a modi�cações ainda mais

profundas. Conforme se verá na Seção 4.4, neste caso a falta de rigidez não torna a busca

local menos e�ciente.

Page 60: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 48

4.3 Implementação da Busca Local

Nesta seção são discutidas implementações de métodos de busca local baseados nas três

vizinhanças apresentadas na seção anterior. Conforme se verá, em alguns casos é interes-

sante modi�car ligeiramente a de�nição da vizinhança para tornar mais e�cazes os algorit-

mos. Ao longo das subseções seguintes, será adotada a seguinte convenção: S = (V

S

; E

S

)

denota a solução corrente e S

v

representa uma solução vizinha, sendo v o vértice que car-

acteriza a transição S para S

v

(o signi�cado preciso de v depende da vizinhança utilizada

e �cará claro em cada caso).

4.3.1 Estratégia Geral

Os três métodos de busca local implementados compartilham a mesma estrutura geral;

varia apenas a vizinhança considerada. O método básico consiste em percorrer circular-

mente a lista de vértices que fazem parte do grafo. Para cada vértice, veri�ca-se se ele

determina um ou mais movimentos. Em caso positivo, os vizinhos correspondentes são

explorados, um a um. Se o custo de um vizinho for pelo menos tão bom quanto o da

solução corrente, o vizinho passará a ser a solução corrente. Mesmo em caso de substi-

tuição da solução corrente, a busca continua a partir do nó seguinte na lista. A busca

termina assim que for feita uma passagem por todos os nós sem que haja melhora estrita

no valor da solução corrente. Diz-se então que a busca chegou a um ótimo local .

A noção de movimento depende da vizinhança utilizada. Para a busca por nós de

Steiner, um não-terminal v pode induzir dois tipos de movimento: inserção, se não �zer

parte da solução, e remoção, se �zer. Para a busca por vértices-chaves, um não-terminal

v será candidato a remoção se �zer parte da solução corrente e tiver grau maior ou igual a

três; todos os demais não-terminais são candidatos a inserção. Para a busca baseada em

caminhos-chaves, induzem movimentos tanto os terminais quanto os vértices-chaves: todos

os caminhos incidentes em v são caminhos-chaves e, portanto, candidatos a substituição

(nesse caso, um mesmo vértice pode induzir mais de um movimento).

Pruning Nas buscas baseadas em nós de Steiner e nós-chaves, vizinhos são determina-

dos pelo cálculo de árvores geradoras mínimas. Se houver um nó não-terminal de grau

unitário na árvore, tanto ele quando a aresta associada a ele são retirados. Isso mantém

a viabilidade da solução e reduz o seu valor, o que contribui para melhorar a qualidade

das soluções fornecidas pelas buscas locais e acelera sua convergência. A poda (pruning)

de todos os vértices �descartáveis� de cada solução pode ser feita em tempo O(jV j), des-

prezível em relação ao tempo total de execução das rotinas de busca local. Assim sendo,

esse procedimento foi adotado na computação de vizinhos tanto na busca por vértices de

Steiner quanto na busca por vértices-chaves.

Page 61: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 49

Aleatorização Na descrição inicial da estratégia de busca local, mencionou-se que a

lista de vértices do grafo deve ser percorrida circularmente. A ordem em que os vértices

são considerados pode interferir na qualidade das soluções obtidas. Nas implementações

realizadas, utilizou-se sempre uma permutação aleatória dos vértices.

4.3.2 Busca por Vértices de Steiner

Dado um vértice v, a vizinhança baseada em vértices de Steiner prevê dois tipos de

movimentos: inserção e remoção. Na análise de um potencial vizinho S

v

, é necessário

determinar tanto sua viabilidade como seu custo.

Viabilidade No caso do movimento de inserção, o teste de viabilidade é trivial. Basta

veri�car se existe uma aresta entre ele e algum outro vértice da solução, o que pode ser

feito em tempo proporcional ao grau de v. Para acelerar a busca local, é conveniente

exigir que haja pelo menos duas arestas ligando v a V

S

. Se houver apenas uma aresta,

a solução vizinha será viável, mas seu custo será maior que o de S (antes do pruning),

pois v será obrigatoriamente uma folha. Apenas com duas ou mais arestas ligando v ao

conjunto original de vértices é possível que a solução vizinha seja melhor.

Para o movimento de remoção, o teste de viabilidade é mais complexo. Seria necessário

fazer uma busca (em profundidade, por exemplo) no subgrafo induzido pelos vértices

restantes na solução (nós de Steiner e terminais) e veri�car se todos são alcançados. Isso

requer O(jEj) operações no pior caso.

1

Na implementação realizada, optou-se por embutir

o teste de viabilidade no próprio cálculo do custo da solução (árvore) vizinha.

Custo O custo da solução vizinha é calculado com o algoritmo de Kruskal para o proble-

ma da árvore geradora mínima. Conforme já mencionado na Seção 2.3.1, esse algoritmo

é executado em duas fases. Na primeira, as arestas candidatas a pertencer à árvore ge-

radora mínima são ordenadas em ordem não-decrescente de custos. Na segunda etapa,

percorre-se a lista de arestas e, sempre que uma aresta não formar ciclos, ela é inserida

na solução.

Durante a execução da busca local, o algoritmo de Kruskal é aplicado diversas vezes

sobre diferentes subconjuntos de E. Contudo, não é necessário que em cada execução seja

executado um algoritmo completo de ordenação. Em lugar disso, ordenam-se uma única

vez todas as arestas em E, o que requer O(jEj log jEj) operações. Seja L

0

a lista ordenada

de arestas resultante. A partir de L

0

, criam-se jV j sublistas (também ordenadas), cada

uma representando as arestas adjacentes a um dos vértices: L

1

; L

2

; : : : ; L

jV j

. Repare que

1

Na verdade, em tempo O(jEj) é possível determinar todos os vértices cuja remoção inviabiliza a

solução. Basta calcular as componentes biconexas do subgrafo de G induzido pelos vértices da solução; os

vértices de articulação são os que não podem ser removidos. Um algoritmo para encontrar componentes

biconexas em tempo O(jEj) é descrito, por exemplo, em [37]. Esse algoritmo não foi implementado.

Page 62: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 50

as sublistas não são disjuntas, já que cada aresta aparece em exatamente duas delas.

Como a lista original de arestas L

0

é ordenada, a criação das sublistas pode ser feita em

tempo total O(jEj).

Além das jV j+ 1 listas já mencionadas, é conveniente manter, a cada momento, duas

outras listas ordenadas: L

S

, contendo as arestas da solução corrente, e L

S

, contendo

todas as arestas do subgrafo de G induzido pelos vértices da solução corrente. Ambas as

estruturas podem ser criadas em tempo O(jEj) a partir de L

0

. Repare que, como a solução

corrente (S) pode mudar ao longo do algoritmo, ambas as listas podem ser recomputadas

diversas vezes (ao contrário das listas L

0

; L

1

; : : : ; L

jV j

).

Uma vez de�nidas as estruturas auxiliares, pode-se discutir a implementação dos dois

tipos de movimento na busca por nós.

No caso do movimento de inserção, pode-se garantir que existe uma árvore geradora

mínima do grafo induzido por V

S

[fvg contendo apenas arestas originalmente contidas na

solução corrente (E

S

) e arestas que ligam v a V

S

. Assim, conjunto de arestas candidatas

é resultado da intercalação de L

S

e o subconjunto relevante de L

v

, a lista de arestas

incidentes em v. Como há no máximo O(jV j) elementos em cada lista, a intercalação pode

ser feita em tempo O(jV j). A complexidade do movimento de inserção como um todo é,

portanto, dominada pela da segunda fase do algoritmo de Kruskal: O(jV j�(2jV j; jV j)),

praticamente linear.

2

Para o movimento de remoção, utiliza-se como lista de candidatos L

S

, que contém

todas as arestas do subgrafo induzido pela solução corrente. Algumas dessas arestas

(as incidentes em v) são simplesmente ignoradas durante a segunda fase do algoritmo

de Kruskal, que é executada em tempo O(jEj�(jEj; jV j)) (no pior caso, L

S

tem O(jEj)

elementos). Conforme já mencionado, o algoritmo de Kruskal incorpora um teste de

viabilidade: ao �nal do algoritmo ele testa, em tempo constante, se a solução criada tem

de fato apenas uma componente conexa.

A atualização da lista L

S

é feita após todo movimento bem-sucedido, seja ele de

remoção ou inserção. A atualização pode ser feita em tempo O(jEj). Se efetuada após um

movimento de remoção, basta retirar da lista as arestas incidentes no vértice removido.

Se efetuada após uma inserção, basta intercalar a lista anterior com a lista de arestas

incidentes no vértice inserido (restrita às arestas incidentes em vértices do subgrafo).

4.3.3 Busca por Caminhos-chaves

A implementação da busca local baseada em caminhos-chaves deriva diretamente da de-

�nição da vizinhança. Quando um caminho-chave é retirado da solução, ela é dividida

2

É possível implementar o movimento de inserção em tempo O(jV j) usando algoritmos especí�cos

para atualização de árvores geradoras mínimas [40, 53]. A implementação desses algoritmos, no entanto,

é relativamente complexa, o que sugere que sua aplicação na prática pode não ser tão vantajosa. Esse

métodos não foram implementados.

Page 63: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 51

em duas componentes conexas, C

a

e C

b

. A determinação da solução vizinha consiste

em calcular o menor caminho mínimo entre um vértice de C

a

e um vértice de C

b

. Is-

so pode ser feito em tempo O(jEj + jV j log jV j) executando-se o algoritmo de Dijkstra.

Utillizam-se como pontos de partida todos os vértices de uma das componentes (inseridos

inicialmente no heap com peso 0) e como alvo qualquer vértice da outra componente.

Um detalhe de implementação importante para o tempo de execução do algoritmo é a

escolha da componente que servirá de origem em cada caso. Tipicamente, ao se remover

um caminho-chave, uma das componentes geradas tem muito menos vértices que a outra.

Em tempo proporcional ao tamanho da solução, O(jV j), é possível determinar qual delas

é menor. Escolhê-la como origem acelera consideravelmente a execução do algoritmo.

Conforme já mencionado, a busca é implementada de forma circular e exaustiva, sendo

os vértices analisados seguindo uma permutação aleatória dos rótulos originais. Para cada

vértice-chave ou terminal v, veri�cam-se os vizinhos determinados por todos os caminhos-

chaves da solução S que têm v como extremidade. Para evitar a repetição de operações,

só são considerados os caminhos-chaves cuja outra extremidade tem rótulo maior que v.

Se a solução vizinha S

v

for melhor que a solução original, S

v

torna-se a nova solução

corrente.

De�ne-se agora o que torna uma solução vizinha melhor que a solução corrente. De

acordo com a própria de�nição da vizinhança (Seção 4.2.2), um vizinho S

v

de uma solução

S jamais terá valor maior que o de S. Evidentente, se S

v

tiver valor estritamente menor

que o de S, S

v

deve se tornar a solução corrente. Caso contrário (i.e., se as duas soluções

tiverem o mesmo valor), os seguintes critérios de desempate são considerados:

1. Número de terminais Seja c

i

o caminho-chave retirado de S e c

0

i

o caminho-

chave que o substitui em S

v

. Será considerada melhor a solução cujo caminho-chave

correspondente tiver mais terminais como extremidade (o número de terminais pode

ser 0, 1 ou 2). Se, por exemplo, ambas as extremidades de c

0

i

forem terminais mas

apenas uma das extremidades de c

i

o for, a solução corrente será substituída pela

vizinha. A motivação para esse critério é simples. A substituição de um caminho-

chave por outro que utiliza mais terminais diminui em uma unidade o grau de

pelo menos um não-terminal u que originalmente era vértice-chave. Em especial,

se o novo grau de u for 2, ele deixará de ser um vértice-chave. Com isso, os dois

caminhos-chaves que a ele se ligavam passam a formar um único caminho, que, por

ser mais longo, tem maior probabilidade de ser substituído em iterações futuras do

algoritmo.

2. Número de vértices Em caso de empate no critério anterior, escolhe-se a solução

com maior número de vértices. Um aumento no número de vértices na solução tende

a criar mais �pontos de ligação� entre os pares de componentes conexas formados

pela remoção de caminhos-chaves em passos posteriores da busca local. Com isso,

aumenta a chance de que caminhos menores sejam encontrados.

Os critérios de desempate serão menos e�cazes se utilizados apenas para escolher

Page 64: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 52

entre o caminho mínimo encontrado e o caminho originalmente existente entre as duas

componentes. Na implementação realizada, o próprio algoritmo para determinação do

caminho mínimo incorpora as regras de seleção. Durante a construção dos caminhos, dá-

se prioridade àqueles partem de terminais e/ou chegam a terminais, e em caso de empate,

àqueles que possuem o maior número de vértices. Observe que, estando os critérios de

desempate embutidos no próprio algoritmo de Dijkstra, a solução vizinha calculada será

garantidamente melhor que a solução corrente (ou pelo menos igual a ela). Assim, sempre

a solução vizinha substitui a corrente.

A inclusão dos critérios de desempate no algoritmo pode ser feita de forma muito

simples, pela adição de perturbações aos custos originais das arestas. Para privilegiar

caminhos mais longos, basta subtrair um valor constante "

1

do peso de todas as arestas.

A prioridade para caminhos incidentes em terminais pode ser obtida subtraindo-se um

fator extra "

2

das arestas incidentes em um terminal e 2"

2

das arestas incidentes em dois

terminais. Se os pesos das arestas forem inteiros (como no caso de todas as instâncias

testadas), os valores "

1

= 1=(3jV j) e "

2

= 1=3 (por exemplo) garantem que os critérios

acima serão corretamente observados. Conforme já mencionado na Seção 4.3.1, a busca

termina assim que todos os vértices forem testados sem que o valor da função objetivo se

altere. Nesse caso, o valor é calculado sobre os custos originais das arestas, sem levar em

conta as perturbações.

Na prática, o que se veri�ca é que os critérios de desempate são relevantes quando

há uma multiplicidade de caminhos mínimos ligando duas componentes. Isso é comum

principalmente para instâncias em que muitas arestas têm exatamente o mesmo peso,

como nos classes OR-Library, VLSI e em algumas instâncias da série PUC (as terminadas

em u). Para instâncias de Incidência e as da classe PUC terminadas em p, os critérios

raramente são decisivos.

Experimentos preliminares mostraram, no entanto, que o uso rigoroso dos critérios de

desempate tem um lado negativo. Quando é necessário aplicar a busca local por caminhos-

chaves diversas vezes sobre a mesma instância (a partir de diferentes soluções iniciais),

como no caso das metaeurísticas descritas no Capítulo 5, a variabilidade das soluções pode

diminuir. É razoável que isso aconteça, já que os critérios de desempate contêm certos

�preconceitos� quanto ao que constitui uma boa solução.

Optou-se por uma solução intermediária: utilizam-se os critérios de desempate, mas

não de forma estrita. Adiciona-se a ele um componente aleatório. Mais especi�camente,

subtrai-se do custo da aresta e valor " � (jV j � t(e) + rand(0; 20)) do custo de cada aresta,

sendo " uma constante pequena, t(e) o número terminais em que e é incidente (0, 1 ou 2)

e rand(0; 20) um número escolhido aleatoriamente com distribuição uniforme no intervalo

[0; 20]. Essa expressão, empiricamente determinada, quase sempre obedece à prioridade

dada a caminhos com mais terminais, mas usa apenas de forma aproximada o critério que

privilegia caminhos mais longos. Na implementação realizada, sempre a solução vizinha

substitui a corrente, ainda que seja igual ou mesmo pior (segundo os critérios sugeridos).

Page 65: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 53

4.3.4 Busca por Vértices-chaves

A busca por nós-chaves pode ser implementada como a busca por nós de Steiner, mas

aplicada sobre o grafo de distâncias D(G). O principal problema dessa implementação

é o fato de que o grafo de distâncias é completo, com O(jV j

2

) arestas. A quantidade de

memória necessária se torna rapidamente proibitiva com o aumento de jV j.

Felizmente, é possível calcular a árvore geradora mínima do grafo de distâncias sem que

seja necessário determinar explicitamente esse grafo. De acordo com o discutido na Seção

3.1, pode-se utilizar uma adaptação da heurística construtiva DNH (com a implementação

de Melhorn [39]). Em sua forma original, a heurística calcula a árvore geradora mínima

do subgrafo de D(G) induzido por T , o conjunto de terminais. Para estender o algoritmo

para o subgrafo induzido porK

S

[T (sendoK

S

o conjunto de nós-chaves), basta considerar

como �pseudoterminais� justamente o conjunto T [K

S

(os nós cruciais, na denominação

introduzida na Seção 4.1).

Conforme já mencionando na Seção 3.1, os caminhos escolhidos pela heurística DNH

entre os pares de nós cruciais não são necessariamente disjuntos. Como uma aresta que

aparece em mais de um caminho deve ser considerada apenas uma vez, a solução fornecida

pela heurística DNH pode ter valor menor que o da árvore geradora mínima do subgrafo

induzido pelo conjunto de nós cruciais. Do ponto de vista do método de busca local,

essa particularidade é muito interessante: soluções vizinhas de qualidade melhor que a

esperada são sempre bem-vindas.

A análise experimental das heurísticas construtivas feita no capítulo anterior revela,

no entanto, que a heurística DNH em geral provê soluções de menor qualidade que as

fornecidas por outras heurísticas. Nesse aspecto, um dos métodos de maior destaque é a

heurística de Prim, que fornece melhores soluções sem signi�cativo aumento no tempo de

execução. Seria interessante, portanto, se a heurística de Prim pudesse substituir DNH

na implementação da busca por nós-chaves. Isso pode de fato ser feito, uma vez que o

seguinte teorema é válido:

Teorema 2 Dado um grafo G = (V;E) e um conjunto de vértices X � V , o custo de

qualquer solução fornecida pela heurística de Prim sobre G usando X como um conjunto

de terminais será menor ou igual ao custo de uma árvore geradora mínima do subgrafo

de D(G) induzido por X, sendo D(G) o grafo de distâncias associado a G.

Prova Seja M a árvore geradora mínima do grafo de distâncias e S uma solução obtida

pela heurística de Prim. Seja e = (v; w) uma aresta (no grafo de distâncias) em M e

suponha, sem perda de generalidade, que v é adicionado à solução S pelo algoritmo de

Prim antes de w (observe que ambos são terminais). Para provar que c(S) � c(M),

basta provar que o custo da adição de w à árvore pela heurística de Prim é menor que

ou igual a c(e), para toda aresta e de M . Por hipótese, a heurística adiciona v a S antes

de w. Conseqüentemente, na iteração em que w foi adicionado, v era uma das raízes do

algoritmo de Dijkstra executado e, portanto, a distância de w à árvore era no máximo

Page 66: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 54

igual a c(e) nesse momento. Como a adição de w a S se faz pela inclusão do caminho

mais curto entre eles, o comprimento desse caminho não pode ser maior que c(e), o que

conclui a prova. 2

A Figura 4.1 mostra um exemplo em que a heurística de Prim encontra uma solução

de valor inferior ao da árvore geradora mínima do subgrafo induzido pelo conjunto de

terminais. No exemplo, a árvore geradora tem valor 23, enquanto a solução fornecida

pela heurística vale 22. Lembre-se de que, no caso da busca por nós-chaves, a heurística

é aplicada não sobre o conjunto de terminais, mas sobre o de nós cruciais (que inclui

também os nós-chaves).

�L

L

L

L

L

L

L

L

L

L

L

L

Lru u

u

5 5

13 13

12

u

v

w

x

grafo original

�L

L

L

L

L

L

L

L

L

L

L

L

Lu u

u

10

13

u

v x

árvore geradora mínima do

grafo de distâncias para u, v e x

�L

L

L

L

L

L

L

L

L

L

L

L

Lru u

u

5 5

12

u

v

w

x

solução fornecida pela SPH

(usando v ou x como raiz)

Figura 4.1: Comparação entre a heurística de Prim e árvore geradora do grafo de distâncias

Nos experimentos computacionais apresentados neste e nos próximos capítulos, o méto-

do de fato implementado como sub-rotina da busca local é o de Prim. Além disso, para

cada vizinho, calcula-se também a árvore geradora mínima do subgrafo de G induzido

pelos vértices da solução construtiva (obtida pela heurística de Prim). Esse procedimento

pode melhorar o valor da solução inicialmente calculada. Por �m, faz-se um pruning da

árvore obtida, que consiste na remoção de todos os não-terminais que são folhas. Nesse

ponto, permite-se até a remoção de vértices candidatos a nós-chaves, interpretados como

terminais na execução da heurística de Prim. A combinação da heurística de Prim com

o cálculo da árvore geradora do subgrafo e sua posterior poda contribui para que vizin-

hos de melhor qualidade sejam encontrados, principalmente quando a solução inicial está

distante do valor ótimo.

Conforme já mencionado, uma característica dessa busca local é o fato de que não há

controle sobre a estrutura da solução vizinha obtida. A heurística de Prim recebe como

entrada o grafo original e um conjunto de �pseudoterminais� (composto pelos terminais

e pelo conjunto K de nós-chaves candidatos). Na solução obtida pelo algoritmo de Prim

sobre essa entrada, haverá um conjunto K de nós não-terminais com grau maior que três,

os nós-chaves. Não necessariamente é verdade que K

0

= K. Pode-se assegurar que os

vértices de K farão parte da solução obtida, mas nada garante que todos terão grau maior

Page 67: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 55

que dois. Além disso, pode haver em K

0

vértices que não pertencem a K. Isso não deve

ser entendido como uma de�ciência, mas como uma característica da busca local.

Na implementação, adotou-se a seguinte convenção. Se uma solução vizinha S

v

tiver

valor menor ou igual ao da solução corrente S, S

v

passa a ser a solução corrente. Para

se chegar a S

v

, calculou-se uma árvore associada a um determinado conjunto de nós-

chaves candidatos, que, como se viu, podem ser diferentes dos nós-chaves que de fato

�aparecem� em S

v

. Quando S

v

se torna a solução corrente, passa-se também a considerar

como corrente o conjunto real de nós-chaves.

4.3.5 Estratégias Híbridas

A combinação das vizinhanças propostas permite a criação de estratégias híbridas de

busca local, mais poderosas que os métodos individuais. A idéia é submeter as soluções

encontradas por um método a outro. Mais precisamente, a busca híbrida consiste em

executar um método de busca local até que ele não tenha mais capacidade de melhorar

a solução; em seguida aplica-se sobre a solução resultante outro método, também até o

seu limite; e assim sucessivamente. É interessante aplicar esse método de forma circular:

depois de aplicados todos os métodos, retorna-se ao primeiro. Com isso, pode-se melhorar

ainda mais o valor da função objetivo. Nesse caso, interrompe-se o algoritmo quando todos

os métodos falharem consecutivamente.

Repare que o resultado fornecido pela estratégia híbrida jamais será pior que o forneci-

do pelo primeiro dos métodos de busca local aplicados (por outro lado, ela também jamais

será mais rápida que ele). No entanto, nada garante que a solução fornecida será melhor

que a obtida pela aplicação exclusiva de algum dos demais métodos diretamente sobre

a solução original. Em geral, contudo, é razoável esperar que os resultados fornecidos

pelo método híbrido tenham qualidade superior aos fornecidos por cada um dos outros

métodos isoladamente. A�nal, na verdade está-se utilizando uma vizinhança mais ampla.

A combinação de diversas buscas locais é relativamente comum em metaeurísticas.

Para o caso especí�co do problema de Steiner, há pelo menos um caso em que isso foi

feito: em [38], Martins et al. apresentam um GRASP paralelo que usa uma combinação

das buscas por nós de Steiner e por caminhos-chaves.

4.4 Resultados Experimentais

Esta seção apresenta uma análise comparativa experimental de diversas estratégias de

busca local. São testados de forma individual os três métodos propostos ao longo do

capítulo: as buscas por nós de Steiner (N ), por caminhos-chaves (P, do inglês key-paths)

e nós-chaves (K, do inglês key-nodes). Estudaram-se ainda algumas estratégias híbridas

formados a partir da composição desses métodos: NP, PN, KNP, KPN, NPK e PNK.

O rótulo de cada método híbrido é formado pelos símbolos que representam os métodos

Page 68: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 56

individuais utilizados, na ordem em que são aplicados.

Como no caso das heurísticas construtivas, há dois aspectos básicos a se analisar:

a qualidade das soluções fornecidas e o tempo de execução. Assim sendo, o estudo do

desempenho relativo dos métodos é feito nos mesmos moldes do estudo apresentado no

capítulo anterior.

As estratégias de busca local foram testadas para todas as instâncias apresentadas

na Seção 2.4.2. Para as classes OR-Library e VLSI, foram utilizadas as instâncias pré-

processadas. Os tempos mencionados nesta seção, obtidos num AMD K6-2 de 350 MHz,

não incluem os tempos de pré-processamento, apresentados separadamente no Apêndice

A. Fixada uma instância, garantiu-se que todos os métodos de busca local fossem testados

sobre exatamente a mesma solução inicial, construída pelo algoritmo de Prim.

Para cada classe de instâncias, a Tabela 4.1 compara a qualidade de das soluções

fornecidas por quatro estratégias de busca local (N, P, NP e PN ) utilizando as medidas

introduzidas na Seção 3.6.1. Além disso, a mesma tabela compara os tempo de execução

dessas estratégias; a última coluna mostra o tempo médio obtido por cada método em

relação aos tempos obtidos pelo método-base (N, nesse caso).

Instâncias para as quais todos os métodos encontraram o mesmo valor foram conside-

radas apenas para o cálculo do tempo relativo médio. As três primeiras medidas (dr%,

rank e melhor) foram feitas com base apenas nas demais instâncias (o número de ins-

tâncias efetivamente consideradas em cada caso é mostrado na primeira coluna da tabela,

junto ao nome de cada classe).

A Tabela 4.2 tem a mesma estrutura, mas compara as estratégias NP, K, KNP, KPN,

NPK e PNK. A estratégia NP é utilizado como base para o cálculo dos tempos relativos

nesse caso.

Fez-se a divisão dos métodos em dois grupos para a comparação porque tanto a busca

K quanto as estratégias híbridas que a utilizam são de uma a duas ordens de grandeza

mais lentas que as demais buscas. Apesar de os maiores tempos de execução em geral

levarem a soluções de melhor qualidade, há situações em que utilizar a busca K pode

não ser interessante, o que justi�ca uma comparação mais pormenorizada das estratégias

alternativas.

A existência de um elemento comum aos dois grupos, a busca NP, permite que estraté-

gias de grupos distintos sejam convenientemente comparadas. O fato de que estratégias

que utilizam a busca K são signi�cativamente mais lentas pode ser comprovado utilizando-

se justamente o método NP : a Tabela 4.1 mostra que ele pode ser executado em tempos

próximos aos dos métodos N, P e PN ; por outro lado, na Tabela 4.2 observa-se que os

métodos que utilizam a busca por nós-chaves são pelo menos 20 vezes mais lentos.

Também podem ser utilizadas para comparar os diversos métodos a Tabela 4.3 e a

Tabela 4.4. A primeira mostra, para cada uma das séries de instâncias estudadas, o

desvio percentual médio das soluções obtidas pelas diferentes estratégias de busca lo-

cal em relação às melhores soluções primais conhecidas. A segunda tabela mostra os

Page 69: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 57

classe estratégia dr% rank melhor tempo rel.

N 1.171 2.480 117 1.000

Incidência P 14.797 3.436 56 1.014

(320 instâncias) NP 0.449 1.884 196 1.644

PN 0.573 1.961 187 2.139

N 0.798 2.707 14 1.000

OR-Library P 0.334 3.328 6 0.502

(29 instâncias) NP 0.068 1.931 22 1.566

PN 0.113 2.034 22 1.502

N 0.568 2.141 22 1.000

PUC P 4.284 3.946 0 0.370

(46 instâncias) NP 0.433 1.913 26 1.326

PN 0.477 2.000 25 1.600

N 1.162 3.622 6 1.000

VLSI P 0.361 2.592 18 0.795

(49 instâncias) NP 0.128 1.888 35 2.140

PN 0.105 1.898 32 1.820

N 1.083 2.586 159 1.000

Total P 11.170 3.389 80 0.879

(444 instâncias) NP 0.387 1.891 279 1.675

PN 0.481 1.963 266 1.988

Tabela 4.1: Estratégias formadas pelas buscas por nós de Steiner e caminhos-chaves

Page 70: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 58

classe estratégia dr% rank melhor tempo rel.

NP 1.556 4.148 73 1.000

K 1.587 4.365 76 22.643

Incidência KNP 0.795 3.089 152 27.610

(337 instâncias) KPN 0.763 3.049 156 27.719

NPK 0.921 3.166 154 23.154

PNK 0.862 3.147 148 23.017

NP 1.239 5.354 3 1.000

K 0.037 3.229 20 77.472

OR-Library KNP 0.028 2.979 22 78.047

(24 instâncias) KPN 0.028 3.000 21 76.323

NPK 0.061 3.542 16 77.538

PNK 0.011 2.896 22 76.348

NP 1.731 4.564 5 1.000

K 2.268 4.894 5 19.506

PUC KNP 0.613 2.926 13 29.953

(47 instâncias) KPN 0.615 2.851 18 28.024

NPK 0.526 2.766 20 23.024

PNK 0.645 3.000 16 24.045

NP 0.708 5.407 4 1.000

K 0.160 3.477 22 20.930

VLSI KNP 0.112 3.163 24 22.243

(43 instâncias) KPN 0.084 3.163 25 21.776

NPK 0.134 2.988 29 22.838

PNK 0.113 2.802 31 21.427

NP 1.476 4.376 85 1.000

K 1.439 4.275 123 27.524

Total KNP 0.670 3.073 211 32.049

(451 instâncias) KPN 0.643 3.037 220 31.726

NPK 0.759 3.127 219 28.436

PNK 0.722 3.085 217 28.127

Tabela 4.2: Estratégias que utilizam a busca por nós-chaves

Page 71: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 59

tempos de execução médios (em segundos) de cada estratégia. (Conforme já observa-

do na Seção 3.6.2, deve-se ter cuidado ao analisar tabelas como essa, já que os valores

mostrados são de�nidos basicamente pelo comportamento de cada método para as maiores

instâncias.) Em ambas as tabelas, fez-se também a divisão dos métodos em dois grupos,

determinados pelo fato de se utilizar ou não a busca por nós-chaves. Os melhores valores

obtidos em cada grupo estão destacados em negrito. As medidas relativas à heurística

construtiva (Prim) também são apresentados nas tabelas, como referência.

série desvio percentual médio

Prim N P NP PN K KNP KPN NPK PNK

i080 16.898 3.466 11.637 2.934 3.289 3.235 2.521 2.467 2.366 2.340

i160 19.592 3.608 14.723 3.178 3.231 3.030 2.392 2.386 2.655 2.592

i320 20.558 3.879 16.397 3.264 3.361 3.288 2.624 2.613 2.831 2.966

i640

21.937 4.241 17.216 3.441 3.345 3.385 2.655 2.613 2.769 2.501

c 1.359 0.182 0.272 0.146 0.227 0.035 0.035 0.028 0.017 0.005

d 1.749 0.748 0.831 0.620 0.672 0.008 0 0.008 0.041 0

e 2.826 1.778 0.897 0.825 0.761 0.030 0.026 0.026 0.045 0.035

bip

15.068 7.382 10.930 7.122 6.461 6.643 4.678 4.771 4.566 4.749

cc

9.674 3.687 6.684 3.534 3.977 3.797 2.792 2.769 2.569 2.951

hc

8.472 2.549 7.059 2.549 2.329 4.272 1.821 1.806 2.023 1.585

alue 2.355 1.376 0.769 0.540 0.674 0.237 0.192 0.191 0.175 0.185

alut 2.547 1.753 0.761 0.802 0.630 0.175 0.164 0.174 0.182 0.195

diw 1.207 0.823 0.446 0.424 0.401 0.050 0.050 0.050 0.104 0.024

dmxa 2.157 1.460 0.481 0.433 0.399 0.170 0.170 0.170 0.292 0.227

gap 2.585 1.160 0.554 0.340 0.181 0.182 0 0 0.231 0

msm 1.615 0.741 0.593 0.372 0.318 0.015 0.015 0.015 0.008 0.099

taq 2.199 1.063 0.644 0.395 0.485 0.394 0.370 0.241 0.181 0.182

Tabela 4.3: Desvios percentuais médios em relação às melhores soluções conhecidas

Com base no que a apresentam as Tabelas 4.1 a 4.4, é possível efetuar uma análise

pormenorizada do comportamento dos diversos algoritmos.

Estratégias mais rápidas (N e P) Inicialmente, considere apenas as estratégias

mais rápidas, que não utilizam a busca K. Comparando-se as duas formas �puras� de

busca local nesse grupo (P e N ), veri�ca-se que a busca baseada em nós de Steiner tende

a obter soluções de melhor qualidade para grafos densos ou com muitos terminais. Para

instâncias de incidência, os resultados da busca por nós foram sensivelmente melhores

que os obtidos pela busca por caminhos-chaves. Para as instâncias VLSI e a série e da

OR-Library (instâncias esparsas após o pré-processamento), a busca P é a melhor. Os

caminhos-chaves nesses casos são longos (possuem mais arestas), o que favorece a busca

P. Além disso, a busca N pouco tem a fazer, já que raramente um único nó de Steiner

pode ser adicionado ou retirado da solução sem torná-la inviável.

Quanto ao tempo de execução, o que se observa é que a busca P depende menos

fortemente do número de vértices. Para instâncias muito esparsas, ela é a mais rápida;

Page 72: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 60

série tempos médios de execução (em segundos)

Prim N P NP PN K KNP KPN NPK PNK

i080 0.0011 0.008 0.007 0.012 0.016 0.06 0.08 0.08 0.06 0.07

i160 0.0049 0.033 0.040 0.050 0.087 0.41 0.60 0.61 0.41 0.46

i320 0.0234 0.147 0.287 0.234 0.509 3.25 4.53 4.54 3.36 3.51

i640 0.1158 0.714 2.383 1.185 3.493 27.79 47.24 45.73 25.81 28.26

c 0.0012 0.009 0.003 0.012 0.010 0.45 0.45 0.46 0.45 0.46

d 0.0033 0.038 0.010 0.058 0.044 2.82 2.72 2.79 2.44 2.56

e 0.0110 0.286 0.053 0.416 0.249 21.23 21.47 20.99 22.33 20.93

bip 0.0355 2.797 0.456 3.722 4.222 98.66 119.22 123.01 92.38 132.68

cc 0.0460 6.070 0.264 7.726 6.891 69.69 162.72 145.97 144.31 104.96

hc 0.0350 9.534 1.415 9.790 8.747 110.83 136.69 130.55 116.73 165.88

alue 0.0120 6.720 1.204 23.669 10.079 237.66 317.15 325.38 370.45 345.81

alut 0.0185 8.265 1.614 12.013 17.952 403.54 796.84 526.23 515.34 344.95

diw 0.0024 0.034 0.021 0.075 0.047 5.87 5.71 5.67 5.32 6.40

dmxa 0.0003 0.002 0.002 0.006 0.004 0.11 0.11 0.11 0.08 0.08

gap 0.0014 0.024 0.014 0.054 0.056 5.75 5.73 5.79 6.07 6.07

msm 0.0007 0.008 0.005 0.016 0.015 0.65 0.64 0.64 0.59 0.61

taq 0.0032 0.192 0.060 0.375 0.294 8.53 10.02 8.56 8.90 8.45

Tabela 4.4: Tempos médios de execução

para mais densas (como as de incidência) a busca N é a mais rápida. De qualquer forma,

observa-se que a ordem de grandeza dos tempos de execução é, em média, a mesma para

as instâncias testadas.

Conforme esperado, as buscas híbridas (NP e PN ) levam a soluções de melhor quali-

dade quando comparadas aos métodos �puros�. Conforme mostram as Tabelas 4.1 e 4.3,

na média ambas as buscas híbridas obtêm resultados melhores que qualquer dos métodos

individuais, mesmo que o �pior� método seja executado primeiro. Ainda assim, os tempos

de execução das buscas híbridas não são consideravelmente muito maiores que os das bus-

cas individuais. Isso indica que, na prática, cada um dos métodos é executado um número

pequeno de vezes: o ótimo local �híbrido� é alcançado logo nas primeiras iterações.

Quando as buscas NP e PN são comparadas entre si, não se observam diferenças

signi�cativas na qualidade das soluções obtidas. Ora uma das estratégias é melhor, ora a

outra. Já a diferença no tempo de execução pode ser expressiva. Observe por exemplo as

séries i640, e e alue na Tabela 4.4: nesses casos, uma estratégia pode requerer até o dobro

do tempo da outra, em média. A melhor política para garantir um bom desempenho

parece ser executar primeiro o método mais rápido, até porque os demais jamais serão

executados mais vezes que ele.

Estratégias que utilizam a busca por nós-chaves Conforme já mencionado, a busca

K é consideravelmente mais lenta que as buscas N e P. E a diferença é grande, freqüen-

temente de uma ou duas ordens de grandeza. Em contrapartida, as soluções encontradas

pela busca K foram, em todas as séries de instâncias, melhores (na média) que soluções

Page 73: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 61

encontradas pelas buscas N ou P. A superioridade da busca K é mais evidente nas classes

VLSI e OR-Library, conforme mostram tanto a Tabela 4.1 quanto a Tabela 4.3.

Apesar de menos �poderosas�, as buscas N e P podem contribuir para melhorar o

desempenho da busca K. Os ganhos obtidos quando se utiliza uma estratégia híbrida

(NPK, PNK, KNP, KPN ) são mais evidentes justamente nos casos em que a busca K

não é tão superior às demais: nas classes Incidência e PUC (a Tabela 4.2 deixa clara

essa diferença). Os quatro métodos híbridos estudados fornecem soluções de qualidade

semelhante: não é evidente a superioridade de nenhum dos métodos sobre os demais.

Já quando se considera o tempo de execução, nota-se uma diferença entre os métodos,

principalmente nas classes Incidência e PUC. Iniciar a busca híbrida com os métodos mais

rápidos (N ou P) parece ser mais vantajoso que iniciá-la com a busca K. Para algumas

séries, as estratégias NPK e PNK são até mais rápidos que o método K �puro�, conforme

mostram os valores em negrito na Tabela 4.2.

4.5 Conclusão

A Tabela 4.3 con�rma a a�rmação feita no início deste capítulo: métodos de busca local

podem melhorar signi�cativamente soluções produzidas por heurísticas construtivas. Para

várias das séries testadas, é possível reduzir o desvio relativo médio em uma ordem de

grandeza. Tome o caso da série i320: um desvio de 20.5% é reduzido a 3.2% pela busca

NP e a 2.6% pela busca KPN. Na série d, o valor reduz-se de 1.7% para zero pela ação

das estratégias KNP e PNK, o que signi�ca que todos os ótimos da série são encontrados.

Há casos em que a redução é relativamente mais modesta, como no caso das instâncias

bip. Mesmo assim, os ganhos são signi�cativos.

Naturalmente, as soluções de melhor qualidade são obtidas às custas de um aumento

no tempo de execução do algortimo. Mesmo as buscas mais rápidas são pelo menos

uma ordem de grandeza mais lentas que a heurística construtiva. As buscas mais caras,

baseadas na busca K, podem chegar a ser quatro ordens de grandeza mais lentas. Ainda

assim, em situações em que a qualidade das soluções é o mais importante, aumentos dessa

ordem (ou ainda maiores) no tempo de execução são toleráveis.

De qualquer forma, as buscas podem ser aceleradas se forem feitos alguns ajustes na

implementação. Na implementação da busca N, por exemplo, seria interessante man-

ter um controle das componentes biconexas do subgrafo induzido pela solução corrente.

Isso permite descartar vértices candidatos a remoção sem que seja necessário calcular

explicitamente o vizinho. A busca K, no entanto, parece ser a que tem maior espaço

para acelerações. Em particular, seria interessante buscar uma implementação em que

as operações realizadas para a construção de um vizinho pudessem ser aproveitadas para

a computação do vizinho seguinte. Mais concretamente, pode-se conceber uma imple-

mentação baseada na heurística DNH em que o diagrama de Voronoi (cuja construção

constitui primeiro passo da heurística) fosse apenas atualizado de uma iteração para ou-

Page 74: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 4. BUSCA LOCAL 62

tra. As possibilidades de implementação são muitas e merecem estudo mais aprofundado.

A�nal, conforme se pôde observar, é excelente a qualidade das soluções fornecidas pela

busca K ; qualquer aceleração seria muito bem-vinda.

Page 75: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Capítulo 5

Metaeurísticas

As estratégias de busca local apresentadas no capítulo anterior fornecem soluções de qua-

lidade média muito superior às obtidas por heurísticas construtivas. Há situações, no

entanto, em que mesmo esses resultados são insu�cientes. Apela-se então para metaeurís-

ticas, heurísticas mais elaboradas normalmente formadas a partir da composição de ele-

mentos de heurísticas mais simples. Uma característica importante de metaeurísticas

é uma exploração mais completa e cuidadosa do espaço de soluções. Um estudo sobre

metaeurísticas para problemas de otimização combinatória em geral pode ser encontrado

em [1].

Entre as metaeurísticas mais tradicionais, há na literatura exemplos de implementações

para o problema de Steiner em grafos: algoritmos genéticos [18, 30], simulated annealing

[11], busca tabu [3, 21, 49], GRASP [38], entre outras.

Este capítulo descreve HGP+PR, uma nova metaeurística para o problema de Steiner

em grafos. Trata-se de um GRASP híbrido baseado em perturbações com religamento

(path-relinking) adaptativo. Esse método foi introduzido em [50], artigo escrito em co-

autoria com Celso C. Ribeiro e Eduardo Uchoa.

A estrutura básica do algoritmo é descrita na Seção 5.1. Seus elementos constitu-

intes são discutidos mais detalhadamente nas Seções 5.2 a 5.5. Resultados experimen-

tais, incluindo comparações do algoritmo com outras metaeurísticas, são apresentados na

Seção 5.6. Por �m, na Seção 5.7 é feita uma análise das características mais importantes

do algoritmo.

5.1 HGP+PR: Estrutura Básica

A metaeurística aqui apresentada para a resolução do problema de Steiner em grafos é

semelhante a um GRASP [19] (Greedy Randomized Adaptive Search Procedure, ou Pro-

cedimento Guloso Aleatorizado Adaptativo de Busca). Trata-se de um método muito

63

Page 76: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 64

simples, que tem como principal parâmetro de entrada o número de iterações. Em cada

iteração de um GRASP, cria-se uma solução construtiva e, em seguida, aplica-se sobre ela

um método de busca local. Considera-se como solução da metaeurística a melhor solução

encontrada ao longo de todas as iterações.

Repare que, se a mesma solução construtiva fosse encontrada em todas as iterações do

algoritmo, também os ótimos locais seriam semelhantes. Assim, um importante aspecto

do GRASP (em sua forma original) é o uso de um heurística construtiva aleatorizada.

Um algoritmo guloso �puro� toma sempre a decisão que parece ser mais vantajosa em

um determinado instante de sua execução; em versões aleatorizadas, a ação tomada em

cada ponto é sorteada entre uma lista de alternativas mais promissoras. Quanto maior o

tamanho da lista, maior será o grau de aleatorização do algoritmo.

A metaeurística aqui proposta tem a mesma estrutura básica de um GRASP: em cada

iteração, gera-se uma solução construtiva com aleatorização e executa-se um procedimento

de busca local. A diferença básica está justamente na forma de garantir a variabilidade

das soluções construtivas. No GRASP original, os elementos de aleatorização são inseridos

no código do algoritmo construtivo. O que se propõe aqui é, em lugar disso, alterar a

própria instância em cada iteração, adicionando-se perturbações aos pesos das arestas. A

heurística gulosa é aplicada sobre o grafo com pesos perturbados; para a busca local, os

pesos originais são restaurados.

A principal vantagem da aleatorização por perturbações é a facilidade de implemen-

tação. Além disso, ela permite que de forma simples sejam incorporados ao algoritmo

conceitos normalmente utilizados com sucesso em outras metaeurísticas. Combinam-se

diferentes funções de perturbação de forma a que se alternem elementos de intensi�cação

(exploração mais pormenorizadas de regiões promissoras do espaço de busca) e de diver-

si�cação (exploração de regiões menos conhecidas do espaço de busca). Isso caracteriza

o uso de oscilação estratégica, originalmente utilizada em métodos de busca tabu.

O algoritmo também utiliza perturbações em uma etapa de pós-otimização. As me-

lhores soluções criadas pelo GRASP são utilizadas para compor um pool de soluções de

elite. Após a execução de todas as iterações do GRASP, essas soluções são combinadas

entre si, numa técnica conhecida como path-relinking (religamento), implementado tanto

da forma usual (com um algoritmo especi�camente criado para tal �m) quando de forma

aleatorizada, baseada no uso de perturbações.

Em resumo, a principal característica da metaeurística proposta é permitir a inte-

gração, a partir de um único conceito (perturbações), de diversos elementos utilizados

em outras metaeurísticas (tais como a geração de soluções gulosas aleatorizadas, inten-

si�cação, diversi�cação, oscilação estratégica e religamento). Conforme já mencionado,

será usada a sigla �HGP+PR� (Hybrid GRASP with Perturbations and Path-Reliking) em

referências a essa metaeurística. �HGP� representa as versões do algoritmo sem a etapa

de pós-otimização (religamento).

A Figura 5.1 mostra um pseudocódigo simpli�cado do algoritmo HGP+PR.

Page 77: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 65

01 function HGP+PR {

02 for k = 1 to max_it do {

03 aplique uma estratégia de perturbação sobre os pesos originais;

04 construa uma solução gulosa usando os pesos perturbados;

05 aplique busca local sobre a solução obtida (usando pesos originais);

06 atualize o pool de soluções de elite;

07 }

08 aplique path-relinking sobre o pool de soluções de elite;

09 return (melhor solução encontrada);

10 }

Figura 5.1: Pseudocódigo do GRASP híbrido com perturbações e religamento

Nas próximas seções, cada um dos componentes do algoritmo será analisado sepa-

radamente. Na Seção 5.2, discute-se a escolha das heurísticas construtivas utilizadas. A

Seção 5.3 trata das estratégias de busca local. O uso de perturbações para aleatorização

das heurísticas construtivas é analisado na Seção 5.4. A Seção 5.5 discute as estratégias

de religamento utilizadas.

5.2 Heurísticas Construtivas

Uma das principais vantagens do uso de perturbações é o fato de que elas permitem a

aplicação direta de qualquer heurística construtiva. Em um GRASP �puro�, toda heurís-

tica construtiva utilizada deve ter um componente de aleatorização inserido no próprio

algoritmo, o que requer um esforço adicional de implementação. A criação de uma lista

de candidatos muitas vezes altera signi�cativamente a estrutura dos algoritmos utilizados.

No lugar de um heap, por exemplo, pode ser necessário usar uma árvore binária de busca

para armazenar os elementos mais promissores.

Outra di�culdade encontrada na aleatorização de algoritmos construtivos está no fato

de que muitos deles não possuem uma aleatorização �natural�. A criação da lista de can-

didatos pode simplesmente adiar a inserção de elementos originalmente prioritários, sem

alterar signi�cativamente a estrutura das soluções obtidas. Isso compromete seriamente a

e�ciência do GRASP, que depende da aleatorização para explorar diferentes regiões do es-

paço de busca. Uma alternativa para superar esse problema é criar uma lista de candidatos

excepcionalmente grande. Apesar de essa medida de fato aumentar a variabilidade, ela

diminui a qualidade das soluções obtidas.

Numa tentativa de aleatorização da heurística de Prim para o problema de Steiner em

grafos, por exemplo, as di�culdades descritas acima podem ser claramente observadas. A

implementação descrita na Seção 3.3 não pode ser utilizada, já que ela supõe que, uma vez

retirado do heap um nó terminal, o caminho que o liga à árvore será incorporado à solução.

Page 78: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 66

Na versão aleatorizada, isso não necessariamente é verdade. Caminhos �distantes� seriam

adicionados previamente à árvore, possivelmente diminuindo a distância de alguns vértices

já retirados do heap à árvore. Um heap provavelmente deixaria de ser a estrutura mais

adequada para manter as alternativas mais promissoras.

Quando se utiliza a estratégia baseada em perturbações, esses problemas desaparecem.

Qualquer heurística construtiva pode ser utilizada até mesmo como uma �caixa-preta�.

Nenhuma alteração na sua estrutura é necessária. A variabilidade é garantida pela per-

turbação do GRASP. Basta ajustar a intensidade das perturbações para aumentar ou

diminuir a variabilidade das soluções obtidas.

Para deixar clara a �exibilidade de uso de diferentes métodos construtivos na metaeu-

rística, foram utilizadas cinco das heurísticas descritas no Capítulo 3: Prim (implemen-

tação direta), Kruskal (implementação com heap de nós), Bor·vka, DNHz e Multispan.

Os métodos são utilizados nessa ordem nas primeiras cinco iterações: Prim na primeira,

Kruskal na segunda, etc. Em cada uma das iterações posteriores, um dos métodos é

escolhido aleatoriamente.

5.3 Busca Local

Assim como ocorre no caso das heurísticas construtivas, há total liberdade de escolha em

relação à estratégia de busca local utilizada em cada iteração. Os três métodos básicos

(P, N e K ) apresentados no Capítulo 4 podem ser utilizados, bem como qualquer outro

método que se venha a propor. Evidentemente, também métodos híbridos podem ser

aplicados. Essa facilidade de substituição dos diversos componentes é uma das mais

importantes características da metaeurística proposta.

Para a maior parte dos experimentos apresentados neste capítulo, optou-se por utilizar

as buscas NP e PN : uma delas é escolhida aleatoriamente em cada iteração. Conforme

mostra a Seção 4.4, as soluções fornecidas por esses métodos (muito semelhantes entre

si) têm desempenho superior aos métodos N (busca por nós de Steiner) e P (busca por

vértices-chaves), sem que isso signi�que tempos de execução expressivamente maiores. Es-

tratégias de busca local utilizando a busca por nós-chaves (método K ) produzem soluções

de melhor qualidade, mas com tempo de execução consideravelmente maior.

Conforme mencionado na Seção 4.3.1, todos os procedimentos de busca local testados

percorrem circularmente uma lista de vértices que é uma permutação aleatória de seus

rótulos originais, recalculada no início da execução de cada método. Isso signi�ca que, no

HGP+PR, também os procedimentos de busca local têm um componente de aleatorização,

que contribui para melhorar a qualidade das soluções fornecidas pela metaeurística.

Page 79: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 67

5.4 Estratégias de Perturbação

Foram utilizadas três funções de aleatorização distintas. Em todos os casos, o peso da ares-

ta e na i-ésima iteração do algoritmo (c

i

(e)) é escolhido aleatoriamente com distribuição

uniforme entre c(e) (o peso original) e r

i

(e) � c(e), sendo o coe�ciente r

i

(e) justamente o

que diferencia os três métodos. No cálculo de r

i

(e), dois dos métodos utilizam o número

de soluções (ótimos locais) em que a aresta e aparece antes da iteração i; esse número

é representado por t

i�1

(e). Claramente, 0 � t

i�1

(e) � i. A Tabela 5.1 mostra como o

coe�ciente r

i

(e) é calculado para os três métodos de aleatorização.

método efeito coeficiente (r

i

(e))

D diversi�cação 1:25 + 0:75 � t

i�1

(e)=(i� 1)

I intensi�cação 2� 0:75 � t

i�1

(e)=(i� 1)

U uniforme 2

Tabela 5.1: Coe�cientes máximos para aleatorização

No método D, o valor de r

i

(e) tende a ser maior para arestas que apareceram mais

freqüentemente nas soluções previamente encontradas. Com isso, esse método tende a es-

timular a diversi�cação das soluções. O método I, ao contrário, penaliza as arestas pouco

utilizadas em iterações anteriores, favorecendo as mais utilizadas. Trata-se, portanto,

de uma estratégia de intensi�cação, concentrando a busca em regiões mais promissoras

do espaço de soluções. O terceiro método, U , penaliza as arestas de forma uniforme,

independentemente de sua utilização em iterações anteriores.

Evidentemente, como se trata de um GRASP, tanto a diversi�cação quanto a intensi�-

cação devem ser feitas mantendo-se a garantia de aleatorização das soluções construtivas.

Por isso, o valor mínimo de r

i

(e) jamais é inferior a 1.25 nos métodos I e D: garante-se

a existência de um intervalo dentro do qual o peso de cada aresta é escolhido. As pena-

lizações não determinam diretamente o custo penalizado da aresta, elas atuam sobre o

conjunto de valores que o custo pode assumir.

Escolha dos métodos Em cada iteração da metaeurística, pode-se utilizar qualquer

dos métodos de perturbação descritos acima (I, D ou U), bem como qualquer outro

que se venha a conceber. Conforme já mencionado, os métodos de aleatorização I e D

exploram dois conceitos bastante utilizados em metaeurísticas elaboradas: intensi�cação e

diversi�cação. Quando as técnicas são empregadas alternadamente, o algoritmo como um

todo utiliza uma variante de oscilação estratégica, comum em implementações de busca

tabu. A oscilação estratégica é de�nida justamente como a alternância entre fases de

intensi�cação e de diversi�cação na exploração do espaço de busca durante a execução de

um algoritmo. Repare que, no caso do HGP, isso é feito de maneira muito simples, por

meio da manipulação dos pesos das arestas.

Page 80: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 68

Ao menos na primeira iteração do HGP, é conveniente não se utilizar nenhuma per-

turbação, até porque o valor de t

0

não está de�nido. Na implementação realizada, as

h primeiras iterações são executadas sem perturbação, sendo h o número de heurísti-

cas construtivas utilizadas. O próprio fato de se utilizarem diferentes heurísticas induz

a variabilidade das soluções nas iterações iniciais. Em cada uma das demais iterações,

os métodos da estratégia utilizada são aplicados alternadamente, sendo as heurísticas

construtivas escolhidas aleatoriamente.

Essa estratégia torna-se mais clara com um exemplo. Suponha que se executem 128

iterações de um HGP com duas heurísticas construtivas (H

1

e H

2

) e três métodos de

perturbação (I, D e U). Inicialmente, cada método construtivo é aplicado sem qualquer

perturbação. Na primeira iteração, o método H

1

é aplicado; na segunda, H

2

. A partir da

terceira iteração, os métodos de perturbação (I, D e U) são utilizados alternadamente: I

na terceira iteração, D na quarta, U na quinta, I na sexta, D na sétima, etc. A heurística

construtiva aplicada em cada iteração (a partir da terceira) é escolhida aleatoriamente,

com igual probabilidade para cada uma delas. Com isso, espera-se que todas as combi-

nações entre heurísticas construtivas e métodos de perturbação sejam tentadas.

Nos testes apresentados na Seção 5.6.1, são utilizadas cinco heurísticas construtivas

(Prim, Kruskal, Bor·vka, DNHz e Multispan) e três métodos de perturbação (I, D e U).

5.5 Religamento (Path-relinking)

O objetivo primário de umGRASP é encontrar uma solução de boa qualidade. Entretanto,

no processo de busca pela melhor solução, são geradas diversas boas soluções, ótimos locais

em relação aos métodos de busca local utilizados. Tipicamente, mesmo soluções de valores

muito próximos podem ter estruturas muito diferentes.

O método de pós-otimização proposto tenta combinar algumas das soluções obtidas

pelo HGP na tentativa de aproveitar as melhores características de cada uma delas. As

soluções utilizadas no pós-processamento são chamadas de soluções de elite, um conceito

muito utilizado em métodos de busca tabu (como [3], por exemplo). Duas a duas, as

soluções de elite são utilizadas para obter outras soluções, em um processo conhecido

como path-relinking (religamento). Foram estudadas duas técnicas de religamento: uma

baseada em movimentos de inserção e remoção de vértices de Steiner (movimentos com-

plementares) e outra baseada em perturbações.

Na verdade, o método de pós-otimização implementado não se limita a fazer a combi-

nação entre as melhores soluções obtidas pelo HGP. Esse é apenas o seu primeiro passo.

As soluções resultantes da combinação constituem uma segunda geração de soluções de

elite (a primeira é constituída por soluções geradas nas iterações do HGP). Elementos da

segunda geração podem ser combinados novamente entre si, gerando uma terceira geração,

e assim sucessivamente. Pode-se dizer que o procedimento tem elementos de um algoritmo

genético: cada conjunto de soluções de elite pode ser entendido como uma população.

Page 81: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 69

A Seção 5.5.1 explica em detalhes a construção de cada geração de soluções de elite.

Na Seção 5.5.2, discutem-se os métodos implementados para efetuar a combinação de um

par de soluções. A Seção 5.5.3 discute a questão dos critérios de parada para a parte

�genética� do algoritmo.

5.5.1 Soluções de Elite

A lista de soluções de elite (L) contém as soluções de melhor qualidade (menor valor)

encontradas pelo HGP até a iteração corrente, representadas pelo conjunto dos vértices

de Steiner que as compõem. No início do algoritmo, a lista não contém soluções, que são

adicionadas à medida que o HGP progride. Como apenas os ótimos locais são candidatos

a fazer parte da lista soluções de elite, a cada iteração tenta-se inserir no máximo uma

solução em L.

Como todas as soluções na lista devem ser combinadas entre si, o tempo de execução

da fase de pós-processamento é proporcional a jLj

2

. Limitar o valor de jLj a uma constante

pequena é conveniente para evitar que o tempo de execução do algoritmo seja excessivo

(adotou-se jLj = 10 na maioria dos testes realizados).

Dada a limitação do tamanho, é preciso haver um critério para a seleção das soluções

que serão inseridas na lista de elite. Para ser inserida, uma solução S deve ter duas

características. Em primeiro lugar, deve ser diferente de qualquer outra solução presente

na lista. Em segundo lugar, deve ter custo estritamente menor que o da pior solução

armazenada até então (a menos, é claro, que ainda haja espaços vazios). A solução de

maior valor é retirada da lista para dar lugar à nova se necessário.

Esses critérios são observados não só na construção da primeira geração de soluções

de elite, mas de todas as demais. Observe que nada impede que haja numa geração solu-

ções que estiveram presentes em gerações anteriores, desde que resultem de cruzamentos

(elementos de uma geração não são diretamente inseridos na geração seguinte). Portanto,

combinações feitas em uma geração podem ser refeitas em outras. Como alguns dos pro-

cedimentos de combinação não são determinísticos, isso não leva necessariamente a uma

perda de diversidade.

5.5.2 Estratégias de Religamento

Foram implementadas três estratégias de religamento: por movimentos complementares

(descrita na Seção 5.5.2.1), por perturbações (Seção 5.5.2.2) e um terceiro, adaptativo,

resultado da combinação dos anteriores (5.5.2.3).

Page 82: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 70

5.5.2.1 Religamento por Movimentos Complementares

Este método, utilizado por Bastos e Ribeiro [3], baseia-se na representação de soluções por

vértices de Steiner descrita na Seção 4.1. Soluções são representadas por vetores binários:

o valor 1 em uma posição indica que o vértice correspondente faz parte da solução; o

valor 0 signi�ca que o vértice não pertence à solução. Diferentes soluções terão diferentes

vetores característicos (ou vetores de incidência).

Dadas duas soluções, o religamento por movimentos complementares consiste em trans-

formar uma delas (a solução inicial) na outra (a solução guia) a partir de movimentos

sucessivos de inserção e/ou remoção de vértices. Em cada etapa, cada bit diferente entre

a solução atual e a solução guia representa um movimento candidato. Se o vértice v está

presente na solução atual mas não na guia, ele é um candidato a remoção; se ocorre o

contrário (presente na solução guia e ausente na atual), o vértice é candidato a inserção.

Os movimentos de inserção e remoção são similares aos utilizados na busca local por nós

de Steiner (Seção 4.2.1).

Em cada etapa, são testados todos os movimentos possíveis e o melhor deles é escolhido

(o que reduz mais o custo da solução ou o que provoca o menor aumento). Assim, a solução

inicial gradualmente transforma-se na solução guia. O processo pode ser entendido como

uma trajetória por um caminho que liga as duas soluções originais no espaço de busca

(isso torna clara a origem do termo path-relinking). O resultado do religamento é a melhor

solução encontrada ao longo do caminho.

Fixado um par de soluções, veri�cou-se experimentalmente que é mais vantajoso uti-

lizar como solução inicial a de menor valor e como guia a de maior valor. A�nal, como a

vizinhança da solução inicial é explorada mais cuidadosamente pelo método, é interessante

que essa seja uma solução de boa qualidade.

Um aspecto importante a se considerar nesse método é o número de soluções anali-

sadas. Se as soluções combinadas tiverem d bits de diferença, o caminho entre elas terá

exatamente d�1 etapas (soluções) intermediárias. Como em cada uma devem ser testados

todos os movimentos candidatos, serão analisados O(d

2

) vizinhos. Em instâncias cujas

soluções têm muitos vértices, o tempo de execução do método pode ser intoleravelmente

elevado. Para instâncias menores, no entanto, o método é muito e�ciente.

5.5.2.2 Religamento por Perturbações

No religamento por pertubações, a combinação (ou cruzamento) de duas soluções é feita

pela alteração aleatorizada dos custos das arestas do grafo original, seguida da aplicação de

uma heurística construtiva. Depois de construída a solução, os pesos originais das arestas

são restaurados e aplica-se um método de busca local.

1

Na implementação realizada, a

1

Quando usado para caracterizar esse método, o termo �religamento� não deve ser interpretado literal-

mente. A rigor, trata-se apenas de uma combinação de duas soluções. Alternativamente, pode-se pensar

no método como um crossing-over otimizado, utilizando-se a terminologia dos algoritmos genéticos.

Page 83: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 71

estratégia de busca local é a mesma utilizada nas iterações do HGP. Nada impede, no

entanto, que se utilize um método distinto.

A função de penalização é projetada com o objetivo de gerar soluções que de fato

combinem características das duas soluções originais. Cada aresta do grafo original é

multiplicada por um número inteiro,

2

escolhido de acordo com o número de soluções (0,

1, ou 2) em que ela aparece. Quando a aresta está presente em ambas as soluções, o multi-

plicador é 1 (ou seja, o peso permanece inalterado); quando está presente em apenas uma,

o multiplicador é aleatoriamente escolhido no intervalo [50; 100] com distribuição uniforme

de probabilidades; quando não aparece em nenhuma das duas soluções, o multiplicador é

2000.

Assim, as arestas que não estão presentes em qualquer das árvores são severamente

penalizadas e as que aparecem em ambas as árvores praticamente não recebem penaliza-

ção. O objetivo é fazer com que o algoritmo construtivo contenha todas (ou quase todas)

as arestas comuns às soluções originais e nenhuma aresta que não pertença a alguma

das soluções. Arestas presentes em pelo menos uma delas recebem penalizações médias

e em um intervalo relativamente grande; dessa forma, espera-se que elas se misturem na

composição da nova árvore.

5.5.2.3 Religamento Adaptativo

A e�ciência relativa dos dois métodos de religamento propostos depende das características

da instância à qual são aplicados. Tanto o tempo de execução quanto a qualidade das

soluções obtidas variam caso a caso.

Assim sendo, propõe-se um método adaptativo, que combina ambos os métodos. Seja

L a lista de soluções de elite. Inicialmente, utiliza-se o método por movimentos comple-

mentares para combinar a melhor solução de L com cada um das demais. Em seguida,

repetem-se as mesmas ligações, mas usando o método aleatorizado. Os tempos de execu-

ção dessas duas passagens são medidos. O método mais rápido é escolhido para efetuar

as demais combinações, sendo utilizado também nas gerações seguintes, se houver. (Em

caso de empate no tempo de execução, a preferência é dada ao método aleatorizado.)

Esse método privilegia claramente o tempo de execução, mas observações empíricas

mostraram que, em geral, essa escolha leva ao método commaior probabilidade de sucesso,

pelo menos quando NP é a estratégia de busca local utilizada. Um estudo mais detalhado

a esse respeito é apresentado em [50].

2

O uso de um multiplicador inteiro evita que o programa lide com valores em ponto �utuante, o

que tenderia a torná-lo mais lento. Evidentemente, essa estratégia tem a desvantagem de não poder ser

aplicada a grafos cujos pesos originais são muito altos, já que a possibilidade de over�ow seria muito

grande.

Page 84: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 72

5.5.3 Critérios de Parada

Conforme já mencionado, o religamento é feito em diversas iterações. As soluções do

pool são combinadas entre si, formando um novo conjunto de soluções (um novo pool).

Diz-se que as novas soluções constituem uma nova geração. Seus elementos são também

combinados entre si, formando uma outra geração, e assim sucessivamente.

Falta a essa descrição um critério de parada. Se implementado da forma como foi

descrito, as gerações poderiam se suceder inde�nidamente. Entre os critérios possíveis, é

natural pensar nos que se baseiam na comparação de uma geração com as anteriores:

� (B)est : a combinação dos elementos da geração i só será feita se a melhor solução

dessa geração tiver valor menor que a melhor solução encontrada em gerações ante-

riores;

� (A)verage: a combinação dos elementos da geração i só será feita se a média dos

valores das soluções dessa geração for menor que a média dos valores da geração

anterior (i� 1);

� (W)orst : a combinação dos elementos da geração i só será feita se a pior solução

dessa geração for melhor que a pior solução encontrada na geração anterior.

O princípio básico nos três casos é o mesmo: só prosseguir se houver alguma evidência

de que o algoritmo está progredindo. Na prática, observou-se que o métodoB, por ser mais

rigoroso, tende a levar a um número menor de iterações que o método A, por exemplo. O

método W tem comportamento intermediário. Na maioria dos testes realizados, utilizou-

se o método B: o algoritmo prossegue até que uma nova geração não possua uma solução

melhor que todas as encontradas anteriormente.

É possível ainda fazer combinações desses critérios. Na Seção 5.6.2.1, relata-se um

experimento em que o algoritmo só é interrompido se nenhum dos critérios for satisfeito,

ou seja, se os valores da melhor solução, da pior solução e da média das soluções da geração

corrente forem maiores ou iguais aos respectivos valores da geração anterior. Para essa

estratégia (que recebe a denominação de ABW ), a qualidade das soluções fornecidas tende

a aumentar, pois o número de iterações é quase sempre maior que o obtido quando um

critério individual é utilizado.

É preciso, no entanto, ter um cuidado especial: se os critérios forem usados de forma

estrita, o número de iterações pode ser in�nito. Sejam dois critérios C

1

e C

2

quaisquer. É

possível que, numa determinada geração, o critério C

1

melhore e C

2

piore; isso é su�ciente

para que o algoritmo prossiga. Em uma iteração futura, C

1

pode piorar (assumindo o

valor anterior) e C

2

, melhorar. O algoritmo também prossegue nesse caso. É fácil ver

que há o risco de formação de ciclo potencialmente in�nito. Mas é simples evitá-lo: basta

armazenar o valor utilizado na última vez em que cada critério foi utilizado. Em iterações

futuras, proíbe-se que valores menores sejam usados.

Page 85: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 73

5.6 Resultados Experimentais

A qualidade das soluções fornecidas pelo algoritmo HGP+PR depende, conforme já men-

cionado, dos parâmetros utilizados. Em especial, a escolha da busca local, o número de

iterações, o número de soluções de elite e o critério de parada para o path-relinking têm

in�uência marcante sobre a qualidade do algoritmo. Um aumento no tempo de execução

resultante da alteração de qualquer desses parâmetros tende a melhorar a qualidade das

soluções obtidas.

Para os experimentos apresentados na Seção 5.6.1, utiliza-se um conjunto de parâme-

tros �de referência� arbitrariamente escolhido. A implementação resultante é analisada

tanto em termos absolutos quanto em relação a outros algoritmos apresentados na litera-

tura.

Em situações práticas, no entanto, a escolha dos parâmetros deve ser feita de acordo

com o tempo disponível em cada caso. Na Seção 5.6.2, discute-se a questão da escalabili-

dade do algoritmo, ou seja, como um aumento no tempo de execução se traduz na prática

em soluções de melhor qualidade.

Como no caso das buscas locais, foram utilizadas instâncias pré-processadas nos testes

envolvendo as classes OR-Library e VLSI. Todas as execuções foram realizadas em um

Pentium II de 400 MHz. Os tempos de execução apresentados não incluem os tempos de

pré-processamento, que podem ser obtidos no Apêndice A.

5.6.1 Implementação com Parâmetros de Referência

São os seguintes os parâmetros utilizados na implementação de referência da metaeurística

HGP+PR:

� heurísticas construtivas: Prim (implementação direta), Kruskal (Kruskal-V), Bor·v-

ka, DNHz e Multispan.

� busca local : métodos NP e PN (um deles é escolhido aleatoriamente em cada itera-

ção);

� estratégia de perturbação: IDU (oscilação estratégica);

� número de iterações: 128;

� soluções de elite: 10;

� path-relinking : adaptativo (seleciona o mais rápido entre os religamentos por movi-

mentos complementares e por perturbações);

� critério de parada: B (melhor solução).

Page 86: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 74

A Tabela 5.2 mostra a qualidade das soluções obtidas pelo algoritmo HGP+PR com

esses parâmetros. Para cada série de instâncias testada, apresentam-se os desvios per-

centuais médios em relação à melhor solução primal conhecida. O resultado �nal do

algoritmo (o valor obtido após o path-relinking) é apresentado na última coluna. As de-

mais colunas apresentam alguns resultados parciais obtidos pelo algoritmo. A coluna �32�,

por exemplo, apresenta o desvio percentual médio considerando-se, para cada instância,

a melhor solução obtida nas 32 primeiras iterações do GRASP.

série desvios percentuais

1 2 4 8 16 32 64 128 PR

i080 3.003 2.031 1.608 0.772 0.300 0.118 0.048 0.008 0.004

i160 3.049 2.447 1.752 1.019 0.624 0.367 0.308 0.170 0.098

i320 3.391 2.802 2.028 1.425 0.974 0.698 0.522 0.370 0.129

i640

2.918 2.595 1.959 1.561 1.253 0.920 0.792 0.619 0.290

c 0.637 0.154 0.114 0.067 0.047 0.047 0 0 0

d 0.645 0.574 0.557 0.106 0.096 0.081 0.081 0.041 0.017

e 0.476 0.253 0.241 0.194 0.103 0.097 0.083 0.072 0.053

bip

6.928 6.300 5.653 5.227 4.628 4.476 4.157 3.560 2.293

cc

4.070 2.995 2.646 2.374 2.172 2.021 1.848 1.764 0.912

hc

2.520 1.892 1.708 1.545 1.523 1.444 1.420 1.297 0.792

alue 0.705 0.508 0.375 0.276 0.161 0.132 0.091 0.085 0.022

alut 0.642 0.536 0.438 0.279 0.201 0.136 0.096 0.086 0.029

diw 0.375 0.159 0.093 0.027 0.027 0.027 0.027 0 0

dmxa 0.511 0.395 0.211 0.025 0 0 0 0 0

gap 0.577 0.449 0.012 0.012 0.012 0.012 0 0 0

msm 0.427 0.156 0.156 0.059 0.005 0 0 0 0

taq 0.398 0.179 0.179 0.139 0.131 0.062 0.039 0.033 0.021

Tabela 5.2: Qualidade das soluções obtidas ao longo da execução da implementação de

referência

A coluna �1� da tabela representa a primeira iteração do GRASP, que nada mais é que

o algoritmo de Prim seguido de uma busca local (lembre-se de que não há perturbações

na primeira iteração). Observe que o desvio médio diminui signi�cativamente ao longo

do algoritmo, o que demonstra a e�ciência da metaeurística. Evidentemente, isso se

re�ete em um aumento signi�cativo nos tempos de execução do algoritmo, apresentados

na Tabela 5.3 (compare com a Tabela 4.4). A�nal, é necessário executar um procedimento

completo de busca local em cada iteração.

Comparação com outros métodos A melhor maneira de avaliar a qualidade dos

resultados obtidos é compará-los com os obtidos por outras heurísticas apresentadas na

literatura. Serão considerados os seguintes algoritmos:

Page 87: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 75

série tempo (s)

HGP PR Total

i080 2.00 0.14 2.14

i160 9.54 0.57 10.12

i320 54.04 2.89 56.94

i640 345.31 17.05 362.38

c 1.88 0.25 2.13

d 6.93 0.98 7.91

e 47.73 11.47 59.20

bip 371.06 134.22 505.29

cc 571.75 703.49 1275.25

hc 839.30 1335.36 2174.67

alue 1653.52 1909.41 3562.93

alut 1775.44 1886.44 3661.89

diw 9.36 2.00 11.36

dmxa 0.79 0.14 0.93

gap 7.29 1.45 8.74

msm 2.12 0.49 2.61

taq 36.69 11.81 48.50

Tabela 5.3: Tempos médios de execução da implementação de referência

� RTS: Busca tabu reativa apresentada por Bastos e Ribeiro em [3]. O mesmo artigo

apresenta a variante RTS+PR, que utiliza o religamento por movimentos comple-

mentares descrito na Seção 5.5.2.1.

� TS: Busca tabu de Ribeiro e Souza [49].

� FT: Busca tabu de Gendreau et al. [21].

� SV: Procedimento SVertex+ReBuild de Duin e Voss [15].

� PH2: �Método Piloto� de Duin e Voss, na versão apresentada em [16] que leva a

soluções de melhor qualidade.

3

A comparação se baseia na análise de apenas seis séries de instâncias: c, d, e, i080, i160

e i320. As demais séries não foram testadas pelos autores dos algoritmos de referência.

Quanto à qualidade das soluções fornecidas, utilizam-se duas medidas para comparar os

métodos: desvios em relação ao ótimo (Tabela 5.4) e número de soluções ótimas encon-

tradas (Tabela 5.5). Nessas tabelas, é bom lembrar que as séries c, d e e têm 20 instâncias

cada, enquanto as demais têm 100 instâncias cada.

3

Os valores aqui apresentados para esse algoritmo referem-se não ao artigo original, mas a execuções

do algoritmo feitas por C. Duin em abril de 2001 [13].

Page 88: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 76

Para alguns dos algoritmos testados, os valores para a série i320 são estimados (limites

superiores para os desvios e inferiores para o número de ótimos), já que nem todos os óti-

mos dessa série eram conhecidos na época em que os respectivos artigos foram publicados

ou submetidos para publicação. A série só foi completamente resolvida em 2001 por Poggi

de Aragão, Uchoa e Werneck [44]; o algoritmo utilizado para isso (branch-and-ascent) será

apresentado detalhadamente no Capítulo 7.

série HGP HGP+PR RTS RTS+PR TS FT SV PH2

c 0 0 0.13 0.01 0.26 0.02 0.54 �

d 0.041 0.017 0.36 0.10 0.71 0.11 0.75 �

e 0.072 0.032 0.59 0.17 0.83 0.31 � �

OR-Library 0.038 0.016 0.36 0.09 0.60 0.15 � �

i080 0.008 0.004 0.02 0.01 0.08 � 1.03 0.02

i160 0.170 0.098 0.19 0.12 0.35 � 0.98 0.04

i320 0.370 0.129 �0.48 �0.34 �0.89 � �1.20 0.04

Incidência 0.183 0.077 �0.23 �0.16 �0.44 � �1.07 0.03

Tabela 5.4: Metaeurísticas: desvios relativos percentuais médios

série HGP HGP+PR RTS RTS-PR TS FT SV PH2

c 20 20 17.7 19.8 17 18 � �

d 18 19 14.2 16.7 9 14 � �

e 16 17 11.6 13.6 7 10 � �

OR-Lib 54 56 43.5 50.1 33 42 � �

i080 96 97 96 99 89 � � 96

i160 75 81 73 81 58 � � 90

i320 61 67 �56 �64 �39 � � 86

Incidence 232 245 �225 �244 �186 � � 272

Tabela 5.5: Metaeurísticas: número de soluções ótimas encontradas

Os tempos médios de execução dos algoritmos são apresentados na Tabela 5.6. Os

valores são apresentados apenas como referência, já que as máquinas utilizadas são muito

diferentes. Os algoritmos HGP e HGP+PR foram executados em um Pentium II de

400 MHz. O mesmo ocorreu com os algoritmos RTS e RTS+PR para instâncias de

Incidência; para a OR-Library, uma Sun Ultra 1 de 167 MHz. Máquinas do mesmo tipo

foram utilizadas para testar os algoritmos FT e TS. O método SV foi executado em um

Pentium de 90 MHz. Finalmente, os tempos para o algoritmo PH2 foram obtidos em um

Intel Celeron de 500 MHz. Os tempos não incluem o pré-processamento, usado por todas

os métodos para as instâncias da OR-Library.

Page 89: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 77

série HGP HGP+PR RTS RTS+PR TS FT SV PH2

c 1.88 2.13 2.0 3.0 1.0 18.0 � �

d 6.93 7.91 5.3 12.5 3.9 115.0 � �

e 47.73 59.20 21.3 157.2 17.6 1474.0 � �

OR-Library 18.85 23.08 9.6 57.6 7.5 535.7 � �

i080 2.00 2.14 5.8 6.2 3.3 � 0.4 1.1

i160 9.54 10.12 28.1 29.9 12.2 � 2.7 11.1

i320 54.04 56.94 162.6 168.1 50.5 � 14.8 140.4

Incidência 21.86 23.07 65.5 68.1 22.0 � 6.0 50.9

Tabela 5.6: Metaeurísticas: tempos de execução em segundos (com diferentes máquinas)

As tabelas mostram que os algoritmos HGP e HGP+PR apresentam resultados de

excelente qualidade quando comparado a outras metaeurísticas. Para as instâncias da

OR-Library, a qualidade é superior às fornecidas por todos os demais métodos. Já para

as instâncias de Incidência, a busca tabu reativa (RTS e RTS+PR) é capaz de fornecer

soluções de qualidade semelhante; o Método Piloto (PH2) apresenta resultados ligeira-

mente melhores. Note, porém, que tanto a busca tabu reativa quanto o Método Piloto

apresentam tempos de execução maiores (para execuções em máquinas equivalentes ou

superiores às usadas pelo método HGP+PR). A diferença não é muito signi�cativa, mas

existe.

5.6.2 Escalabilidade

Os resultados experimentais apresentados até aqui referem-se a execuções do algoritmo

HGP+PR com o conjunto de parâmetros de referência: 128 iterações, 10 soluções de

elite, busca local NP/PN, etc. Apesar de o algoritmo ter um bom desempenho quando

executado dessa forma, há situações em que se está disposto a gastar um tempo ainda

maior para encontrar soluções de boa qualidade. Esta seção mostra que, em caso de

necessidade, isso pode ser feito com sucesso.

5.6.2.1 Parâmetros

Vários dos parâmetros do algoritmo têm clara in�uência sobre a qualidade das soluções

obtidas (e sobre o tempo de execução). Os mais evidentes são o número de iterações e

o de soluções de elite. O primeiro se re�ete linearmente no tempo de execução (quando

o número de iterações dobra, também aproximadamente dobra o tempo dedicado ao

GRASP). O segundo, o número de soluções de elite, tem in�uência quadrática sobre o

tempo de execução (quando dobra o número de soluções de elite, o número de cruzamentos

feitos em cada geração é multiplicado por quatro, aproximadamente). Em ambos os casos,

há uma in�uência indireta sobre o número de gerações criadas no religamento, que pode

Page 90: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 78

diminuir ou, mais provavelmente, aumentar.

A Tabela 5.2 mostra que o efeito da adição de novas iterações de GRASP tende a

ser menos perceptível que o de um path-relinking mais cuidadoso (basta comparar o que

ocorre quando o número de iterações aumenta de 64 para 128 com o que ocorre quando

se aplica o path-relinking às soluções obtidas após a iteração 128). Se houver mais tempo

disponível, portanto, parece ser mais vantajoso usá-lo para aumentar a e�ciência do path-

relinking.

Para veri�car que execuções mais longas de fato levam a melhores resultados, observe

os resultados mostrados na Tabela 5.7. Ele mostra o resultado da execução do algoritmo

HGP+PR com as mesmas heurísticas construtivas e buscas locais da implementação de

referência, mas com os demais parâmetros alterados. Foram executadas 256 iterações de

GRASP em cada caso, o dobro do valor original. O path-relinking, além de contar com 32

soluções de elite (o valor de referência é 10), tem duas outras características diferentes:

o critério de parada é ABW (veja a discussão na Seção 5.5.3) e o religamento é feito

sempre utilizando o método por perturbações (na implementação de referência, o método

de parada é B e o religamento, adaptativo).

série desvio (%) ótimos tempo (s)

HGP HGP+PR HGP HGP+PR HGP HGP+PR

i080 0.003 0 98 100 4.08 12.78

i160 0.129 0.033 80 92 19.48 84.62

i320 0.258 0.018 66 85 111.80 503.26

Total 0.130 0.017 244 277 45.12 200.22

Tabela 5.7: Execuções �longas� para instâncias de incidência (256 iterações, 32 soluções

de elite e religamento por perturbações com critério de parada ABW )

Quando se comparam esses resultados com os obtidos pela implementação de referência

(colunas HGP e HGP+PR das Tabelas 5.4, 5.5 e 5.6), é possível veri�car claramente

alguns aspectos do funcionamento do algoritmo. Os dados para os algoritmos sem path-

relinking (HGP) mostram que dobrar o número de execuções de fato dobra o tempo

médio de execução (que passa de 21.86s para 45.12s), mas leva a melhores soluções:

o erro relativo médio para as três séries passou de 0.183% para 0.130%. Observe, no

entanto, que um desempenho ainda melhor foi alcançado simplesmente utilizando-se o

path-relinking adaptativo após apenas 128 iterações de GRASP (na média, erro relativo

de 0.077% em 23.07s, conforme mostra a Tabela 5.4). Isso demonstra mais uma vez a

e�cácia do religamento.

Soluções signi�cativamente melhores são obtidas quando após as 256 iterações de

GRASP se executa o path-relinking �reforçado� (por perturbações, com 32 soluções de

elite e critério de parada ABW ). A Tabela 5.7 mostra que o erro relativo é de apenas

0.017%. É claro que isso tem um custo: o tempo médio de execução é de mais de 200

segundos, muito maior que nos outros casos.

Page 91: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 79

De certa forma, pode-se considerar que a parametrização utilizada para construir

a Tabela 5.7 caracteriza um algoritmo fundamentalmente diferente do mostrado pela

implementação de referência. Na parametrização original, apenas cerca de 5% do tempo

de execução é dedicado ao religamento (veja Tabela 5.6). Na nova parametrização a

ênfase do algoritmo é outra: mais de 75% do tempo é dedicado ao path-relinking. As

gerações são maiores (32 soluções), os cruzamentos são mais lentos (para essa classe de

instâncias, o religamento por movimentos complementares é mais rápido) e o número

de gerações é maior (entre outros fatores, porque o critério de parada � ABW � é

menos rígido). Apenas como ilustração, considere o que ocorre com a série i320: com a

implementação de referência, o número de gerações varia de 1 a 5 (1.58 na média); com

a nova implementação, o intervalo se amplia para valores de 1 a 16 (5.24 na média). Um

aumento expressivo.

5.6.2.2 Outras Sub-rotinas

Uma das principais características da metaeurística proposta é permitir a adição de novos

componentes de forma muito simples. Um dos elementos que podem contribuir mais

signi�cativamente para aumentar a qualidade das soluções obtidas é a estratégia de busca

local. Nas versões do algoritmo HGP estudadas até aqui, utilizaram-se apenas as buscas

por nós de Steiner (N) e por caminhos-chaves (P ). No entanto, conforme já demonstrado

no Capítulo 4, a qualidade das soluções obtidas tende a ser maior se for utilizada também

a busca por nós-chaves (K ). O custo, no entanto, é alto: um aumento de uma a duas

ordens de grandeza no tempo de execução do algoritmo.

Considere o caso das instâncias PUC. A Tabela 5.2 mostra que o método HGP+PR

com as buscas NP e PN obtém desvios médios de 2.293% (série bip), 0.912% (série

cc) e 0.792% (hc). Como os valores ótimos das soluções para a maioria das instâncias

nessas séries não são conhecidos, os desvios são calculados em relação às melhores soluções

primais já encontradas, apresentadas em [51]. Essas soluções primais de referência foram

obtidas justamente com o algortimo HGP+PR utilizando a busca NPK. O desvios médios

acima mostram uma nítida diferença na qualidade. (Note porém que ela não se deve

apenas à busca K: em muitos casos foram utilizadas mais iterações de GRASP ou soluções

de elite. Mas a busca K sem dúvida tem papel importantíssimo.)

Trata-se de um excelente exemplo de situação para a qual o algoritmo HGP+PR pode

ser utilizado. O objetivo do artigo [51] era justamente introduzir instâncias que fossem

consideradas �difíceis� tanto para heurísticas primais quanto para algoritmos exatos. Um

dos aspectos que torna uma instância difícil é a diferença percentual entre um bom limite

inferior para o valor de sua solução (obtido por programação linear, conforme se verá no

Capítulo 6) e a solução ótima. Para a maioria das instâncias, no entanto, foi impossível

calcular uma solução ótima (a�nal, trata-se de instâncias difíceis). Fez-se necessário uti-

lizar uma heurística para calcular soluções primais tão boas quanto possível. Utilizou-se o

algoritmo HGP+PR com a busca NPK. Os demais parâmetros variaram de acordo com a

instância. Tipicamente, o tempo de execução foi de vários dias, o que, para essa aplicação

Page 92: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 80

é perfeitamente tolerável.

5.7 Conclusão

Nos algoritmos aqui apresentados, HGP e HGP+PR, componentes básicos muito simples

(heurísticas construtivas e métodos de busca local) são integrados por uma superestrutura

comum. O princípio básico utilizado para a integração é um só: utilizar perturbações.

Elas surgem basicamente para introduzir um elemento de aleatorização nas heurísticas

construtivas do GRASP e para permitir a combinação de soluções na fase de religamento.

Esses dois objetivos podem ser alcançados sem o uso de perturbações. Em um GRASP

�puro�, a aleatorização é conseguida alterando-se o código das heurísticas construtivas

utilizadas. O path-relinking pode ser feito, por exemplo, utilizando-se movimentos com-

plementares. No entanto, o uso de perturbações tem algumas vantagens inerentes:

� Simplicidade de implementação. Perturbar os pesos das arestas de um grafo é mais

simples do que criar novos métodos construtivos ou algoritmos para efetuar o re-

ligamento de forma explícita.

� E�ciência. Aleatorizar diretamente um algoritmo construtivo em muitos casos sig-

ni�ca torná-lo mais lento, pois pode requerer o uso de estruturas mais complexas

(é esse o caso do algoritmo de Prim, por exemplo); o uso de perturbações permite

utilizar as melhores implementações de cada método.

� Qualidade. Em um GRASP puro, a aleatorização de uma heurística gulosa se faz

pela criação de uma lista de candidatos em cada etapa do algoritmo. Em vez de

se escolher apenas o elemento de maior prioridade, escolhe-se um dentre os mais

prioritários. Em muitos casos, obter uma aleatorização razoável requer o uso de

listas extremamente grandes, o que tende a piorar muito a qualidade das soluções

construtivas. Métodos de busca local aplicados sobre essas soluções tendem não só

a ser mais lentos, mas também a obter soluções de pior qualidade.

� Uso de estratégias de busca elaboradas. O uso de perturbações permite que se

implementem de forma de forma muito simples estratégias elaboradas para percorrer

o espaço de soluções, como intensi�cação, diversi�cação e oscilação estratégica.

� Flexibilidade. A adição ou substituição de elementos no HGP+PR é extremamente

simples, pois não requer qualquer alteração na estrutura dos algoritmos entre si.

Novos métodos construtivos e novas formas de busca local podem ser integrados

tanto à primeira fase do algoritmo (HGP) quanto à fase de religamento. Para isso

não é necessário sequer conhecer o princípio de funcionamento dos componentes

adicionados, que podem ser utilizados como �caixas-pretas�.

Page 93: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 5. METAEURÍSTICAS 81

Evidentemente, de nada adiantariam essas vantagens se os resultados fornecidos pela

heurística HGP+PR não fossem competitivos. O algoritmo não só fornece soluções de

excelente qualidade, mas o faz para uma grande variedade de instâncias. Trata-se de um

método muito robusto. Para várias das instâncias em aberto da literatura (da série i640,

por exemplo), os melhores valores conhecidos foram obtidos por esse algoritmo [33].

Page 94: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Capítulo 6

Algoritmos Duais

Os algoritmos apresentados nos capítulos anteriores são capazes de obter soluções de

excelente qualidade para instâncias do problema de Steiner em grafos. Contudo, nenhum

deles é capaz de fornecer garantias relevantes para a qualidade da solução obtida. Na

prática, isso signi�ca que, após a execução de um desses algoritmos, não se sabe ao certo

se a solução fornecida pode ou não ser melhorada, e em quanto pode ser melhorada.

Uma solução primal viável (uma árvore de Steiner) fornece apenas um limite superior

para o valor da solução ótima do problema. Para que se possa fornecer uma garantia de

qualidade para essa solução, é necessário que se conheça também algum limite inferior.

A diferença percentual entre os limites inferior e superior é uma estimativa (de pior caso)

para a qualidade da solução fornecida.

O problema de Steiner em grafos pode ser formulado como um problema de progra-

mação linear inteira. Removendo-se as restrições de integralidade, obtém-se sua relaxação

linear , que pode ser resolvida em tempo polinomial, conforme se verá na Seção 6.1. Em

um problema de minimização (como é o de Steiner), a remoção de qualquer restrição só

pode diminuir o valor da solução obtida (ou mantê-lo inalterado, se a restrição for redun-

dante). Portanto, a solução da relaxação linear do problema é sempre um limite inferior

para o valor de sua solução ótima.

Para o problema de Steiner em grafos, há formulações lineares muito fortes: a diferença

percentual entre o valor da solução ótima (inteira) e a solução da relaxação (o gap de du-

alidade) é normalmente muito pequena, muitas vezes nula. No entanto, mesmo sendo um

problema polinomial, o cálculo exato da relaxação linear pode ser extremamente custoso

na prática. Em certas situações, torna-se interessante calcular apenas soluções aproxi-

madas para a relaxação linear. É justamente disso que trata este capítulo: heurísticas

combinatórias baseadas no dual da relaxação linear da formulação do problema de Steiner

como um problema de programação linear inteira.

A formulação utilizada pelos algoritmos é discutida em detalhes na Seção 6.1. A

Seção 6.2 descreve uma heurística construtiva para a obtenção de soluções duais (dual

82

Page 95: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 83

ascent) proposta por Wong em [65]. A Seção 6.3 introduz alguns métodos derivados

dessa heurística que têm o objetivo de melhorar a qualidade das soluções obtidas. Por

�m, a Seção 6.4 contém alguns comentários �nais sobre o uso de heurísticas duais.

Versões preliminares dos algoritmos apresentados neste capítulo (e no próximo) foram

apresentadas em [44], artigo escrito em co-autoria com Marcus Poggi de Aragão e Eduardo

Uchoa.

A discussão apresentada neste capítulo requer o conhecimento dos princípios básicos

de programação linear inteira e de seu uso para problemas de otimização combinatória.

Referências relevantes para o assunto são [42] e [64].

6.1 Formulação e Dualidade

6.1.1 Formulação Primal

O problema de Steiner de grafos pode ser formulado como um problema de programação

inteira de diversas maneiras diferentes (veja [22, 36, 45] para análises comparativas). Na

prática, uma das mais freqüentemente utilizadas é a baseada em cortes direcionados,

discutida em [65]. Muitos dos mais e�cazes algoritmos exatos para o problema de Steiner

utilizam essa formulação [32, 46, 58]. Será essa a formulação utilizada pelos algoritmos

estudados neste e no próximo capítulo.

A formulação é válida para a versão direcionada do problema de Steiner em grafos (em

que objetivo é encontrar uma arborescência de peso mínimo a partir de uma raiz r), mas

pode ser normalmente aplicada para o caso não-direcionado. Para isso, basta transformar

cada aresta (v; w) do grafo original em dois arcos antiparalelos de mesmo custo no grafo

direcionado � (v; w) e (w; v) � e �xar um terminal qualquer como raiz. Portanto, sem

perda de generalidade, será utilizada a notação G = (V;A) para representar um grafo

direcionado de entrada, sendo V o conjunto de vértices e A o de arcos. O conjunto T ,

como sempre, representa o conjunto de vértices terminais.

Dado um subconjunto próprio W dos vértices de um grafo direcionado G(V;A) (ou

seja, W � V ), de�ne-se o corte direcionado �

(W ) como o conjunto dos arcos (u; v) 2 A

tais que u 62 W e v 2 W . Em outras palavras, pertencem a �

(W ) todos os arcos com

cauda (origem) em V n W e cabeça em W (�

+

(W ) é de�nido de forma análoga, mas

considerando os arcos que saem de W ).

Dada uma instância do problema de Steiner em grafos, seja W o conjunto composto

por todos os conjuntos de vértices que determinam cortes que separam a raiz r de algum

outro terminal. Em outras palavras, W 2 W se W contém pelo menos um terminal e

não contém a raiz r. A formulação baseada em cortes direcionados para o problema de

Steiner em grafos exige apenas que, para todo W 2 W, pelo menos um arco de �

(W )

faça parte da solução. Isso é su�ciente para garantir que a solução ótima (inteira) será

Page 96: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 84

uma arborescência. Associando-se uma variável x

a

a cada arco e sendo c(a) seu custo,

essa formulação pode ser expressa formalmente como:

(P

cd

)

8

>

>

>

>

>

>

>

>

>

>

>

<

>

>

>

>

>

>

>

>

>

>

>

:

min

X

a2A

c(a) x

a

(1)

s.a.

X

a2�

(W )

x

a

� 1 8 W 2 W (2)

x

a

� 0 8 a 2 A (3)

x

a

inteiro 8 a 2 A (4)

A expressão (1) representa a função objetivo: a soma dos custos dos arcos selecionados

(nesta dissertação, considera-se que os custos são sempre inteiros, mas a mesma formulação

pode ser utilizada se não for esse o caso). As restrições do tipo (2) representam os cortes

direcionados. As restrições (3) e (4) são equivalentes a requerer que as variáveis x sejam

binárias (como se trata de um problema de minimização e os custos são positivos, nenhuma

variável terá valor maior que 1).

Repare, no entanto, que o número de restrições do tipo (2) dessa formulação é igual

ao número de elementos em W, exponencial no pior caso. Assim sendo, pode não ser

possível resolver a relaxação linear de forma direta. O que normalmente se faz é resolver

inicialmente um programa linear utilizando um subconjunto de W, muitas vezes vazio.

Executa-se então uma rotina de separação, cuja função é veri�car se a solução obtida

obedece a todas as restrições determinadas por W e, caso isso não ocorra, apresentar

restrições violadas. As restrições encontradas são introduzidas no programa linear, que

é reotimizado. O processo prossegue até que a rotina de separação ateste que a solução

encontrada não viola nenhuma restrição.

Uma propriedade importante da programação linear garante que, se um problema tiver

uma rotina de separação polinomial, então ele pode ser resolvido em tempo polinomial,

mesmo que tenha um número exponencial de restrições [25, 26]. É esse o caso da formu-

lação P

cd

do problema de Steiner em grafos: ela consiste em encontrar cortes de custo

mínimo entre a raiz e todos os demais terminais do grafo usando os valores de x como

custos dos arcos. Esse problema pode ser resolvido em tempo polinomial (utilizando-se,

por exemplo, o algoritmo introduzido em [27] por Hao e Orlin). Assim, resolver o progra-

ma inteiro P

cd

é um problema NP-difícil, mas resolver sua relaxação linear � resultado

da remoção das restrições de integralidade (4) � é um problema polinomial.

6.1.2 Formulação Dual

Essencial para a programação linear é o conceito de dualidade, discutido, entre outros,

em [7]. Para todo programa linear, existe um programa dual correspondente (que tem

o mesmo valor ótimo). No caso do problema de Steiner em grafos, o dual da relaxação

Page 97: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 85

linear da formulação (P

cd

) é o seguinte:

(D

cd

)

8

>

>

>

>

>

>

>

<

>

>

>

>

>

>

>

:

max

X

W2W

W

s.a.

X

W2W :a2�

(W )

W

� c(a) 8a 2 A (1)

W

� 0 8W 2 W (2)

Associa-se uma variável dual �

W

a cada corte direcionado associado a W (o número

de variáveis é exponencial, portanto). O problema consiste em maximizar a soma das

variáveis duais. A restrição básica (além da não-negatividade) é a de que a soma das

variáveis duais associadas aos cortes que contêm um arco a não pode ser superior ao custo

do próprio arco (c(a)).

Essas mesmas restrições podem ser descritas de forma mais compacta se for utilizado

o conceito de custo reduzido. O custo reduzido �c

(a) de um arco

1

a em relação a uma

solução dual � é de�nido como:

�c

(a) = c(a)�

X

W2W :a2�

(W )

W

:

As restrições mencionadas apenas impõem que os custos reduzidos de todos os arcos

sejam não-negativos. Um conceito importante associado à de�nição de custos reduzidos

é o de saturação. Um arco é dito saturado se seu custo reduzido for zero. A existência de

um arco com custo reduzido negativo em uma solução � indica que alguma restrição foi

violada; nesse caso, diz-se que � é inviável.

6.1.3 Complementaridade de Folga

A formulação do problema de Steiner como um programa linear nos permite utilizar alguns

teoremas conhecidos em programação linear (veja, por exemplo, [7]). Em primeiro lugar,

sendo a formulaçãoD

cd

o dual da relaxação linear da formulação P

cd

, pode-se garantir que

as soluções ótimas dos dois problemas têm exatamente o mesmo valor. Além disso, a partir

de uma solução primal ótima (possivelmente fracionária) x

= fx

1

; x

2

; : : : ; x

jAj

g, é possível

obter uma solução dual ótima �

= f�

1

; �

2

; : : : ; �

jWj

g com as seguintes propriedades,

conhecidas como condições de complementaridade de folga:

Propriedade 1 Para qualquer arco a, pelo menos uma das seguintes condições deve ser

válida:

P

W2W :a2�

(W )

W

= c(a); ou

1

Quando se menciona o custo reduzido de um arco, deve-se ler �o custo reduzido da variável associada

a um arco�.

Page 98: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 86

� x

a

= 0.

Propriedade 2 Para toda variável dual �

W

, ao menos uma das seguintes condições é

válida:

P

a2�

(W )

x

a

= 1; ou

� �

W

= 0.

De acordo com a primeira propriedade, para que a tenha valor primal positivo (x

a

> 0),

ele obrigatoriamente deve estar saturado. Pela segunda propriedade, se uma variável dual

tiver valor positivo, os arcos que fazem parte do corte que ela representa têm valor primal

total igual a 1.

Considere uma instância para o problema de Steiner em grafos com gap de dualidade

nulo. Nesse caso, existe uma solução inteira para a relaxação linear de P

cd

: todo arco

a tem associada a si uma variável x

a

de valor 0 ou 1, exatamente. Os arcos de valor 1

compõem uma arborescência de Steiner. De acordo com a Propriedade 2, isso signi�ca que

a solução dual correspondente é tal que todos os cortes de custo dual positivo interceptam

essa aborescência uma única vez. Esse fato será importante para a discussão do dual

adjustment , feita na Seção 6.3.2.

6.1.4 Fixação por Custos Reduzidos

A �nalidade básica para o cálculo de soluções duais para um problema de minimização

é determinar um limite inferior para o problema e, dessa forma, veri�car a qualidade

da melhor solução (primal) conhecida. No entanto, podem-se utilizar as soluções duais

viáveis fornecidas por esses métodos para, em conjunto com limites superiores (primais),

reduzir o tamanho da instância processada. Trata-se da �xação por custos reduzidos,

discutida, por exemplo, em [64]. Esta seção mostra como é feita a �xação no caso do

problema de Steiner em grafos.

Dada uma instância do problema de Steiner em grafos, seja � uma solução dual viável

de valor v(�) e seja Z

inc

o valor da melhor solução primal conhecida. Então, pode-se �xar

a variável x

a

em zero (i.e., eliminar o arco a) se a seguinte condição for observada:

v(�) + �c

(a) > Z

inc

� 1: (6.1)

A �xação em zero no caso do problema de Steiner baseia-se numa redução ao absurdo.

Inicialmente, supõe-se que a está na solução ótima, o que equivale a adicionar a restrição

x

a

� 1 ao problema. Se isso for de fato verdade, pode-se então aumentar a variável dual

associada a essa restrição em até �c

(a) unidades sem tornar inviável a solução dual. O

custo da solução passa de v(�) para v(�) + �c

(a). Se esse valor não for menor que o da

Page 99: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 87

melhor solução primal conhecida, chega-se a uma contradição: um limite inferior pior que

a melhor solução conhecida. O termo ��1� na Condição 6.1 pode ser utilizado devido à

integralidade da função objetivo.

Conforme já observado em [12] e [46], a estrutura do problema de Steiner em grafos

pode ser usada para que se obtenham condições mais favoráveis à �xação, tornando

maiores as chances de que ela ocorra. A suposição de que a está na solução ótima na

verdade tem outras conseqüências. Se a = (u; v) de fato �zer parte de uma arborescência,

as seguintes condições devem ser satisfeitas:

1. deve haver um caminho na arborescência entre r (a raiz) e u;

2. se v não for um terminal, deve haver um caminho na arborescência entre v e algum

terminal t (que não seja a raiz).

Ambas as condições derivam imediatamente do fato de que todos os arcos de uma ar-

borescência de Steiner mínima devem fazer parte de um caminho entre a raiz r e algum

terminal. A Figura 6.1 ilustra as condições.

u

r

r

u

r

v

u

t

--

-

Figura 6.1: Condição para a �xação de (u; v) por custo reduzido

6.1.4.1 Chegada

Concentremo-nos na primeira condição: a existência de um caminho na arborescência

entre a r e u (um caminho que chega ao arco). Em termos da formulação como programa

linear, isso signi�ca que existe um caminho P

ru

= (a

0

; a

1

; : : : ; a

k

) em que todos os arcos

estão associados a variáveis de valor 1 (x(a

0

); x(a

1

); : : : ; x(a

k

)). Para que isso ocorra, é

necessário que todos os arcos nesse caminho estejam saturados, i.e., tenham custo reduzido

zero (caso contrário, devido às condições de complementaridade de folga apresentadas na

Seção 6.1.3, os valores das variáveis associadas não poderão ser maiores que 0).

É conveniente neste ponto de�nir o grafo auxiliar G

, de�nido a partir do grafo de

entrada G e de uma solução dual viável �. O grafo G

é o subgrafo de G que contém

todos os seus vértices, mas apenas as arestas saturadas em relação a � (G

é o grafo de

Page 100: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 88

saturação associado a G e �). Pode-se exigir, portanto, que o caminho P

ru

esteja contido

em G

.

Dada uma solução dual � arbitrária, nada garante que haverá tal caminho; u pode não

ser alcançável em G

a partir da raiz r. No entanto, a suposição inicial feita na �xação

por custos reduzidos, de que a pertence à solução ótima, exige a existência desse cami-

nho. Conseqüentemente, podem ser adicionados novos cortes (restrições) à formulação

(com custo dual positivo) separando r de u; adicionam-se tantos cortes quantos forem

necessários, até que se crie um caminho de custo reduzido total igual a zero entre r e u.

Seja Q

ru

a soma dos valores duais adicionados nesse processo. O teste de �xação por

custos reduzidos (Condição 6.1) passa então a conter um fator adicional:

v(�) + �c

(u; v) +Q

ru

> Z

inc

� 1: (6.2)

Como esse fator é positivo, a chance de a desigualdade acima se veri�car é maior que a

da desigualdade original. Portanto, é maior a probabilidade de que a seja eliminado.

A probabilidade de eliminação será máxima se Q

ru

for maximizado. Para isso, é

necessário encontrar o conjunto de cortes separando r de u cuja soma dos respectivos

valores duais seja máxima. Isso é equivalente a encontrar o caminho mínimo entre r e u

em G usando como pesos os custos reduzidos dos arcos em relação a �. A�nal, o problema

do caminho mínimo entre dois vértices é dual ao problema do empacotamento de cortes

entre dois vértices [2].

6.1.4.2 Saída

Pode-se também exigir a existência de um caminho entre v e algum terminal t em G

, o

grafo de arcos saturados. Se no grafo associado à solução dual original não houver um tal

caminho, novos cortes podem ser adicionados à formulação. Sendo Q

vt

a soma dos custos

dos novos cortes, a Condição 6.1 pode ser estendida para:

v(�) + �c

(u; v) +Q

vt

> Z

inc

� 1: (6.3)

O valor de máximo de Q

vt

pode ser determinado de forma similar à discutida na

seção anterior: calculando-se em G o caminho mínimo (em relação aos custos reduzidos

associados à solução dual original) de v ao terminal t mais próximo.

6.1.4.3 Combinação de Chegada e Saída

Simplesmente combinando-se as condições 6.2 e 6.3, obtém-se a seguinte condição válida:

v(�) + �c

(u; v) + max(Q

ru

; Q

vt

) > Z

inc

� 1: (6.4)

O termo max(Q

ru

; Q

vt

) indica que pode ser usado o caminho mais longo entre os obtidos

segundo os procedimentos descritos nas seções 6.1.4.1 e 6.1.4.2.

Page 101: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 89

Surge aqui uma questão óbvia. Não seria possível utilizar a soma dos custos desses

caminhos? Nem sempre. Nada garante que não há interseção entre os cortes (implici-

tamente) adicionados no cálculo de Q

ru

e os (implicitamente) adicionados no cálculo de

Q

vt

. Se houver alguma interseção, perde-se a garantia de viabilidade da solução dual

resultante.

Há, no entanto, uma forma de combinar as duas estratégias. Para garantir a viabili-

dade da solução dual, basta que os custos reduzidos de todos os arcos sejam atualizados

entre o cálculo de um dos caminhos mínimos (ru) e o cálculo do outro (vt).

2

Para que isso

seja feito de forma e�ciente, é conveniente modi�car ligeiramente o algoritmo de Dijkstra.

É ele o algoritmo utilizado para determinar Q

ru

e Q

vt

isoladamente, usando os custos

reduzidos como pesos dos arcos. A idéia para melhorar a Condição 6.4 é, ao invés de

realizar duas execuções independentes do algoritmo de Dijkstra, fazer a segunda execução

depender da primeira.

É importante neste ponto relembrar os princípios básicos do algoritmo de Dijkstra

(para uma discussão mais completa veja [2], por exemplo). Suponha que se queira encon-

trar um caminho mínimo entre uma fonte (origem) s = v

1

e todos os demais nós de um

grafo com n vértices (v

2

; v

3

; : : : ; v

n

). O algoritmo de Dijkstra baseia-se na atribuição aos

nós de �potenciais� (p

1

; p

2

; : : : ; p

n

) que representam limites superiores para sua distância

à origem. Obviamente, p

1

= 0, já que s = v

1

é a origem. Inicialmente in�nitos, os poten-

ciais dos demais nós são progressivamente reduzidos ao longo da execução do algoritmo;

ao �nal dela, os potenciais representarão as distâncias exatas de cada nó à origem. Em

um ponto qualquer da execução, seja S o conjunto dos nós cujos potenciais já foram �-

xados, ou seja, para os quais o valor do potencial é igual ao valor da distância. No início,

S = fsg. Em cada iteração do algoritmo, o potencial de um certo vértice v

i

é �xado e

esse nó passa a fazer parte de S. O nó escolhido (v

i

) é justamente aquele, entre todos

os nós que não pertencem a S, que é separado de S pelo corte de valor mínimo. O valor

desse corte é a diferença entre o potencial de v

i

(p

i

) e o potencial do nó inserido em S na

rodada imediatamente anterior. Ao �nal da execução do algoritmo, serão conhecidos os

potenciais �nais de todos os vértices: p

1

; p

2

; : : : ; p

n

. Pode-se provar o seguinte resultado:

Teorema 3 Seja a

ij

um arco de custo c

ij

e sejam p

i

e p

j

os potenciais �nais encontrados

pelo algoritmo de Dijkstra para a cauda (v

i

) e a cabeça (v

j

) de a

ij

. O custo reduzido

�c

ij

desse arco em relação aos cortes introduzidos pelo algoritmo de Dijkstra é dado por

�c

ij

= c

ij

�maxf0; p

j

� p

i

g.

Prova No algoritmo de Dijkstra, todo corte (implicitamente) adicionado separa o con-

junto S do restante do grafo. Como no conjunto S são apenas inseridos novos vértices ao

longo da execução do algoritmo, os cortes estão divididos em �camadas�. Interceptarão

o arco a

ij

os cortes adicionados em iterações em que v

i

�zer parte de S e v

j

, não (isso

decorre imediatamente da de�nição de corte direcionado). O custo reduzido de a

ij

será

2

Assume-se aqui que os caminhos são calculados nessa ordem (ru antes de vt). O cálculo na ordem

inversa também é possível, com algumas poucas modi�cações nos procedimentos descritos na seqüência.

Page 102: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 90

simplesmente �c

ij

= c

ij

� s

ij

, sendo s

ij

a soma dos custos dos cortes adicionados após a

inserção de v

i

até a inserção de v

j

. Resta calcular o valor de s

ij

. Considere inicialmente o

caso em que v

j

é inserido em S antes de v

i

. Quando isso ocorre, nenhum corte interceptará

a

ij

e, portanto, s

ij

= 0. Já no outro caso, em que v

i

é inserido em S antes de v

j

, todos os

cortes adicionados entre as duas inserções interceptarão o arco a

ij

. O valor dual associado

a cada corte é igual à diferença de potencial entre o novo nó e o nó inserido na iteração

anterior; para uma seqüência de cortes, o valor total é simplesmente a diferença entre o

potencial do último nó inserido e o potencial original (basta fazer uma soma telescópica).

Portanto, no caso em que a inserção de v

i

precede a de v

j

, s

ij

= p

j

� p

i

. Lembrando

que no caso em que a inserção de v

j

precede a de v

j

temos que p

i

� p

j

, conclui-se que

�c

ij

= c

ij

�maxf0; p

j

� p

i

g. 2

Esse teorema mostra que, se forem conhecidos os potenciais resultantes da execução

do algoritmo de Dijkstra, pode-se determinar o custo reduzido de qualquer arco em tempo

O(1).

Voltando ao problema de Steiner em grafos, considere o que ocorre no algoritmo para

�xação de um arco (u; v) por custos reduzidos, considerando-se uma solução dual �. O

custo reduzido �original� do arco em relação a � é denotado por �c

(u; v). Esse valor e os

dos custos reduzidos de todos os demais arcos do grafo são conhecidos. Conforme proposto

na Seção 6.1.4.1, a partir da execução de um algoritmo de Dijkstra novos cortes podem

ser (implicitamente) adicionados à solução � de forma a garantir que haja um caminho

entre r (a raiz) e v. Seja �

0

a solução dual obtida após essa adição. O Teorema 3 mostra

que o novo custo reduzido de um arco a = (i; j) qualquer é dado por:

�c

0

(i; j) = �c

(i; j)�maxf0; p

j

� p

i

g (6.5)

Repare que essa fórmula utiliza os custos reduzidos originais (em relação a �), já que são

esses os custos utilizados durante o algoritmo de Dijkstra. Por essa fórmula, podem ser

determinados todos os custos reduzidos em relação à solução �

0

, obtida para a computação

de Q

rv

. Utilizando esses custos reduzidos, pode então ser executado um segundo algoritmo

de Dijkstra para garantir a existência de um caminho entre w e um terminal qualquer,

conforme proposto na seção 6.1.4.2.

SejaQ

ruvt

a soma dos cortes adicionados à formulação pelos dois algoritmos de Dijkstra

(a partir de r, usando os custos reduzidos originais, e a partir de v, usando os custos

reduzidos modi�cados). A condição para �xação do arco (u; v) pode ser reescrita da

seguinte forma:

v(�) + �c

(u; v) +Q

ruvt

> Z

inc

� 1: (6.6)

Ao longo deste capítulo, será utilizada a expressão custo reduzido estendido de (u; v)

para representar �c

(u; v) +Q

ruvt

.

Page 103: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 91

6.1.4.4 Implementação

A discussão acima mostra que duas execuções do algoritmo de Dijkstra podem determinar

o custo reduzido estendido de um arco em relação a uma determinada solução dual. O

custo dessa operação pode parecer alto, principalmente quando se considera que normal-

mente não apenas um, mas todos os arcos do grafo são veri�cados pela rotina de �xação.

Na verdade, nesse caso apenas duas execuções do algoritmo de Dijkstra são su�cientes

para medir os custos reduzidos estendidos de todos os arcos:

1. A primeira execução encontra a distância (em relação aos custos reduzidos determi-

nados por �) entre a raiz r e todos os demais vértices do grafo.

2. A segunda execução deve encontrar o caminho mais curto de cada vértice ao ter-

minal mais próximo (em relação aos custos reduzidos corrigidos, de�nidos pela

Equação 6.5). Isso pode ser feito executando-se o algoritmo de Dijkstra no grafo

transposto

G (obtido a partir de G pela inversão de todos os arcos; veja [9], por

exemplo), utilizando-se como origens todos os terminais (exceto a raiz).

Depois de feitas as duas execuções do algoritmo de Dijkstra, pode-se testar se cada

arco pode ou não ser �xado em tempo O(1).

Em princípio, a remoção de um arco pode aumentar a probabilidade de que outros

sejam removidos, mantida a mesma solução dual. Para atualizar os custos reduzidos

estendidos, seria necessário executar mais duas vezes o algoritmo de Dijkstra. No entanto,

como as modi�cações ocorrem muito raramente, não foi feito o recálculo na implementação

realizada.

6.1.4.5 Melhorando as Condições de Fixação

É possível melhorar ainda mais as condições para �xação por custo reduzido. Suponha

que se deseje fazer a �xação por custo reduzido do arco (u; v), como no exemplo da Figura

6.1.

No cálculo do caminho mínimo entre v e t (seguindo a mesma notação utilizada até

aqui), utilizam-se custos reduzidos corrigidos para os demais arcos. De acordo com a

Equação 6.5, o valor do custo reduzido corrigido de um arco (i; j) qualquer é

�c

0

(i; j) = �c

(i; j)�maxf0; p

j

� p

i

g;

sendo p

i

e p

j

os potenciais dos vértices i e j ao �nal da execução do algoritmo de Dijkstra

com raiz em r.

Na verdade, se esse custo reduzido for utilizado apenas para a tentativa de eliminação

de (u; v), pode-se utilizar a seguinte expressão alternativa:

�c

0

(i; j) = �c

(i; j)�maxf0;minfp

u

; p

j

g � p

i

g: (6.7)

Page 104: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 92

Essa expressão leva em conta o fato de que o algoritmo inicial de Dijkstra (com raiz

em r) tem o objetivo apenas de encontrar um conjunto de cortes entre r e u. Todos

os cortes adicionados depois que u é alcançado são irrelevantes e podem ser ignorados.

O fato de o vértice j ter potencial p

j

maior que p

u

(o potencial do vértice u) indica que

foram adicionados cortes depois que u foi alcançado. Os cortes podem ser desconsiderados

e o potencial de u pode ser utilizado no lugar do potencial de j para o cálculo do custo

reduzido corrigido de (i; j). Repare que, se p

u

� p

j

, nada muda em à Equação 6.5. Por

outro lado, se p

i

� p

u

, nenhuma correção precisa ser feita: o custo reduzido original é

utilizado.

A nova expressão para o custo reduzido corrigido aumenta a probabilidade de �xação

de um arco. Entretanto, por ser dependente do arco que se deseja �xar, um algoritmo

baseado nessa expressão requereria execuções especí�cas do algoritmo de Dijkstra, uma

associada a cada arco que se tenta �xar. Deixa de ser possível realizar uma execução

�global� do algoritmo, como proposto na Seção 6.1.4.4. Resultados preliminares mostram

que são raras as situações em que a Equação 6.7 permite a �xação de um arco e a Equação

6.5 não permite. Em vista disso, os experimentos computacionais descritos neste e no

próximo capítulo utilizam o algoritmo mais rápido, basados na Equação 6.5.

6.2 Dual Ascent

Em [65], Wong propõe uma heurística construtiva para obter de forma combinatória so-

luções duais viáveis de boa qualidade para o problema de Steiner em grafos. O algoritmo

se baseia na formulação por multi�uxos para o problema [8, 65], que é equivalente à for-

mulação baseada em cortes direcionadas. Apresenta-se aqui uma adaptação do algoritmo

para a formulação por cortes direcionados.

O algoritmo trabalha com dois grafos direcionados: G, o grafo original, e G

, subgrafo

de G contendo apenas os arcos saturados em relação à solução dual � (o grafo de satu-

ração). G permanece imutável ao longo de todo o algortimo; a G

são adicionados novos

arcos no decorrer da execução.

Um conceito essencial no algoritmo de Wong é o de componente-raiz . Seja R uma

componente fortemente conexa de G

e seja V (R) o conjunto de vértices de R. R será

uma componente-raiz se obedecer simultanemente às seguinte condições:

1. V (R) contém pelo menos um terminal;

2. V (R) não contém a raiz r;

3. não existe um caminho em G

de um terminal t 62 R até R.

É necessário de�nir algumas outras estruturas relacionadas a uma componente-raiz R.

De�ne-se w(R) como o conjunto dos vértices que alcançam R em G

, incluindo os próprios

Page 105: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 93

vértices de R. O conjunto de arcos incidentes em w(R) (partindo de V n w(R)) é repre-

sentado por �

(w(R)). A variável dual associada ao corte de�nido por w(R) é denotada

por �

w(R)

.

A Figura 6.2 apresenta o pseudocódigo do algoritmo de Wong. O algoritmo pode ser

aplicado sobre qualquer solução dual viável �. Em [65], utiliza-se sempre uma solução

nula (� = 0); em alguns dos algoritmos propostos nas próximas seções, nem sempre isso

ocorre.

01 function DUAL_ASCENT (�) {

02 inicialize G

com os arcos saturados em relação a �;

03 while (existe uma componente-raiz R em G

) {

04 W w(R);

05 aumente �

W

até que algum arco em �

(W ) �que saturado;

06 adicione a G

os novos arcos saturados;

07 }

08 return �;

09 }

Figura 6.2: Dual Ascent

Considere que � = 0 no início. Como todas as variáveis duais são nulas, não há arcos

saturados em G e G

não contém arco algum. Nesse momento, cada terminal (exceto

a própria raiz) é uma componente-raiz. Em cada iteração, o algoritmo escolhe uma

componente-raiz e aumenta o valor da variável dual a ela associada até que pelo menos

um arco esteja saturado. Portanto, a cada iteração pelo menos um novo arco é adicionado

a G

, o que pode provocar o aumento de algumas componentes-raízes e/ou a destruição

de algumas outras (em razão de passarem a ser alcançáveis a partir de terminais). Ao

�nal de no máximo O(jEj) iterações, todos os terminais serão alcançáveis a partir de r

em G

. Não havendo mais componentes-raízes, o algoritmo termina.

6.2.1 Soluções Primais

Depois de terminada a execução do dual ascent, haverá pelo menos um caminho da raiz r a

qualquer terminal em G

. Essa é justamente a condição de parada do algoritmo. Em [65],

Wong sugere um método para extrair de G

um subgrafo (arborescência) que representa

uma solução primal de boa qualidade. Inicialmente, determina-se a arborescência de peso

mínimo do subgrafo de G

induzido pelos vértices que podem ser alcançados a partir da

raiz. Seja A a árvore (não-orientada) correspondente a essa arborescência. Removem-se

de A todos os vértices não-terminais de grau 1, bem como as arestas neles incidentes.

Repete-se o processo de remoção até que todas as folhas da árvore sejam terminais.

O algoritmo utilizado para encontrar a arborescência de peso mínimo é o próprio dual

Page 106: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 94

ascent proposto por Wong. Quando aplicado sobre um grafo em que todos os vértices são

terminais, a heurística de Wong comporta-se exatamente como o algoritmo de Edmonds

[17] para a arborescência de peso mínimo. A única diferença é o fato de que, depois

de encontrar a solução dual, o algoritmo de Edmonds realiza um reverse delete step.

Esse procedimento consiste em remover os arcos de G

na ordem inversa em que foram

saturados, tomando-se o cuidado de não desconectar o grafo. Claramente, o resultado

desse procedimento é uma arborescência. E, nesse caso, pode-se provar que ela tem peso

mínimo.

O procedimento para obtenção de soluções primais utilizado nos experimentos deta-

lhados na Seção 6.2.4 é mais simples que o proposto por Wong. Em vez de se calcular

a arborescência mínima de G

, realiza-se um reverse delete step diretamente sobre G

.

Nesse caso, no entanto, não se exige que todo o grafo G

permaneça conexo; exige-se

apenas que sejam preservados caminhos da raiz a todos os terminais do grafo. O re-

sultado será uma arborescência contendo todos os terminais. A qualidade das soluções

primais obtidas por esse método é bastante satisfatória, especialmente quando a solução

dual encontrada pelo algoritmo é de boa qualidade. Para tornar as soluções primais ainda

melhores, podem ser usados métodos de busca local (como os apresentados no Capítulo 4)

sobre a árvore (não-orientada) correspondente à arborescência.

6.2.2 Implementação

Em cada iteração do dual ascent, pelo menos um arco é saturado. Haverá, portanto, no

máximo O(jEj) iterações. Em cada uma delas é gerado um novo corte. Todos os arcos

são investigados para que se determine o valor do corte. Como cada corte é composto por

até O(jEj) arcos, a complexidade do algoritmo como um todo é O(jEj

2

). É essa também

a complexidade do reverse delete step implementado (para cada aresta, faz-se uma busca

em profundidade para determinar se ela pode ser retirada).

Na prática, o pior caso do dual ascent é extremamente raro. Em primeiro lugar, a

parcela dos cortes que contêm um número de arcos proporcional a jEj é normalmente

pequena. Além disso, para acelerar a convergência do algoritmo, é conveniente, ao se

aumentar em � unidades o valor dual de um corte, que se considere saturado todo arco

a (do corte) cujo custo reduzido (antes do aumento) tenha valor �c � �+ ", sendo " uma

constante não-negativa. Com isso, mais arcos serão saturados em cada iteração; se " for

signi�cativamente pequeno em relação ao valor médio dos arcos, as soluções obtidas serão

tão boas quanto as soluções �reais�.

Quando todos os custos são inteiros, usar " = 0 já pode ser muito vantajoso. Nesse

caso, garante-se que o número de iterações nunca será maior que o valor da relaxação

linear L do problema. A�nal, em cada iteração o valor da solução dual subirá no mínimo

uma unidade.

3

A relevância dessa observação pode ser con�rmada com exemplos concre-

3

Na verdade, para que o número de iterações seja limitado a bLc é necessário que a solução dual

inicial tenha custos reduzidos inteiros. Se os custos originais forem inteiros mas o dual ascent estiver

Page 107: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 95

tos. A instância e16 (OR-Library), por exemplo, tem 62500 arestas, mas o valor de sua

solução ótima (um limite superior para a relaxação linear) é 15. Portanto, um dual ascent

executado sobre essa instância não terá mais que 15 iterações. Para outras instâncias, essa

observação é menos relevante: a instância i640-301 (Incidência) tem apenas 960 arestas,

mas o valor de sua solução ótima é 45005. Como regra geral, o dual ascent tende a ser

mais rápido para instâncias com arcos de valor pequeno.

6.2.3 Seleção da Componente-raiz

O pseudocódigo apresentado na Figura 6.2 exige que em cada iteração seja escolhida

uma componente-raiz, mas não especi�ca exatamente qual deve ser a escolhida. Em [65],

Wong não recomenda qualquer critério de seleção. A rigor, isso de fato não é necessário,

pois o algoritmo estará correto independentemente do critério de escolha. Ao �nal da

execução, haverá uma solução dual viável maximal (i.e., com caminhos saturados da raiz

até qualquer outro terminal) e, portanto, será possível calcular um limite inferior para o

problema. No entanto, não basta encontrar um limite inferior, deseja-se que ele seja tão

bom quanto possível. A Seção 6.2.4 mostra que o critério de escolha das componentes-

raízes tem in�uência direta sobre a qualidade das soluções obtidas. Foram testados os

seguintes critérios (os nomes são dados em inglês seguindo a nomenclatura já adotada em

[44]):

� random: Escolhe-se qualquer das componentes-raízes com igual probabilidade.

� �rst: Percorre-se a lista de vértices em ordem até que se encontre um vértice que

faz parte de uma componente-raiz, que é a escolhida.

� circular: Similar ao critério anterior, mas a busca na lista numa determinada iteração

é feita a partir do vértice seguinte ao selecionado na iteração anterior (quando se

chega ao �nal da lista, retorna-se ao começo).

� minarcs/maxarcs: Seleciona-se a componente-raiz que determina o corte com menor

(maior) número de arcos.

� minvalue/maxvalue: Escolhe-se a componente-raiz que determina o corte de menor

(maior) valor, ou seja, dentre todos os cortes, aquele cujo arco de menor custo

reduzido tem valor mínimo (máximo).

� minsaturated/maxsaturated: A componente-raiz que determina o corte com menor

(maior) número de arcos saturados é selecionada.

sendo executado sobre uma solução dual fracionária, apenas o limite superior de O(jEj) para o número

de iterações será válido.

Page 108: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 96

Implementação Usando um dos três primeiros critérios sugeridos (random, �rst e cir-

cular), a complexidade do dual ascent permanece sendo O(jEj

2

), já que a escolha de uma

componente-raiz por qualquer desses critérios pode ser feita em tempo O(jV j).

Na implementação dos demais critérios, a complexidade aumenta para O(jT jjEj

2

).

Esses métodos requerem informações sobre todos os cortes que podem ser escolhidos

numa iteração, não apenas sobre o que de fato é selecionado. Cada uma das O(jT j)

componentes-raízes determina um corte, e o processamento de cada corte requer que

sejam examinados os até O(jEj) arcos que o compõem. A complexidade de cada uma das

O(jEj) iterações, portanto, pode chegar a O(jT jjEj).

Na prática, contudo, a deterioração no desempenho não é tão grave, mesmo quando o

número de terminais é grande. Para isso, é conveniente armazenar as informações sobre

todos os potenciais cortes ao invés de simplesmente recalculá-las em cada iteração. Uma

vez selecionado um corte numa iteração, uma simples busca em profundidade no grafo de

saturação (G

) pode determinar quais componentes-raízes são potencialmente �afetadas�.

Apenas para essas componentes é necessário recalcular o valor, o número total de arcos e o

número de arcos que seriam saturados caso o corte correspondente fosse escolhido. Essas

componentes também são as únicas candidatas à fusão com outras componentes ou ao

desaparecimento (i.e., podem deixar de ser componentes-raízes). Cabe ressaltar que essa

é uma heurística para aceleração do algoritmo; no pior caso, todas as O(jT j) componentes

podem ser afetadas pela saturação de um corte, o que signi�ca que o algoritmo pode

chegar a fazer a O(jT jjEj

2

) operações.

6.2.4 Resultados Experimentais

Para analisar o comportamento do algoritmo de dual ascent na prática, ele foi executado

sobre as instâncias apresentadas na Seção 2.4.2. Da classe PUC, foram testadas todas

as instâncias; das classes OR-Library e VLSI, foram consideradas as instâncias não re-

solvidas pelo pré-processamento; das instâncias de Incidência, foram testadas apenas as

80 terminadas em �1�.

Cada execução é composta por uma série de operações. Inicialmente, executa-se um

dual ascent. Em seguida, obtém-se uma solução primal com um reverse delete step seguido

de uma busca local do tipo NP. Finalmente, a solução dual encontrada pelo dual ascent

e o limite primal são utilizados na execução da rotina de �xação por custos reduzidos

descrita na Seção 6.1.4.4.

Para cada instância, foram testados os nove critérios de escolha de componentes-raízes

sugeridos na Seção 6.2.3. Para os critérios minarcs, maxarcs, minsaturated, maxsaturated,

minvalue e maxvalue, podem ocorrer empates entre duas componentes-raízes durante a

execução do algoritmo; os desempates foram feitos de forma aleatória.

A Tabela 6.1 mostra os resultados obtidos para cada classe de instâncias. As medidas

apresentadas na tabela são as seguintes:

Page 109: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 97

classe critério gap (%) inst. redução tempo

média max resolv. (%) (s)

�rst 10.516 31.852 1 15.55 2.68

circular 3.241 11.390 15 49.40 6.09

random 3.790 14.301 14 43.31 6.23

minvalue 10.713 28.303 1 15.35 3.49

Incidência maxvalue 4.199 14.109 12 39.21 28.96

minarcs 2.684 13.368 14 51.96 22.54

maxarcs 11.765 30.864 0 13.84 3.43

minsaturated 4.155 13.295 9 41.07 20.36

maxsaturated 5.489 21.489 6 34.28 9.93

�rst 2.904 14.286 18 65.75 0.51

circular 2.047 18.182 27 74.03 0.55

random 1.690 14.286 24 67.88 0.51

minvalue 2.717 17.241 16 60.05 0.52

OR-Library maxvalue 1.853 13.043 26 72.68 0.50

minarcs 0.621 5.556 33 81.05 0.39

maxarcs 4.705 25.000 14 58.21 0.55

minsaturated 0.898 15.385 33 80.66 0.40

maxsaturated 3.953 30.769 16 63.99 0.61

�rst 18.616 31.710 0 0.00 28.42

circular 14.962 27.329 0 0.00 27.92

random 16.025 28.659 0 0.00 30.64

minvalue 19.365 34.446 0 0.00 31.54

PUC maxvalue 16.907 31.034 0 0.01 42.74

minarcs 12.322 21.053 0 0.00 44.51

maxarcs 19.550 32.496 0 0.00 33.74

minsaturated 13.748 21.870 0 0.00 40.64

maxsaturated 18.344 30.189 0 0.00 33.69

�rst 1.628 15.078 20 44.28 12.23

random 1.367 3.929 13 43.27 10.77

circular 1.199 3.799 15 45.55 9.27

minvalue 2.499 11.196 11 32.78 11.89

VLSI maxvalue 1.326 4.799 14 42.48 11.55

minarcs 1.246 3.945 15 46.69 9.71

maxarcs 2.447 15.084 15 35.44 12.93

minsaturated 1.273 4.597 16 46.21 11.35

maxsaturated 1.609 6.006 13 40.92 12.87

Tabela 6.1: Critérios para escolha da componente-raiz por classe

Page 110: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 98

� Gap de dualidade (gap): Diferença percentual entre os valores primal e dual

obtidos pelo próprio algoritmo (a solução ótima não é levada em consideração). Em

cada classe, são apresentados tanto o valor médio quanto o valor máximo observado

para o gap.

� Instâncias resolvidas (inst. resolv.): Número de instâncias resolvidas à oti-

malidade, ou seja, instâncias para as quais o limite superior (primal) e o limite

inferior (dual) foram iguais.

� Redução percentual média do número de arcos (redução): Porcentagem

do total de arcos eliminada pela �xação por custos reduzidos (considera-se o valor

médio para todas as instâncias da classe). Quando uma instância é resolvida à

otimalidade, considera-se que houve uma redução de 100%.

� Tempo de execução (tempo): Tempo médio de execução em segundos. Con-

sidera toda a execução do algoritmo (dual ascent, reverse delete step, busca local e

�xação por custos reduzidos). Os tempos se referem a execuções feitas em um AMD

K6-2 de 350 MHz.

A Tabela 6.2 mostra as mesmas medidas, mas considera todas as 264 instâncias tes-

tadas. Para tornar mais simples a análise, nessa tabela os métodos estão ordenados

de acordo com a redução percentual média obtida (os algoritmos mais e�cazes são os

primeiros).

critério gap (%) inst. redução tempo

média max resolv. (%) (s)

minarcs 3.645 21.053 62 46.86 18.17

circular 4.608 27.329 57 44.24 9.96

minsaturated 4.428 21.870 58 43.34 17.26

random 4.947 28.659 51 40.40 10.94

maxvalue 5.261 31.034 52 39.96 20.35

maxsaturated 6.460 30.769 35 36.14 13.27

�rst 7.814 31.852 39 31.83 9.87

minvalue 8.230 34.446 28 27.18 10.61

maxarcs 8.997 32.496 29 27.10 11.32

Tabela 6.2: Critérios para escolha da componente-raiz (todas as instâncias testadas)

Critérios Analisando-se a Tabela 6.2, observa-se que o critério de escolha da componen-

tes-raízes tem grande in�uência sobre a e�ciência do dual ascent. Veri�ca-se que minarcs

é o melhor dos critérios testados, com desempenho próximo ao dos métodos circular e

minsaturated. Isso indica que os métodos de maior qualidade tendem a ser os que buscam

Page 111: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 99

adiar ao máximo a �destruição� das componentes-raízes. Uma componente-raiz deixa de

ser componente-raiz (é �destruída�) quando passa a ser alcançável em G

por um terminal.

Para que isso ocorra, é necessário que novos arcos sejam adicionados a G

.

O método minarcs tenta justamente evitar isso, adicionando o número mínimo possível

de arcos em cada iteração. Os métodos circular, minsaturated, random e maxvalue fazem

o mesmo, mas de forma indireta. Os métodos circular e random executam um crescimen-

to mais ou menos equilibrado das componentes-raízes, evitando a criação prematura de

grandes componentes, indesejáveis porque induzem cortes com muitos arcos (isso é jus-

tamente o contrário do que faz o critério �rst). O critério random tem comportamento

similar. O critério minsaturated possui boa qualidade principalmente para as instâncias

em que muitas arestas têm custos semelhantes, como OR-Library, VLSI e parte da solução

PUC; nesses casos, o algoritmo acaba se comportando de maneira muito semelhante a mi-

narcs. O método maxvalue também é de certa forma uma aproximação de minarcs. Tudo

mais permanecendo igual, o valor de um corte (o critério de seleção de maxvalue) tende a

diminuir à medida que aumenta o número de arcos por ele interceptados; a�nal, o valor

do corte é determinado pelo arco de custo reduzido mínimo.

Privilegiar cortes com poucos arcos em cada iteração tem como efeito, além do aumento

da qualidade das soluções obtidas, um aumento também no tempo de execução. Isso se

explica pelo fato de o número de iterações tender a ser maior, já que a �destruição� de

componentes-raízes é executada. Na média, o tempo de execução do método minarcs é

quase o dobro do observado para o método maxarcs.

Quanto à diferença entre os métodos �rst, circular e random (de complexidade O(jEj

2

))

e os demais (de pior caso O(jT jjEj

2

)), ela existe, mas não é tão dramática quanto sugerem

as expressões de complexidade. Na média, o método minarcs é executado em tempo igual

ao dobro do requerido por circular; para o método maxarcs, por outro lado, a diferença

é de apenas 20%, aproximadamente. Isso mostra que o número de iterações do método

pode ser até mais importante que o fator jT j na complexidade.

No restante deste capítulo e no próximo emprega-se um critério híbrido entre os mais

promissores: o critério primário é minarcs; em caso de empate, utiliza-se minsaturated;

persistindo a igualdade, a escolha �nal é feita aleatoriamente.

Qualidade da Solução Quando se utilizam os melhores critérios, a e�ciência do dual

ascent é bastante satisfatória. Os resultados do algoritmo, não por acaso, tendem a ser

melhores para instâncias que possuem gap de dualidade real pequeno. Considera-se �real�

o gap medido pela comparação entre a relaxação linear e o valor ótimo de cada solução;

não é esse o valor a que se refere a tabela. Das classes estudadas, as que possuem menor

gap médio são OR-Library e VLSI (veja [32] e [58], por exemplo). São justamente as que

apresentaram a menor diferença percentual entre os limites dual e primal obtidos pelo

dual ascent.

As instâncias de Incidência, apesar de possuírem gaps um pouco maiores, apresentam

Page 112: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 100

reduções bastante expressivas no número de arcos. Isso é resultado do fato de maior

comprimento médio dos arcos nesses casos, o que facilita a �xação.

Os piores resultados foram obtidos para as instâncias PUC. Isso já era esperado, uma

vez que essas instâncias foram criadas justamente com o propósito de desa�ar os melhores

algoritmos conhecidos para o problema de Steiner em grafos [51]. Ainda assim, a diferença

percentual média entre as soluções primais e duais obtidas com o melhor critério (minarcs)

foi de apenas 12%, um valor pequeno se considerarmos a natureza especial das instâncias.

6.3 Outras Heurísticas Duais

Apesar de as soluções fornecidas pelo algoritmo de dual ascent puro terem excelente

qualidade, especialmente se forem utilizados os critérios mais e�cazes, é possível melhorá-

las ainda mais. Nesta seção, são propostas três técnicas que tentam, heuristicamente,

atingir dois objetivos relacionados: aumentar o valor da solução dual encontrada e reduzir

o tamanho das instâncias de teste através de �xações por custos reduzidos. Trata-se das

técnicas de dual scaling, dual adjustment e �xação ativa.

6.3.1 Dual Scaling

O primeiro método implementado para melhorar as soluções fornecidas pelo dual ascent foi

o scaling das variáveis duais. Uma solução fornecida pelo dual ascent é maximal , ou seja,

é impossível aumentar o valor dual de qualquer corte (inclusive os que possuem valor nulo)

sem tornar negativo o custo reduzido de algum arco e por conseguinte tornar a solução

inviável. Dada uma solução dual viável maximal �, o dual scaling consiste em multiplicar

os valores de todas as variáveis duais por um mesmo fator constante e menor que 1. Dessa

forma, obtém-se uma nova solução dual, que é viável mas não maximal. Pode-se então

aplicar DUAL_ASCENT sobre ela, o que leva a uma nova solução �

, potencialmente

melhor que �. Esse método pode ser iterado repetidas vezes. A Figura 6.3 apresenta um

pseudocódigo para esse método.

Na prática, essa estratégia não teve um bom desempenho. São pouquíssimas as ins-

tâncias para a aplicação do scaling eleva signi�cativamente o valor da solução dual. Além

disso, esse método tem um �efeito colateral�: ele aumenta muito o número de cortes não-

nulos na solução dual (note que a técnica só adiciona cortes à solução, jamais os retira).

O excesso de cortes pode tornar lenta a aplicação de outras heurísticas duais, além de

aumentar a demanda por memória.

No entanto, o aumento no número de cortes tem um efeito positivo em uma situação

especí�ca: quando a solução dual obtida é utilizada como conjunto inicial de cortes na

resolução exata da relaxação linear (utilizando-se um resolvedor de programas lineares

como o CPLEX [29]). Mesmo utilizando os mesmos cortes, a primeira solução dual obtida

pelo resolvedor tende a ser muito melhor que a obtida pelas heurísticas duais, já que o

Page 113: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 101

01 function DUAL_SCALING (�) {

02 �

�;

03 for it 1 to itmax do {

04 � DUAL_ASCENT (� � �);

05 if (v(�) > v(�

)) then �

�;

06 else return �

;

07 }

08 return �

;

09 }

Figura 6.3: Dual Scaling

resolvedor pode atribuir valores duais diferentes a eles.

Uma das raras situações em que o algoritmo é bem-sucedido é a instância e18, consi-

derada a mais difícil da classe OR-Library. O valor de sua solução ótima é 564 e o valor

fornecido pelo dual ascent, 551. Aplicando-se dez iterações de scaling com � = 0:875,

obtém-se uma solução de valor 556.55. A solução obtida é melhor, mas utiliza 2137 cortes

com valor não nulo, cerca de quatro vezes mais que a solução original. Mudando os valores

duais atribuídos a esses cortes, o resolvedor é capaz de encontrar uma solução dual de

valor 561.49, bastante próxima do ótimo (e utiliza apenas aproximadamente 828 cortes,

descartando 1309, considerados redundantes). Prosseguindo a rotina de separação, a oti-

malidade da solução (564) pode ser provada em 191 segundos (em uma Sun Ultra 1 de

167 MHz). Se apenas a solução do dual ascent for utilizada para inicializar o programa

linear, o tempo total sobe para 391 segundos. Nesse caso, o dual scaling é realmente útil.

Infelizmente, é um dos poucos: para a grande maioria das instâncias testadas o scaling

é incapaz de elevar o valor da solução dual inicial e o número excessivo de cortes muitas

vezes retarda a solução do programa linear.

6.3.2 Dual Adjustment

O procedimento de dual adjustment pode ser entendido como um método de busca local

para soluções duais. Seja � uma solução dual viável (normalmente maximal). Uma solução

vizinha é obtida retirando-se de � um ou mais cortes (tornando nulos seus valores duais)

e, em seguida, executando-se a rotina DUAL_ASCENT sobre a solução resultante. Numa

aplicação bem-sucedida dessa operação, a solução obtida terá valor maior que a solução

inicial.

Em princípio, qualquer subconjunto de cortes pode ser escolhido para retirada. No en-

tanto, observou-se que um conjunto particularmente interessante é o formado pelos cortes

que interceptam uma solução primal de boa qualidade mais de uma vez. De acordo com

as restrições de complementaridade de folga (Seção 6.1.3), se a solução primal utilizada

Page 114: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 102

for ótima e não houver gap de dualidade, os cortes retirados com certeza não fazem parte

da solução. Uma extensão desse raciocínio para os casos não ideais (soluções sub-ótimas

e/ou instâncias com gap) mostrou-se relativamente e�ciente na prática, conforme se verá

na Seção 6.3.4.

01 function DUAL_ADJUSTMENT (�, x

r

) {

02 �

�;

03 repeat {

04 Para todo �

W

> 0 tal que �

(W ) cruza x

r

mais de uma vez, �

W

0;

05 � DUAL_ASCENT(�);

06 faça �xação por custos reduzidos em �;

07 if (v(�) > v(�

)) then �

�;

08 else return �

;

09 } forever;

10 }

Figura 6.4: Dual Adjustment

O pseudocódigo para o DUAL_ADJUSTMENT é apresentado na Figura 6.4. Os dois

parâmetros básicos de entrada são a solução dual (�) e uma solucão primal de referência

(x

r

), em sua versão orientada (com as arestas tranformadas em arcos e utilizando a mesma

raiz utilizada pela solução dual).

Repare que, enquanto o procedimento for bem-sucedido, ele se repete com as novas

soluções duais geradas. Para cada nova solução, seja ela melhor ou pior que a original, é

interessante �xar por custos reduzidos do maior número possível de variáveis.

6.3.3 Fixação Ativa

Como o próprio nome sugere, a �xação ativa é um procedimento que tem como principal

objetivo aumentar o número de arcos eliminados (�xados em zero) por custos reduzidos.

De acordo com as Condições 6.1 e 6.6, a probabilidade de um arco x

a

ser eliminado

cresce com o aumento de seu custo reduzido. O custo reduzido será máximo (igual ao

comprimento do arco) quanto todos os cortes que interceptam o arco a tiverem custo dual

igual a zero; em outras palavras, quando não houver corte algum interceptando o arco.

A �xação ativa é um procedimento que utiliza o dual ascent para gerar uma solução

dual de boa qualidade que garante essa condição para algum arco a. Quando executado

a partir de uma solução dual nula, a implementação do procedimento é simples: dado o

arco a, basta inseri-lo no grafo �saturado� G

(isso equivale à adição da restrição x

a

= 1).

Executando o algoritmo de dual ascent sobre o grafo G, será obtida uma solução dual que

garantidamente não utiliza cortes que interceptam o arco a.

O método pode também ser aplicado a partir de uma solução dual inicial � viável e

Page 115: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 103

não-nula. Basta que todos os cortes que interceptam a em � sejam previamente retirados

da solução (ou seja, tenham seu valor reduzido a zero). Note que isso pode resultar em

alterações no grafo G

. Feito isso, adiciona-se a G

o arco a e executa-se o dual ascent

normalmente.

Independentemente da solução inicial, pode-se garantir que a solução �nal será dual

viável. Portanto, podem-se fazer �xações por custos reduzidos sem problemas. É claro que

o intuito é �xar o próprio a a zero; entretanto, uma análise empírica desse procedimento

mostrou que é interessante testar também os demais arcos. Em muitos casos, vários

deles são �xados. São comuns também os casos em que a solução obtida pela �xação

ativa é melhor que a obtida pelo dual ascent �livre� (sem restrições quanto aos arcos que

podem ser utilizados). Nesse caso, a �xação ativa acaba atuando como um método de

dual adjustment.

O pseudocódigo para todo o procedimento é apresentado na Figura 6.5. Observe que

resta ainda discutir dois detalhes do algoritmo: o critério de parada (linha 03) e o critério

de escolha do arco testado em cada iteração (linha 04).

01 function ACTIVE_FIXATION (�) {

02 �

�;

03 while (critério de parada) {

04 escolha um arco a;

05 �

0

f�

n �

W

; 8W tal que a 2 �

W

g;

06 insira a em G

0

;

07 � DUAL_ASCENT (�

0

);

08 faça �xação por custos reduzidos em �;

09 if (v(�) > v(�

)) then �

�;

10 }

11 return �

;

12 }

Figura 6.5: Fixação Ativa

Comecemos pela escolha dos arcos. Sendo � a solução inicial, consideram-se apenas

os arcos cujos custos são superiores ao gap entre a melhor solução primal conhecida e �.

Entre esses arcos, a prioridade é dada àqueles interceptados em � por um conjunto de

cortes de pequeno valor dual total. A�nal, são esses os arcos mais próximos da �xação.

Quanto ao critério de parada, na verdade foram utilizados diversos critérios simul-

taneamente. Em pricípio, não se permitiu que uma única execução do algoritmo acima

superasse dez segundos. Há uma única exceção. Quando o dual ascent da linha 07 encon-

tra uma solução melhor que a original, permite-se que o algoritmo seja executado por mais

dez segundos. Outro critério de parada utilizado é o número de execuções mal-sucedidas:

se forem executadas diversas iterações sem sucesso (i.e., sem que nenhum arco seja elimi-

nado) o algoritmo é interrompido, mesmo que não tenham se passado dez segundos. Nos

Page 116: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 104

testes realizados, permitiu-se que o algoritmo tivesse no máximo duas falhas inicialmente;

além disso, a cada duas iterações de sucesso, dá-se um �crédito� extra ao algoritmo. Na

prática, portanto, o número de falhas pode ser maior, desde que seja no máximo igual à

metade do número de iterações bem-sucedidas.

A limitação de tempo é um tanto arbitrária, mas fez-se necessária. Para muitas instân-

cias grandes, o algoritmo é e�caz � ou seja, consegue efetuar a �xação do arco selecionado

�, mas muito lento. Observou-se na prática que é mais conveniente interromper o al-

goritmo e, por exemplo, executar outro algoritmo ou mesmo dividir o problema em dois

subproblemas, conforme será discutido na Seção 7.3.

6.3.4 Resultados Experimentais

Nesta seção, apresentam-se resultados empíricos que demonstram a e�ciência das heurís-

ticas duais apresentadas. Foram utilizadas nos testes aqui apresentados as mesmas ins-

tâncias testadas na Seção 6.2.4: instâncias de Incidência terminadas em �1�, PUC, VLSI

e OR-Library (sendo as duas últimas séries consideradas após o pré-processamento).

Foram analisadas três diferentes estratégias de combinação das heurísticas duais.

A primeira estratégia é semelhante à testada na Seção 6.2.4: realiza-se um único dual

ascent, seguido de um reverse delete step com busca local NP e da �xação por custos

reduzidos (em relação à solução obtida pelo dual ascent).

A segunda estratégia analisada também utiliza apenas o dual ascent como heurística

dual, mas de forma iterada. Executa-se inicialmente o ciclo mais simples (dual ascent,

reverse delete step, busca local e �xação por custos reduzidos). Se a redução no tamanho

da instância for menor que 1% ou igual a 100% (i.e., se a instância for resolvida), o

algoritmo pára; caso contrário, executam-se novamente os mesmos algoritmos. Repare que

as execuções posteriores podem aproveitar as reduções e os limites primais encontrados

nas iterações anteriores. As iterações se sucedem enquanto houver reduções signi�cativas

(de pelo menos 1%) e o problema não for resolvido.

A terceira estratégia testada utiliza os métodos de dual adjustment e �xação ativa para

tentar melhorar os resultados obtidos pela segunda estratégia. Inicialmente, executam-se

os algoritmos da segunda estratégia. Caso a instância não seja completamente resolvida,

aplica-se um dual adjustment sobre a melhor solução dual encontrada e, em seguida,

executa-se a rotina de �xação ativa. Se a �xação ativa conseguir uma redução superior

a 1%, repete-se todo o algoritmo (a menos que a instância seja completamente resolvida,

evidentemente).

Em todos os testes, na execução do dual ascent, seja como heurística construtiva

dual, seja como sub-rotina do dual adjustment e da �xação ativa, foi utilizado o critério

minarcs para seleção das componentes-raízes, sendo minsaturated e random (nessa ordem)

os critérios de desempate.

Page 117: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 105

A Tabela 6.3 mostra os resultados obtidos pelas três estratégias. As medidas são as

mesmas utilizadas nas Tabelas 6.1 e 6.2. No cálculo do gap, consideram-se a melhor

solução primal e a melhor solução dual obtidas ao longo de toda a execução.

algoritmo classe gap (%) inst. redução tempo

média max resolv. (%) (s)

Incidence 2.767 8.815 14 51.02 23.01

dual ascent OR-Library 0.820 15.385 37 83.89 0.42

(uma execução) PUC 12.675 21.053 0 0.00 44.32

VLSI 1.195 4.932 15 47.97 10.73

Total 3.765 21.053 66 47.56 18.59

Incidence 1.740 7.708 38 62.46 38.10

dual ascent OR-Library 0.287 5.505 51 89.48 0.47

(várias execuções) PUC 12.675 21.053 0 0.00 44.80

VLSI 0.782 4.932 37 65.52 11.67

Total 3.218 21.053 126 57.36 23.54

Incidence 1.647 7.708 40 64.88 46.91

dual ascent OR-Library 0.251 4.587 51 89.48 0.56

+ adjustment PUC 11.882 21.053 0 0.01 66.02

+ �xação ativa VLSI 0.652 4.932 46 71.50 16.52

Total 2.994 21.053 137 59.84 31.66

Tabela 6.3: Resultados obtidos pelas heurísticas duais

Observe que a aplicação iterada do dual ascent obtém resultados muito superiores aos

obtidos por uma única aplicação do algoritmo e faz isso sem requerer aumentos signi-

�cativos no tempo de execução. As novas heurísticas duais sugeridas (dual adjustment

e �xação ativa) contribuem para aumentar ainda mais a qualidade das soluções obtidas,

também sem aumentos expressivos no tempo de execução.

Repare, no entanto, que o uso de heurísticas duais mais elaboradas é e�caz apenas para

as instâncias que possuem gap de dualidade relativamente pequeno. Para as instâncias

PUC, criadas justamente com o objetivo de desa�ar algoritmos baseados em dualidade, a

repetição do dual ascent não tem qualquer efeito (até porque nem chega a ser feita, já que

em nenhuma instância a primeira execução obtém reduções maiores que 1%). As novas

heurísticas duais conseguem melhorar ligeiramente os resultados obtidos, mas de forma

marginal.

6.4 Conclusão

O algoritmo básico discutido neste capítulo é o dual ascent, uma heurística dual para o

problema de Steiner em grafos. Por sua natureza, seu objetivo principal é fornecer bons

limites inferiores para o problema. No entanto, ele tem um subproduto, uma solução

Page 118: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 6. ALGORITMOS DUAIS 106

primal, em geral de boa qualidade. O resultado da interação entre esses dois elementos (um

limite inferior e um limite superior) é um método poderoso para a resolução do problema

de Steiner em grafos. Para boa parte das instâncias, foi possível provar a otimalidade

das soluções obtidas. Em muitos outros casos, foi possível reduzir signi�cativamente o

tamanho das instâncias por meio da �xação por custos reduzidos. No mínimo, o método é

capaz de fornecer boas soluções primais com garantia de qualidade. Além disso, conforme

se verá no Capítulo 7, as soluções duais fornecidas pelas heurísticas podem ser utilizadas

como ponto de partida para o cálculo exato da relaxação linear do problema.

Foram apresentadas ainda outras heurísticas duais, todas tendo o dual ascent como

sub-rotina: dual scaling, dual adjustment e �xação ativa. Esses métodos, especialmente os

dois últimos, se mostraram úteis para potencializar os efeitos do dual ascent. Com eles foi

possível resolver mais instâncias à otimalidade, eliminar mais arcos por custos reduzidos

e diminuir o gap de dualidade médio obtido.

Um aspecto das heurísticas alternativas que merece um estudo mais detalhado é o tem-

po necessário para sua execução. Da forma como foram propostos, os métodos requerem

a execução de um dual ascent como sub-rotina. Se para o dual adjustment o tempo de

execução é tolerável, para a �xação ativa nem sempre é esse o caso. A�nal, deve-se execu-

tar um dual ascent para cada arco candidato à �xação. Para evitar um aumento maior no

tempo de execução, foram utilizados diversos critérios de parada simultâneos, baseados no

tempo de execução e na e�cácia da estratégia. Uma maneira mais apropriada de lidar com

esse problema seria executar não o dual ascent de Wong como sub-rotina da �xação ativa,

mas um algoritmo mais simples e rápido, semelhante à versão modi�cada do algoritmo de

Dijkstra apresentada na Seção 6.1.4 (um algoritmo com essas características é apresentado

por Polzin e Daneshmand em [46]). Um dual ascent mais rápido tende a fornecer soluções

de pior qualidade quando utilizado como heurística dual construtiva. Entretanto, como

sub-rotina do dual adjustment e da �xação ativa, o método apenas completa uma solução

dual que é quase maximal, o que tende a torná-lo relativamente mais e�ciente.

Outro algoritmo que requer um estudo mais aprofundado é o dual scaling. Na ver-

são apresentada, sua utilidade se limita a algumas poucas instâncias. Seria interessante

estudar variantes do método que o tornassem mais e�ciente ou robusto.

Page 119: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Capítulo 7

Algoritmos Exatos

Este capítulo trata de algoritmos exatos para o problema de Steiner em grafos: algoritmos

capazes de encontrar a solução ótima (e provar sua otimalidade) de qualquer instância

em tempo �nito. Como o problema de Steiner é NP-difícil, os algoritmos propostos são

exponenciais no pior caso. Conforme se verá, no entanto, eles são capazes de resolver

rapidamente grande parte das instâncias apresentadas na Seção 2.4.2, muitas vezes em

frações de segundo; em vários casos, os algoritmos aqui descritos foram os primeiros a

provar a otimalidade da solução.

Os dois algoritmos apresentados são instanciações da técnica de branch-and-bound,

conceito discutido na Seção 7.1. A Seção 7.2 descreve o funcionamento de um dos algo-

ritmos, um branch-and-cut ; a Seção 7.3 trata do segundo, que recebeu a denominação de

branch-and-ascent . Na Seção 7.4, os algoritmos são comparados empiricamente entre si e

com outros métodos descritos na literatura. Finalmente, a Seção 7.5 discute a aplicabili-

dade de cada um dos métodos e possíveis formas de torná-los ainda mais e�cientes.

Conforme mencionado no capítulo anterior, os métodos aqui discutidos foram origi-

nalmente apresentados em [44], artigo escrito em co-autoria com M. Poggi de Aragão e

E. Uchoa. Alguns dos resultados apresentados neste capítulo são discutidos também na

tese de doutorado de E. Uchoa [57].

7.1 Branch-and-bound e Enumeração Implícita

Ambos os algoritmos propostos neste capítulo são do tipo branch-and-bound. Nesta seção,

discute-se brevemente o princípio de funcionamento dessa técnica para problemas de

otimização combinatória em geral. Para uma discussão mais completa, veja [64], por

exemplo.

Um algoritmo de branch-and-bound nada mais é um método de enumeração implícita

de todas as possíveis soluções para a instância de entrada. Ele requer duas rotinas básicas:

107

Page 120: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 108

uma para calcular limites superiores, outra para calcular limites inferiores. Inicialmente,

aplicam-se as rotinas sobre a instância de entrada. Se o limite inferior for igual ao supe-

rior, o algoritmo termina. Se não for esse o caso, faz-se uma rami�cação (ou branching):

o problema é particionado em dois ou mais subproblemas que, juntos, são equivalentes

ao problema original. No caso de um problema de otimização 0-1, a rami�cação é nor-

malmente feita com base no valor de uma variável, a variável de branching , que tem seu

valor �xado em 0 em um dos subproblemas e em 1 no outro. Cada subproblema é re-

solvido recursivamente. A melhor solução encontrada para os subproblemas é a solução

do problema original.

Observe que o branch-and-bound constrói uma árvore de resolução durante sua exe-

cução. Cada nó da árvore dá origem a dois ou mais nós-�lhos, a menos que os limites

inferior e superior coincidam. Nesse caso, o subproblema estará resolvido. Diz-se que o

ramo que tem esse nó como raiz foi podado, ou que se fez o pruning do nó.

Assim sendo, o número de nós efetivamente visitados na árvore (que é exponencial no

pior caso) depende da qualidade dos limites inferiores e superiores calculados ao longo da

execução do algoritmo. Com limites melhores, o número de rami�ções feitas até que se

possa fazer um pruning é menor.

Os dois algoritmos apresentados nesse capítulo usam como limites inferiores soluções

duais para a relaxação linear da formulação por cortes direcionados, decrita na Seção 6.1.

A diferença entre os algoritmos está na forma de se obter essa solução: no branch-and-cut,

utiliza-se um algoritmo exato; no branch-and-ascent, heurísticas.

7.2 Branch-and-Cut

O primeiro algoritmo exato apresentado é do tipo branch-and-cut. Em cada nó da árvore

de resolução, resolve-se de forma exata a relaxação linear do subproblema correspondente,

sendo o valor obtido utilizado como limite inferior para sua solução ótima. Alguns dos mais

e�cientes algoritmos para o problema de Steiner em grafos utilizam essa mesma estratégia:

Lucena e Beasley [35], Koch e Martin [32], Uchoa et al. [58] e Polzin e Daneshmand [46].

Nas subseções seguintes, descrevem-se os procedimentos para o cálculo de limites in-

feriores, para realização da rami�cação (branching) e para a determinação de limites

superiores.

7.2.1 Limites Inferiores

O algoritmo utiliza a formulação por cortes direcionados, a mesma utilizada em [32, 46, 58].

Conforme já mencionado na Seção 6.1, essa formulação de�ne um número exponencial de

restrições, o que torna inviável resolvê-la diretamente. O que se faz é iniciar o algoritmo

com apenas um subconjunto de restrições e adicionar novas restrições aos poucos por

Page 121: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 109

meio da execução de uma rotina de separação. Com isso, o valor da solução dual (limite

inferior) cresce progressivamente até atingir o valor da relaxação linear do problema.

Inicialização Em algoritmos do tipo branch-and-cut, é comum que a resolução da re-

laxação linear no nó-raiz (o problema original) se inicie com um programa linear sem

restrições ou apenas com restrições triviais. É esse o caso, por exemplo, dos algoritmos

descritos em [32, 58]. Entretanto, para acelerar a convergência do algoritmo, é conveniente

resolver a relaxação a partir de um bom conjunto inicial de cortes. Em [46], utilizam-se

soluções fornecidas pelo algoritmo de dual ascent. No algoritmo aqui proposto, utilizam-

se também as técnicas de dual adjustment e �xação ativa para melhorar a solução dual

inicial, conforme proposto na Seção 6.3.4.

Separação Para a formulação por cortes direcionados para o problema de Steiner em

grafos, o procedimento de separação consiste em encontrar um corte que separa a raiz de

um terminal e é tal que a soma das variáveis correspondentes aos arcos cortados por ele

tenha valor inferior a 1.0. Utilizou-se como rotina de separação uma versão modi�cada do

algoritmo de Hao e Orlin [27] para encontrar o corte mínimo global de um grafo orientado.

A modi�cação foi feita por Eduardo Uchoa [57] sobre a implementação original de G.

Skorobohatyj [52]. Um aspecto positivo desse algoritmo é o de que, na busca pelo corte

mínimo, ele normalmente encontra até jT j � 1 outros cortes violados. Adicionados à

formulação, eles aceleram signi�cativamente a convergência do algoritmo. Cada execução

da rotina de separação é feita em tempo O(jV j

2

q

jEj) no pior caso.

Subproblemas Num algoritmo de branch-and-cut, é necessário resolver a relaxação

linear não só do nó-raiz, mas também de todos os subproblemas. No algoritmo aqui

introduzido, a resolução de uma subproblema é feita pela aplicação (iterada, se necessário)

da rotina de separação sobre o conjunto de cortes de valor dual positivo presentes na

relaxação linear do problema pai. Como essa estratégia requer a manutenção simultânea

de diversas soluções duais em memória, optou-se por percorrer em profundidade a árvore

de resolução (isso limita o número de nós ativos).

7.2.2 Soluções Primais

No algoritmo proposto por Koch e Martin [32], o método utilizado para encontrar limites

superiores é a heurística construtiva de Prim (Seção 3.3). Para obter melhores qualidades,

o algoritmo é executado considerando não os pesos originais das arestas, mas pesos modi�-

cados a partir dos valores fornecidos durante a resolução da relaxação linear do problema.

Sendo �x

a

o custo da variável associada ao arco a na solução do programa linear, será

c(a)(1 � �x

a

) o custo do arco a para a heurística de Prim. Essa modi�cação privilegia os

arcos �escolhidos� pelo resolvedor LP (�x

a

= 1) e penaliza os que foram preteridos (�x

a

= 0).

Page 122: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 110

O algoritmo aqui proposto utiliza procedimento semelhante. A cada execução da roti-

na de separação, o algoritmo de Prim é executado dez vezes, sendo uma delas exatamente

como a descrita acima; nas demais execuções, os custos modi�cados são aleatoriamente

perturbados em até 5%. Além disso, as soluções construtivas mais promissoras são sub-

metidas à busca local NP.

7.2.3 Branching

Apesar de a formulação por cortes direcionados associar uma variável a cada arco, decidiu-

se fazer uma rami�cação binária com base nos vértices do grafo. Pode-se fazer isso porque

o conjunto de vértices de uma solução é su�ciente para determiná-la totalmente, conforme

demonstrado na Seção 4.1. Como o número de vértices não-terminais em um grafo pode

ser menor que o de arestas, usá-los no branching tende a reduzir a profundidade da árvore

de resolução.

O princípio básico utilizado é o mesmo já descrito anteriormente. Seja v o vértice es-

colhido para rami�cação (um não-terminal, obrigatoriamente). Em um dos subproblemas

(ramos), exige-se que v faça parte da solução, o que é feito por meio da tranformação do

vértice em um terminal. No outro subproblema, exige-se que o vértice não faça parte de

qualquer solução, o que se faz eliminando o vértice (e os arcos associados) do grafo.

Na implementação realizada, a seleção do vértice de branching é feita com base na

solução primal da relaxação linear. Para cada vértice, calcula-se a soma das variáveis x

correspondentes a todos os arcos incidentes; será escolhido o vértice que tiver esse valor

mais próximo de 0.5. Utilizar a variável mais próxima de 0.5 é um critério de branching

muito adotado na prática. Em caso de empate, tem preferência aquele cuja soma das

variáveis associadas aos arcos de saída tem valor máximo.

7.3 Branch-and-Ascent

Praticamente todo o tempo de execução do branch-and-cut proposto acima é gasto na

resolução de relaxações lineares. Tomadas em conjunto, as execuções da rotina de se-

paração e as reotimizações do programa linear após a adição de cada novo conjunto de

cortes são bastante custosas. O algoritmo de branch-and-ascent nasce como uma tentativa

de contornar essa di�culdade, reduzindo signi�cativamente o tempo gasto no cálculo de

limites inferiores.

O branch-and-ascent é um algoritmo de enumeração implícita, assim como o branch-

and-cut. Entretanto, enquanto o branch-and-cut usa a solução exata da relaxação linear

de cada subproblema como limite inferior, o branch-and-ascent usa soluções heurísticas.

Como as soluções aproximadas são de pior qualidade, isso acaba se traduzindo em ár-

vores de resolução mais profundas. Por outro lado, reduz-se drasticamente o tempo de

processamento de cada nó. Para diversas instâncias, essa troca é extremamente vantajosa.

Page 123: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 111

7.3.1 Método de Resolução de um Nó

Em cada nó da árvore de resolução executa-se a estratégia apresentada na Seção 6.3.4,

composta por uma ou mais execuções do algoritmo de dual ascent, dual adjustment e

�xação ativa. As soluções primais (limites superiores) são fornecidos pela execução do

reverse delete step após cada dual ascent, seguida sempre da aplicação da busca local NP.

Optou-se por fazer com que em cada nó da árvore fosse executado um dual ascent a

partir �do zero�. A alternativa seria aplicar o dual ascent sobre a melhor solução dual

encontrada pelo pai, mas esse método se revelou pouco interessante. Na grande maioria

dos casos uma solução maximal para o nó-pai continua maximal mesmo após transformada

em solução para o �lho (pela remoção de um nó ou pela conversão de um não-terminal em

terminal). Assim, são necessários inúmeros branchings até que uma solução encontrada

tenha valor dual elevado. Executado a partir �do zero�, o dual ascent tem mais liberdade

para explorar a nova estrutura do grafo (com menos vértices ou mais terminais), o que se

traduz em soluções de melhor qualidade.

É claro que, por se tratar de um método heurístico, nada garante que o dual ascent

executado em um nó encontrará solução melhor que a encontrada no pai. Assim sendo,

não necessariamente a solução fornecida para as rotinas de dual adjustment e �xação

ativa terá sido encontrada no próprio nó; pode ser a melhor solução encontrada em algum

ancestral. Por sinal, tanto o dual adjustment quanto a �xação ativa se mostraram muito

úteis, especialmente nas instâncias mais difíceis, para melhorar soluções encontradas em

outros nós da árvore de resolução.

7.3.2 Branching

As rami�cações do branch-and-ascent são baseadas em vértices, como no branch-and-cut.

Muda apenas o critério de seleção do vértice de branching. No branch-and-ascent, a rami-

�cação é feita sobre o vértice com maior número de arcos saturados incidentes na melhor

solução dual conhecida; o desempate é feito com base nos arcos �de saída�. A motivação

é o fato de que, para um vértice com essas características, a probabilidade de que ele de

fato pertença à solução ótima (do subproblema) é relativamente alta. Isso ajuda a equili-

brar a árvore de resolução, uma vez que, como se veri�cou empiricamente, subproblemas

resultantes da inserção de um terminal tendem a ser mais facilmente resolvidos que os

resultantes da remoção de um vértice.

Strong Branching Experimentalmente, veri�cou-se que o critério de branching des-

crito acima nem sempre é bem-sucedido. O número de arcos saturados numa solução

fornecida por heurísticas duais é normalmente muito alto. Não são raras as situações em

que mais da metade dos arcos estão saturados ao �nal da execução das heurísticas. Assim,

há vários vértices com um grande número de arcos incidentes saturados, mas nem todos

podem fazer parte da solução �nal; o critério acima não garante que uma boa decisão será

Page 124: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 112

tomada.

Com o objetivo de minimizar esse problema, utilizou-se um método de rami�cação

forte (strong branching). Para a seleção do vértice de branching, o algoritmo testa diversos

vértices. A lista de candidatos é construída com base nos critérios utilizados para o

branching simples: número de arcos saturados incidentes em cada vértice. O teste de um

candidato v consiste em duas execuções do dual ascent : na primeira, exige-se que o vértice

não faça parte da solução (ele e os arcos nele incidentes são removidos); na outra, exige-se

que o ele faça parte da solução (ele é transformado em terminal). Sejam os valores duais

obtidos q

0

(v) e q

1

(v), respectivamente. De�ne-se a qualidade do nó como

q(v) = 2minfq

0

(v); q

1

(v)g+maxfq

0

(v); q

1

(v)g:

Escolhe-se como vértice de branching o candidato de maior qualidade. Observe que, ao

atribuir um peso maior ao pior ramo, essa estratégia tenta garantir rami�cações mais

balanceadas.

7.4 Resultados Experimentais

Esta seção analisa experimentalmente o desempenho dos algoritmos propostos, que são

comparados entre si e com os algoritmos exatos de melhor desempenho disponíveis na

literatura. Trata-se dos algoritmos apresentados por Koch e Martin [32], Uchoa et al.

[58] e Polzin e Daneshmand [46]. Todos eles são do tipo branch-and-cut. Para evitar

ambigüidades, será utilizada a abreviação �B&C� para o branch-and-cut proposto na

Seção 7.2; os demais algoritmos serão identi�cados pelas iniciais de seus autores: KM

(Koch e Martin), UPR (Uchoa, Poggi de Aragão e Ribeiro) e PD (Polzin e Daneshmand).

O termo �B&A� será ocasionalmente utilizado em referências ao branch-and-ascent.

Uma análise preliminar dos algoritmos aqui propostos indica que eles são complemen-

tares. Para grafos com muitos vértices, o B&C parece ser o método mais adequado. Para

grafos com menos vértices, a melhor alternativa parece ser o branch-and-ascent (indepen-

dentemente do número de arestas). Assim, para as instâncias testadas, o branch-and-

ascent apresentou melhores resultados para as instâncias de incidência; para as instâncias

VLSI e OR-Library, a melhor alternativa é B&C. Para as instâncias PUC, ambos os algo-

ritmos são igualmente ine�cazes, devido aos grandes gap de dualidade e à simetria dessas

instâncias.

1

As subseções seguintes detalham os resultados obtidos para cada classe.

1

Lembre-se de que as instâncias PUC foram criadas com o propósito de serem �difíceis�. E os algoritmos

aqui propostos foram justamente os utilizados para �atestar� a di�culdade das instâncias. Portanto, pode-

se dizer que eles são, por construção, incapazes de resolvê-las (exceto no caso de algumas poucas instâncias

muito pequenas [51]).

Page 125: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 113

7.4.1 Incidência

As Tabelas 7.1 e 7.2 apresentam os resultados obtidos pelo algoritmo de branch-and-

ascent para as instâncias de Incidência terminadas em �1�. Para cada instância, as tabelas

apresentam suas dimensões (números de vértices, arestas e terminais) e o valor da solução

ótima (caso ela seja conhecida). Além disso, as tabelas mostram ainda o número de

nós (nós) e a profundidade máxima (prof.) da árvore de resolução percorrida pelo

branch-and-ascent. Apresenta-se também o tempo de execução do algoritmo em cada

caso. Os tempos de execução podem ser comparados com os obtidos pelo algoritmo de

Koch e Martin, apresentados na coluna KM (os algoritmos PD e UPR não foram testados

para instâncias dessa classe). Os tempos para o branch-and-ascent foram obtidos em um

Pentium II de 400 MHz; o algoritmo KM foi executado numa Sun Enterprise 3000. Nas

tabelas, os tempos de execução são apresentados em segundos.

Note que tanto o algoritmo de branch-and-ascent aqui proposto quanto o algoritmo de

branch-and-cut de Koch e Martin foram capazes de resolver todas as instâncias das séries

i080 e i160. Já a série i320 pôde ser resolvida completamente apenas pelo branch-and-

ascent. Seis das instâncias não puderam ser resolvidas pelo algoritmo de Koch e Martin

em 10 mil segundos, o tempo máximo de execução permitido em [32]. Na série i640, ambos

os algoritmos tiveram di�culdades (o algoritmo de Koch e Martin deixou de resolver oito

instâncias; o branch-and-ascent deixou de solucionar seis delas).

Em termos do tempo de execução, observe que o algoritmo de branch-and-ascent é

normalmente mais rápido, mas o algoritmo de Koch e Martin tem desempenho superior

em alguns casos, especialmente para instâncias muito esparsas: seu tempo de execução

para a instância i640-331, por exemplo, é inferior à metade do requerido pelo branch-and-

ascent, mesmo sendo executado em uma máquina mais lenta. Para instâncias mais densas,

mesmo que apenas ligeiramente, o desempenho do branch-and-ascent é muito superior.

Em alguns casos, chega a ser de duas a três ordens de grandeza mais rápido. Trata-se de

um método muito interessante para essa classe de instâncias, portanto.

Branch-and-cut Pode-se chegar às mesmas conclusões a partir de uma comparação

direta entre o branch-and-ascent e o branch-and-cut. O B&C foi executado sobre as

instâncias de �nal �1� das séries i080 e i160 que não foram resolvidas pelo branch-and-

ascent no nó-raiz. A Tabela 7.3 mostra, para cada um dos algoritmos (e também para o

de Koch e Martin), o número de nós na árvore de resolução e o tempo total de execução

(que, no caso do B&C, foi feita numa Sun Ultra de 167 MHz).

A tabela deixa clara a principal característica do branch-and-ascent : o número de nós

na árvore de resolução pode ser muito maior que no branch-and-cut, mas a resolução de

cada nó é muito mais rápida. Mantido constante o número de vértices, a diferença entre os

tempos de execução de cada nó é maior para as instâncias mais densas, já que a existência

de um grande número de variáveis no programa linear torna a sua resolução mais lenta.

Nas heurísticas duais, a dependência em relação ao número de arestas é mais fraca.

Page 126: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 114

instância jV j jEj jT j ótimo nós prof. tempo KM

i080-001 80 120 6 1787 1 0 0.02 0.2

i080-011 80 350 6 1479 1 0 0.10 0.8

i080-021 80 3160 6 1175 1 0 0.15 5.5

i080-031 80 160 6 1570 1 0 0.01 0.2

i080-041 80 632 6 1276 1 0 0.10 2.5

i080-101 80 120 8 2608 9 4 0.20 0.1

i080-111 80 350 8 2051 1 0 0.34 4.0

i080-121 80 3160 8 1561 1 0 0.50 7.5

i080-131 80 160 8 2284 1 0 0.04 0.4

i080-141 80 632 8 1788 1 0 0.40 3.5

i080-201 80 120 16 4760 1 0 0.02 0.3

i080-211 80 350 16 3631 1 0 0.12 2.3

i080-221 80 3160 16 3158 1 0 0.58 22.1

i080-231 80 160 16 4354 1 0 0.09 0.4

i080-241 80 632 16 3538 25 9 14.83 1097.1

i080-301 80 120 20 5519 1 0 0.02 0.2

i080-311 80 350 20 4554 17 7 3.64 8.6

i080-321 80 3160 20 3932 1 0 0.36 29.8

i080-331 80 160 20 5226 5 2 0.50 1.7

i080-341 80 632 20 4236 3 1 1.12 3.1

i160-001 160 240 7 2490 1 0 0.14 0.6

i160-011 160 812 7 1677 1 0 0.29 1.6

i160-021 160 12720 7 1352 1 0 0.82 53.4

i160-031 160 320 7 2170 1 0 0.05 0.5

i160-041 160 2544 7 1494 1 0 0.40 29.3

i160-101 160 240 12 3859 1 0 0.04 0.8

i160-111 160 812 12 2869 1 0 0.94 2.5

i160-121 160 12720 12 2363 1 0 4.06 808.0

i160-131 160 320 12 3356 1 0 0.08 1.3

i160-141 160 2544 12 2549 1 0 12.05 42.8

i160-201 160 240 24 6923 27 9 1.05 1.9

i160-211 160 812 24 5583 51 8 37.07 1143.5

i160-221 160 12720 24 4729 1 0 5.08 889.1

i160-231 160 320 24 6662 19 6 2.76 2.3

i160-241 160 2544 24 5086 23 9 83.42 21008.6

i160-301 160 240 40 11816 3 1 0.22 1.1

i160-311 160 812 40 9135 231 20 192.86 687.9

i160-321 160 12720 40 7876 1 0 7.61 2959.4

i160-331 160 320 40 10414 11 5 1.17 1.8

i160-341 160 2544 40 8331 283 24 708.06 54500.7

Tabela 7.1: Resultados do branch-and-ascent nas séries i080 e i160 e comparação de

tempos (em segundos)

Page 127: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 115

instância jV j jEj jT j ótimo nós prof. tempo KM

i320-001 320 480 8 2672 1 0 0.11 1.3

i320-011 320 1845 8 2053 1 0 1.02 25.5

i320-021 320 51040 8 1553 1 0 4.14 1102.0

i320-031 320 640 8 2673 1 0 0.47 10.5

i320-041 320 10208 8 1707 1 0 13.40 434.6

i320-101 320 480 17 5548 1 0 0.17 1.7

i320-111 320 1845 17 4273 15 5 14.87 206.5

i320-121 320 51040 17 3321 1 0 7.54 2595.3

i320-131 320 640 17 5255 5 2 2.12 7.4

i320-141 320 10208 17 3606 11 5 113.45 �

i320-201 320 480 34 10044 15 7 1.28 5.0

i320-211 320 1845 34 8039 355 21 592.92 8274.6

i320-221 320 51040 34 6679 1 0 43.31 �

i320-231 320 640 34 9862 35 8 17.20 39.5

i320-241 320 10208 34 7027 297 61 2567.66 �

i320-301 320 480 80 23279 29 9 6.33 13.3

i320-311 320 1845 80 17945 58549 34 134052.94 �

i320-321 320 51040 80 15648 9 4 687.94 �

i320-331 320 640 80 21517 1425 35 609.36 266.7

i320-341 320 10208 80 16296 13991 69 154091.24 �

i640-001 640 960 9 4033 1 0 0.39 5.2

i640-011 640 4135 9 2392 1 0 2.31 18.8

i640-021 640 204480 9 1749 1 0 29.26 11004.9

i640-031 640 1280 9 3278 1 0 1.07 6.5

i640-041 640 40896 9 1897 1 0 43.00 2214.9

i640-101 640 960 25 8764 13 5 6.09 26.7

i640-111 640 4135 25 6167 393 15 1038.90 13677.5

i640-121 640 204480 25 4906 1 0 200.99 �

i640-131 640 1280 25 8097 11 4 16.15 28.6

i640-141 640 40896 25 � � � � �

i640-201 640 960 50 16079 9 4 5.29 31.3

i640-211 640 4135 50 � � � � �

i640-221 640 204480 50 9821 5 2 798.93 �

i640-231 640 1280 50 15014 77 10 145.61 804.1

i640-241 640 40896 50 � � � � �

i640-301 640 960 160 45005 367 41 277.11 152.3

i640-311 640 4135 160 � � � � �

i640-321 640 204480 160 � � � � �

i640-331 640 1280 160 42796 8377 70 7902.88 3817.9

i640-341 640 40896 160 � � � � �

Tabela 7.2: Resultados do branch-and-ascent nas séries i320 e i640 e comparação de

tempos (em segundos)

Page 128: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 116

instância dimensões B&A B&C KM

jV j jEj jT j nós tempo nós tempo nós tempo

i080-101 80 120 8 9 0.20 1 0.14 1 0.1

i080-241 80 632 16 25 14.83 17 671.92 115 1097.1

i080-311 80 350 20 17 3.64 3 6.50 1 8.6

i080-331 80 160 20 5 0.50 3 0.97 5 1.7

i080-341 80 632 20 3 1.12 1 2.22 1 3.1

i160-201 160 240 24 27 1.05 5 3.70 5 1.9

i160-211 160 812 24 51 37.07 11 743.58 15 1143.5

i160-231 160 320 24 19 2.76 1 2.19 1 2.3

i160-241 160 2544 24 23 83.42 19 13032.69 121 21008.6

i160-301 160 240 40 3 0.22 1 0.5 1 1.1

i160-311 160 812 40 231 192.86 13 394.33 25 687.9

i160-331 160 320 40 11 1.17 1 0.87 1 1.8

i160-341 160 2544 40 283 708.06 19 46622.88 131 54500.7

Tabela 7.3: Comparação entre o branch-and-ascent (B&A) e o branch-and-cut (B&C)

Melhorando o desempenho do Branch-and-ascent São duas as principais razões

pelas quais o número de nós visitados pelo branch-and-ascent tende a ser maior que o

número visitado pelo branch-and-cut. Em primeiro lugar, como os limites inferiores são

de pior qualidade, o número de rami�cações feitas até que um nó seja podado tende a ser

maior. Além disso, a escolha do vértice de branching é mais criteriosa no branch-and-cut,

que dispõe dos valores primais associados às variáveis.

Podem-se tomar medidas para amenizar essas di�culdades. Uma delas é o uso do

strong branching , que normalmente leva a uma árvore de enumeração mais equilibrada.

Outra medida interessante consiste em calcular melhores limites primais; a�nal, limites

superiores são tão importantes quanto limites inferiores para a poda de ramos da árvore

de enumeração e para a diminuição dos tamanhos dos subproblemas (pela �xação por

custos reduzidos). É claro que o algoritmo exato obrigatoriamente achará bons limites

superiores ao longo da execução, inclusive o valor ótimo. No entanto, o uso de uma

boa solução primal desde o começo da execução tende a torná-la signi�cativamente mais

rápida, especialmente para instâncias consideradas difíceis.

Para ilustrar esse fato, o branch-and-ascent foi testado em todas as instâncias da série

i320 que, segundo a SteinLib, estavam em aberto até janeiro de 2001 (quando foram

resolvidas pela primeira vez, justamente pelo branch-and-ascent [44]). Foram utilizadas

nas execuções soluções primais fornecidas pela metaeurística HGP+PR, apresentada no

Capítulo 5. Além disso, utilizou-se strong-branching : no nó-raiz (profundidade zero)

testavam-se dez diferentes alternativas; em nós de profundidade 1, nove alternativas; na

profundidade 2, oito alternativas; e assim sucessivamente. A partir da profundidade 10,

utilizou-se branching simples. A Tabela 7.4 mostra os resultados obtidos.

Page 129: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 117

instância jV j jEj jT j ótimo nós prof. tempo (s)

i320-215 320 1845 34 8015 827 15 1310

i320-223 320 51040 34 6695 1 0 42

i320-224 320 51040 34 6694 1 0 37

i320-225 320 51040 34 6691 1 0 43

i320-241 320 10208 34 7027 15 7 109

i320-242 320 10208 34 7072 59 25 543

i320-243 320 10208 34 7044 31 13 324

i320-244 320 10208 34 7078 61 16 570

i320-245 320 10208 34 7046 21 9 253

i320-311 320 1845 80 17945 33529 29 63279

i320-312 320 1845 80 18122 99311 30 165981

i320-313 320 1845 80 17991 44197 39 79373

i320-314 320 1845 80 18088 70390 44 125664

i320-315 320 1845 80 17987 113494 41 192909

i320-321 320 51040 80 15648 5 2 309

i320-322 320 51040 80 15646 11 4 571

i320-323 320 51040 80 15654 3 1 299

i320-324 320 51040 80 15667 21 10 1210

i320-325 320 51040 80 15649 3 2 430

i320-341 320 10208 80 16296 4007 54 44630

i320-342 320 10208 80 16228 117 15 2629

i320-343 320 10208 80 16281 789 42 10354

i320-344 320 10208 80 16295 1549 34 17944

i320-345 320 10208 80 16289 3025 54 30263

Tabela 7.4: Resultados do branch-and-ascent com strong-branching nas 24 instâncias da

série i320 não resolvidas até janeiro de 2001, segundo a SteinLib

Page 130: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 118

Repare que a tabela inclui quatro instâncias apresentadas também na Tabela 7.2:

i320-241, i320-311, i320-221 e i320-341. Em todos os casos, observaram-se reduções signi-

�cativas no número de nós visitados e na profundidade máxima da árvore de busca (com

destaque para a instância i320-241). Os tempos de execução também foram signi�cati-

vamente reduzidos, mas é importante lembrar que eles não incluem o cálculo da solução

primal inicial (com a metaeurística HGP+PR). De qualquer forma, para as instâncias

realmente difíceis, i320-311 e i320-341, o tempo gasto com as heurísticas primais é despre-

zível (alguns minutos). Para a solução de instâncias em aberto, portanto, uma execução

prévia de uma metaeurística é uma boa estratégia.

7.4.2 OR-Library

Para a classe OR-Library, os resultados obtidos pelos algoritmos propostos serão compara-

dos com os apresentados em [32] e [46] (em [58], apenas instâncias VLSI são consideradas).

Como mostrou a Tabela 6.3, 51 das 57 instâncias dessa série

2

são completamente resolvi-

das pelas heurísticas duais. Nesta seção, serão consideradas apenas as seis instâncias

remanescentes: c18, d18, d19, e13, e18 e e19.

Um dado importante a respeito dessas instâncias é o fato de que em todas o gap

de dualidade é inferior a uma unidade. Como os algoritmos baseados em branch-and-cut

resolvem completamente a relaxação linear do problema, todos eles são capazes de resolver

todas as instâncias em um único nó. Só ocorrerá branching se a solução ótima não for

encontrada no nó-raiz. Entre as instâncias testadas, a única que não teve a solução ótima

detectada no primeiro nó foi a e18: tanto o B&C quanto KM �zeram branching (PD foi

o único algoritmo capaz de encontrar a solução na raiz da árvore de resolução).

A Tabela 7.5 mostra os tempos de execução obtidos pelos algoritmos. Como os valores

mostrados para os algoritmos de Koch e Martin (KM) e de Polzin e Daneshmand (PD)

incluem a etapa de pré-processamento, a tabela reproduz os tempos de pré-processamento

mostrados no Apêndice A na coluna prep.. Deve-se, portanto, considerar que o tempo

total do algoritmo aqui proposto é a soma das colunas prep. e B&C.

Para estas instâncias, o algoritmo KM foi executado em uma Sun SPARC 20/71; o

algoritmo PD, em um Pentium de 300 MHz; e o B&C, em uma Sun Ultra de 167 MHz

(exceto a fase de pré-processamento, executada em um AMD K6-2 de 350 MHz).

A tabela mostra que o algoritmo aqui proposto tem desempenho claramente superior

ao de KM. Contribui para isso o fato de que o B&C emprega técnicas de pré-processamento

mais completas, introduzidas em [58]. Além disso, o fato de o programa linear ser inici-

alizado com uma solução dual heuristicamente obtida (o que não é feito em KM) acelera

a signi�cativamente convergência do B&C.

Já o algoritmo PD tem, em geral, desempenho superior ao do B&C. A razão básica

é o conjunto de métodos de redução utilizados por Polzin e Daneshmand. Conforme já

2

Na verdade são 60 instâncias no total, mas três são resolvidas pelo pré-processamento.

Page 131: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 119

instância dimensões ótimo tempo (s)

jV j jEj jT j prep. + B&C KM PD

c18 500 12500 83 113 8.1 + 5.0 104.8 3.0

d18 1000 25000 167 223 38.2 + 6.4 308.0 1.9

d19 1000 25000 310 310 45.2 + 1.6 868.8 1.5

e13 2500 12500 417 1280 104.1 + 45.3 2816.3 4.3

e18 2500 62500 417 564 286.4 + 1757.0 68949.1 74.1

e19 2500 62500 625 758 252.8 + 16.6 4581.5 14.0

Tabela 7.5: Resultados do branch-and-cut para a classe OR-Library

mencionado na Seção 2.5, os autores propõem implementações muito rápidas dos testes

disponíveis na literatura. Além disso, eles também fazem uso de técnicas de redução

baseadas em dualidade (limites superiores e inferiores), que são extremamente e�cientes

para instâncias como as dessa classe, com gap muito pequeno. Se for desconsiderado o

tempo dedicado pelo algoritmo de B&C às técnicas de pré-processamento, ele se torna mais

competitivo. A única exceção é a instância e18: conforme já mencionado, o método PD

foi o único capaz de encontrar a solução ótima no nó-raiz e, portanto, não precisou fazer

branching. Os autores apresentam algumas heurísticas primais que são muito e�cientes

para essa classe de instâncias, pois também se baseiam fortemente em informações de

dualidade.

As mesmas instâncias foram testadas também com o algoritmo de branch-and-ascent.

Os resultados da execução desse algoritmo em um Pentium II de 400 MHz são apresentados

na Tabela 7.6. Observe que as dimensões apresentadas na tabela referem-se às instâncias

pré-processadas, sobre as quais foi aplicado o algoritmo. O tempo de pré-processamento

não foi considerado nesse teste.

instância jV j jEj jT j ótimo nós prof. tempo

c18 391 1044 50 113 21 6 6.2

d18 813 2284 97 223 3 1 4.2

d19 700 1932 100 310 3 1 0.5

e13 1418 2962 232 1280 809 38 1563.0

e18 2219 6185 248 564 � � �

e19 1156 2757 174 758 � � �

Tabela 7.6: Branch-and-ascent com strong branching para a classe OR-Library

A tabela mostra que, para as instâncias c18, d18 e d19, o desempenho do algoritmo

é comparável ao do B&C. Para as demais, é muito pior: as instâncias e18 e e19 não

puderam sequer ser resolvidas (em uma hora, o tempo máximo permitido nesse caso).

Percebe-se que, quando aumenta o número de vértices do grafo, é grande o risco de o

branch-and-ascent gerar árvores profundas demais, mesmo quando o strong branching é

Page 132: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 120

utilizado; nesses casos, o branch-and-cut deve ser o método preferido.

7.4.3 VLSI

Das instâncias aqui analisadas, a classe VLSI é a que possui o maior número de vértices.

Assim sendo, o método escolhido para sua análise é o branch-and-cut. Esse método é

comparado apenas com os algoritmos de Polzin e Daneshmand (PD) e de Uchoa, Poggi

de Aragão e Ribeiro (UPR). O algoritmo de Koch e Martin fornece resultados signi�cati-

vamente piores que os apresentados por esses dois métodos. O B&C foi executado sobre

as instâncias pré-processadas pela implementação apresentada em [58] (que fornece resul-

tados ligeiramente diferentes dos apresentados no Apêndice A), para permitir uma melhor

comparação entre esses dois métodos.

A Tabela 7.7 mostra os resultados obtidos para todas as instâncias que não foram

resolvidas apenas por pré-processamento e heurísticas duais. Os tempos apresentados

são tempos totais, incluindo o pré-processamento. Tanto o B&C quanto UPR foram

executados em uma Sun Ultra 1; o algoritmo PD foi executado em um Pentium de 300

MHz.

Quando se comparam os algoritmos B&C e UPR, observa-se que o primeiro é clara-

mente superior ao segundo. Como a maioria das instâncias dessa série tem gap de du-

alidade muito pequeno, raramente há branching e, quando há, a árvore não é profunda

[58]. O gargalo de ambos os algoritmos é o cálculo da relaxação linear, o que indica que

as grandes diferenças observadas entre seus tempos de execução devem-se basicamente ao

fato de que B&C usa heurísticas duais para inicializar o programa linear.

3

Há também

razões secundárias: a rotina de separação utilizada pelo B&C é mais e�ciente que a rotina

utilizada no algoritmo UPR.

A comparação entre o B&C e PD é mais equilibrada: ora um dos algoritmos tem

melhor desempenho, ora o outro. Nos dois sentidos, há casos em que um método é de

uma a duas ordens de grandeza mais rápido que o outro. O algoritmo PD utiliza muitos

testes de redução baseados em limites (bound-based reductions), e�cazes apenas quando a

diferença entre o valor dual e o valor primal conhecidos é pequena. Assim, PD parece ser

mais adequado nos casos em que o dual ascent fornece soluções muito próximas do valor

ótimo.

Nas demais situações, o B&C tem vantagens. Em primeiro lugar, ele utiliza durante

a fase de pré-processamento alguns testes concebidos justamente para instâncias VLSI

[58], sendo que todos eles se baseiam apenas em implicações lógicas (o gap de dualidade é

irrelevante). Além disso, a rotina de separação implementada parece ser particularmente

e�ciente, acelerando a convergência do algoritmo.

A Tabela 7.7 mostra que, para quatro das instâncias propostas, o B&C foi o único

3

Na verdade, para algumas instâncias o gargalo é o pré-processamento, mas ele é idêntico nos dois

algoritmos; portanto, não pode ser ele o responsável pelas �grandes diferenças�.

Page 133: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 121

instância dimensões ótimo tempo (s)

jV j jEj jT j B&C UPR PD

alue3146 3626 5869 64 2240 15.6 20 22.5

alue5345 5179 8165 68 3507 327 3039 1136

alue5623 4472 6938 68 3413 138.8 1755 1298

alue5901 11543 18429 68 3912 119.7 1367 653

alue6179 3372 5213 67 2452 51.7 161 4.17

alue6457 3932 6137 68 3057 101.3 645 4.49

alue6735 4119 6696 68 2696 47.7 129 18.8

alue6951 2818 4419 67 2386 110.8 167 22.1

alue7065 34046 54841 544 23881 163123 � �

alue7066 6405 10454 16 2256 5923 9871 1666

alue7080 34479 55494 2344 62449 18476 � �

alut0805 1160 2089 34 958 1.1 2 1.8

alut1181 3041 5693 64 2353 27.4 82 358

alut2010 6104 11011 68 3307 78.7 143 29.1

alut2288 9070 16595 68 3843 324.8 1459 1078

alut2566 5021 9055 68 3073 103.1 876 604

alut2610 33901 62816 204 12239 1810410 � �

alut2625 36711 68117 879 35459 671406 � �

diw0779 11821 22516 50 4440 1704 35467 1298

diw0820 11749 22384 37 4167 1984 35946 159

dmxa0368 2050 3676 18 1017 2.2 3 1.1

dmxa1801 310 553 17 1365 40.8 120 0.8

gap3128 10393 18043 104 4292 782 2135 23.3

msm2846 3263 5783 89 3135 59.7 275 292

msm4312 5181 8893 10 2016 250.5 1498 10.6

taq0014 6466 11046 128 5326 393 10797 1556

taq0377 6836 11715 136 6393 834 27684 6486

taq0903 6163 10490 130 5099 934 14368 16056

Tabela 7.7: Resultados obtidos para instâncias VLSI

Page 134: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 122

dos algoritmos apresentados capaz de resolvê-las. Os tempos de execução, no entanto,

foram consideravelmente altos: 2 dias para a instância alue7065, 5 horas para a alue7080,

21 dias para a instância alut2610 e 8 dias para alut2625.

4

Os altos tempos de execução

se justi�cam porque essas instâncias não haviam sido previamente resolvidas; o branch-

and-cut proposto nesta dissertação (apresentado originalmente em [44]) foi o primeiro a

fazê-lo. A Figura 7.1, que apresenta a solução exata da instância alue7080, deixa bem

clara a �não-trivialidade� da tarefa.

7.5 Conclusão

Os algoritmos exatos propostos neste capítulo, branch-and-cut e branch-and-ascent, estão

entre os mais e�cientes descritos na literatura. O algoritmo de branch-and-ascent mostrou-

se extremamente e�ciente para instâncias com poucos nós. Foi ele o primeiro algoritmo

capaz de resolver completamente a série i320, de Incidência. Para instâncias com mais nós,

o branch-and-cut é a melhor alternativa. Ele foi o primeiro algoritmo capaz de resolver

todas as instâncias da classe VLSI.

A e�ciência dos métodos é inegável, mas é possível melhorar ainda mais os resultados

obtidos.

Considere, por exemplo, a rotina de pré-processamento utilizada. Seria interessante

reimplementar alguns dos testes utilizando as sugestões apresentadas em [46] (preservando

os testes introduzidos em [58], responsáveis por signi�cativas reduções adicionais). Dessa

forma, haveria sensível melhora nos tempos de execução, notadamente para as instâncias

da série OR-Library. Além disso, seria interessante aplicar os testes de redução também

nos nós internos da árvore de resolução. Na versão atual, elas se aplicam somente ao

problema original, no nó-raiz.

Uma estratégia que poderia ser utilizada para acelerar a convergência do branch-and-

cut é uma utilização mais freqüente das heurísticas duais. Na implementação discutida ao

longo deste capítulo, as heurísticas duais (dual ascent, dual adjustment e �xação ativa) são

utilizadas apenas para inicializar o programa linear. Depois disso, a solução da relaxação

linear é feita da forma tradicional: reotimizações do programa linear (com um resolvedor

apropriado) intercaladas com rotinas de separação. Nada impede, no entanto, que as

heurísticas duais (dual adjustment, �xação ativa, scaling ou mesmo o próprio dual ascent)

sejam executadas tendo como solução inicial uma solução fornecida pelo resolvedor LP.

Testes preliminares indicaram que há situações em que a convergência do algoritmo é mais

rápida. Não foi possível, no entanto, determinar uma estratégia que garantisse a aceleração

de forma sistemática. Isso merece, sem dúvida, uma investigação mais minuciosa.

4

As instâncias alut2610 e alut2625 foram processadas por versão preliminar do algoritmo de branch-

and-cut, similiar à utilizada em [58], mas inicializada com os cortes fornecidos pelo dual ascent. Não foi

utilizada a �xação por custos reduzidos �estendidos� nem a rotina de separação baseada no algoritmo de

Hao-Orlin, que sem duvida contribuiriam para diminuir os tempos de execução.

Page 135: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 123

Figura 7.1: Solução ótima da instância alue7080

Page 136: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 7. ALGORITMOS EXATOS 124

Outro aspecto a se considerar são os critérios para escolha do vértice de branching no

branch-and-ascent. Mesmo com o strong branching, em alguns casos a árvore de resolução é

extremamente desbalanceada. Um critério de branching mais adequado poderia contribuir

signi�cativamente para diminuir o número de nós visitados.

Page 137: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Capítulo 8

Conclusão

Esta dissertação apresentou diversas estratégias para a solução de um único problema, o

de Steiner em grafos. Foram implementadas rotinas de pré-processamento, heurísticas (e

metaeurísticas) primais, heurísticas duais e métodos de enumeração implícita, baseados

ou não em programação linear. Conforme evidenciaram os experimentos computacionais,

cada um desses métodos contribui de forma particular para a solução do problema, seja de

forma exata, seja de forma aproximada. Havendo um conjunto tão amplo de ferramentas

à disposição, uma questão é inevitável: qual delas é a melhor?

Não há uma resposta de�nitiva. A escolha depende da instância a ser resolvida, do

tempo que se pode dedicar à sua resolução e da qualidade desejada.

Considere duas instâncias em especial, i320-311 e alue7080. Ambas foram resolvidas à

otimalidade pela primeira vez por algoritmos apresentados nesta dissertação. A primeira,

uma instância de Incidência, foi resolvida pelo branch-and-ascent ; a segunda, da classe

VLSI, foi resolvida pelo branch-and-cut. Ambas podem ser consideradas difíceis, mas

por razões diferentes: a instância de Incidência, pelo gap de dualidade; a VLSI, por seu

tamanho.

A Tabela 8.1 mostra os resultados obtidos para a instância i320-311 por diversos dos

métodos estudados. Para cada um deles, apresenta-se o tempo de execução, o valor da

solução primal obtida e o desvio desse valor em relação ao ótimo. A ordem de apresentação

é determinada pelos tempos de execução. A tabela deixa claro o que foi dito ao longo

de toda a dissertação: aumentos na qualidade da solução obtida normalmente requerem

aumentos no tempo de execução. Nesse caso, é possível obter uma solução heurística a

26% do ótimo em pouco mais de três milésimos de segundo. Encontrar a solução ótima

com a heurística HGP+PR requer cerca de quatro minutos, quase 100 mil vezes mais

tempo. A prova da otimalidade (com o branch-and-ascent) requer cerca de um dia de

processamento.

A Tabela 8.2 é análoga, mas para a instância alue7080 (após o pré-processamento).

Uma comparação com a Tabela 8.1 deixa claro que a e�cácia de cada método depende da

125

Page 138: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 8. CONCLUSÃO 126

algoritmo tempo (s) valor erro%

Bor·vka 3:4 � 10

�3

22621 26.06

Prim-D 4:8 � 10

�3

23160 29.06

Kruskal-V 4:9 � 10

�3

23418 30.50

Prim-D + busca local NP 2:1 � 10

�1

18970 5.71

Prim-D + busca local NPK 2:1 � 10

0

18924 5.46

dual ascent + busca local NP 3:2 � 10

0

18503 3.11

HGP (128 iterações) 2:7 � 10

1

18307 2.02

HGP+PR (128 it., 10 sol. elite, relig. adaptativo) 3:4 � 10

1

18073 0.71

HGP (256 iterações) 5:3 � 10

1

18307 2.02

HGP+PR (256 it., 32 sol. elite, relig. adaptativo) 1:3 � 10

2

18012 0.37

HGP+PR (256 it., 32 sol. elite, relig. perturb.) 2:6 � 10

2

17945 0

branch-and-ascent 6:3 � 10

4

17945 �

Tabela 8.1: Resultados para a instância i320-311 (jV j = 320; jEj = 1845; jT j = 80)

instância à qual se aplica. Enquanto uma metaeurística (HGP+PR) é capaz de encontrar

a solução ótima de i320-311 em um centésimo do tempo do algoritmo exato, para a

instância alue7080 uma metaeurística mais simples (HGP) precisa de um tempo maior

que o do algoritmo exato para ser executada e encontra uma solução pior. Nem sempre

uma metaeurística é uma boa alternativa ao algoritmo exato.

algoritmo tempo valor erro (%)

Prim-D 0:7 � 10

�1

64305 2.97

Bor·vka 1:0 � 10

�1

63956 2.41

Kruskal-V 1:5 � 10

�1

63922 2.36

Prim-D + busca local NP 1:8 � 10

2

62734 0.46

dual ascent + busca local NP 2:6 � 10

2

62598 0.24

Prim-D + busca local NPK 2:0 � 10

3

62577 0.20

branch-and-cut 1:7 � 10

4

62449 �

HGP (128 iterações) 2:4 � 10

4

62653 0.33

HGP+PR (128 it., 10 sol. elite, relig. adaptativo) 4:3 � 10

4

62555 0.17

Tabela 8.2: Resultados para a instância alue7080 (jV j = 9272; jEj = 16019; jT j = 1402)

Outro exemplo de distinção: a busca por nós-chaves K é muito mais e�caz para a

instância alue7080 que para a i320-311. No primeiro caso, uma única iteração da busca

NPK encontra um resultado melhor que o HGP com busca NP (em um décimo do tempo).

No segundo, a busca NPK é praticamente equivalente à busca NP, mas dez vezes mais

lenta.

Esses exemplos mostram que não há um algoritmo que seja inequivocamente melhor

que todos os outros: cada um tem seus pontos fracos e seus pontos fortes. É isso que

justi�ca a implementação dos diversos métodos discutidos ao longo desta dissertação. Da

Page 139: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

CAPÍTULO 8. CONCLUSÃO 127

integração desses métodos, surge uma estratégia robusta para o tratamento do problema

de Steiner em grafos.

Page 140: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Apêndice A

Resultados do Pré-processamento

As tabelas desta seção mostram o resultado da aplicação dos procedimentos de redução

citados na Seção 2.5 sobre as instâncias das classes OR-Library e VLSI. Os procedimentos

não foram aplicados sobre as instâncias de incidência e sobre a classe PUC, já que seu

efeito sobre elas é desprezível. As tabelas mostram as dimensões de cada instância antes

e depois da redução, bem como o tempo necessário para a execução das rotinas de pré-

processamento. As execuções foram feitas em um AMD K6-2 de 350 MHz.

128

Page 141: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

APÊNDICE A. RESULTADOS DO PRÉ-PROCESSAMENTO 129

instância tempo grafo original reduzido

(s) jV j jEj jT j jV j jEj jT j

c01 0.09 500 625 5 108 188 5

c02 0.15 500 625 10 82 144 8

c03 0.17 500 625 83 55 90 24

c04 0.15 500 625 125 51 81 24

c05 0.09 500 625 250 15 24 10

c06 0.62 500 1000 5 353 795 5

c07 1.16 500 1000 10 359 802 9

c08 0.99 500 1000 83 128 238 30

c09 1.13 500 1000 125 132 241 49

c10 0.22 500 1000 250 15 21 10

c11 11.21 500 2500 5 488 1692 5

c12 8.76 500 2500 10 454 1395 9

c13 3.59 500 2500 83 177 332 37

c14 1.33 500 2500 125 5 7 4

c15 0.58 500 2500 250 4 5 3

c16 31.38 500 12500 5 499 2715 5

c17 13.26 500 12500 10 494 2294 8

c18 8.09 500 12500 83 391 1044 50

c19 8.53 500 12500 125 266 637 40

c20 3.22 500 12500 250 0 0 0

Tabela A.1: OR-Library � Série C

Page 142: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

APÊNDICE A. RESULTADOS DO PRÉ-PROCESSAMENTO 130

instância tempo grafo original reduzido

(s) jV j jEj jT j jV j jEj jT j

d01 0.49 1000 1250 5 234 433 5

d02 0.45 1000 1250 10 255 459 10

d03 0.52 1000 1250 167 31 48 18

d04 0.43 1000 1250 250 24 36 14

d05 0.29 1000 1250 500 24 37 16

d06 2.24 1000 2000 5 746 1694 5

d07 2.06 1000 2000 10 725 1647 10

d08 6.51 1000 2000 167 287 515 84

d09 2.56 1000 2000 250 69 116 34

d10 0.79 1000 2000 500 47 78 30

d11 46.25 1000 5000 5 975 3749 5

d12 31.08 1000 5000 10 956 3061 9

d13 21.28 1000 5000 167 423 828 84

d14 7.64 1000 5000 250 79 137 32

d15 1.83 1000 5000 500 23 37 14

d16 119.03 1000 25000 5 1000 6725 5

d17 163.18 1000 25000 10 1000 6332 10

d18 38.17 1000 25000 167 813 2284 97

d19 45.21 1000 25000 250 700 1932 100

d20 12.96 1000 25000 500 0 0 0

e01 1.54 2500 3125 5 657 1239 5

e02 1.40 2500 3125 10 678 1256 9

e03 2.66 2500 3125 417 120 195 64

e04 2.95 2500 3125 625 50 82 31

e05 1.52 2500 3125 1250 16 25 11

e06 9.03 2500 5000 5 1830 4277 5

e07 8.20 2500 5000 10 1876 4321 10

e08 45.90 2500 5000 417 894 1714 196

e09 27.93 2500 5000 625 506 899 187

e10 5.74 2500 5000 1250 89 152 51

e11 312.55 2500 12500 5 2487 10861 5

e12 386.53 2500 12500 10 2462 9836 10

e13 104.13 2500 12500 417 1418 2962 232

e14 62.14 2500 12500 625 339 589 119

e15 12.45 2500 12500 1250 26 41 17

e16 1563.92 2500 62500 5 2500 19698 5

e17 751.41 2500 62500 10 2500 17045 10

e18 286.41 2500 62500 417 2119 6185 248

e19 252.80 2500 62500 625 1156 2757 174

e20 79.30 2500 62500 1250 0 0 0

Tabela A.2: OR-Library � Séries D e E

Page 143: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

APÊNDICE A. RESULTADOS DO PRÉ-PROCESSAMENTO 131

instância tempo grafo original reduzido

(s) jV j jEj jT j jV j jEj jT j

alue2087 0.85 1244 1971 34 36 58 13

alue2105 0.89 1220 1858 34 7 10 3

alue3146 13.03 3626 5869 64 113 187 29

alue5067 28.86 3524 5560 68 305 509 42

alue5345 53.89 5179 8165 68 1191 2012 64

alue5623 27.34 4472 6938 68 807 1377 58

alue5901 68.48 11543 18429 68 1077 1847 58

alue6179 26.18 3372 5213 67 480 817 51

alue6457 44.25 3932 6137 68 849 1451 57

alue6735 24.23 4119 6696 68 360 592 49

alue6951 12.33 2818 4419 67 473 790 58

alue7065 2233.35 34046 54841 544 13073 23017 445

alue7066 324.77 6405 10454 16 1791 3151 9

alue7080 1021.30 34479 55494 2344 9272 16019 1402

alue7229 0.75 940 1474 34 0 0 0

alut0787 0.33 1160 2089 34 9 13 5

alut0805 1.06 966 1666 34 92 154 23

alut1181 7.03 3041 5693 64 234 412 42

alut2010 38.40 6104 11011 68 435 742 45

alut2288 299.47 9070 16595 68 1224 2195 59

alut2566 34.24 5021 9055 68 715 1242 62

alut2610 4359.47 33901 62816 204 10760 20185 182

alut2625 1843.85 36711 68117 879 12196 22457 764

alut2764 0.02 387 626 34 0 0 0

Tabela A.3: VLSI � Séries alue e alut

Page 144: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

APÊNDICE A. RESULTADOS DO PRÉ-PROCESSAMENTO 132

instância tempo grafo original reduzido

(s) jV j jEj jT j jV j jEj jT j

diw0234 248.20 5349 10086 25 860 1599 21

diw0250 0.02 353 608 11 0 0 0

diw0260 0.15 539 985 12 0 0 0

diw0313 0.03 468 822 14 0 0 0

diw0393 0.03 212 381 11 0 0 0

diw0445 1.34 1804 3311 33 31 49 11

diw0459 1.08 3636 6789 25 16 25 7

diw0460 0.02 339 579 13 0 0 0

diw0473 0.75 2213 4135 25 14 22 6

diw0487 1.73 2414 4386 25 4 5 3

diw0495 0.21 938 1655 10 0 0 0

diw0513 0.07 918 1684 10 0 0 0

diw0523 0.05 1080 2015 10 0 0 0

diw0540 0.03 286 465 10 0 0 0

diw0559 10.52 3738 7013 18 27 45 9

diw0778 42.35 7231 13727 24 178 318 15

diw0779 1046.62 11821 22516 50 2387 4508 37

diw0795 84.62 3221 5938 10 290 529 9

diw0801 90.35 3023 5575 10 393 719 10

diw0819 468.78 10553 20066 32 1186 2214 22

diw0820 1626.92 11749 22384 37 1891 3563 32

taq0014 137.69 6466 11046 128 1766 3155 86

taq0023 0.85 572 963 11 48 80 8

taq0365 35.84 4186 7074 22 998 1797 21

taq0377 103.39 6836 11715 136 2040 3603 118

taq0431 2.77 1128 1905 13 123 216 10

taq0631 0.07 609 932 10 7 9 4

taq0739 2.41 837 1438 16 73 121 12

taq0741 1.91 712 1217 16 107 183 14

taq0751 2.23 1051 1791 16 136 233 15

taq0891 0.02 331 560 10 0 0 0

taq0903 96.09 6163 10490 130 1851 3294 90

taq0910 0.06 310 514 17 0 0 0

taq0920 0.00 122 194 17 0 0 0

taq0978 0.07 777 1239 10 0 0 0

Tabela A.4: VLSI � Séries diw e taq

Page 145: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

APÊNDICE A. RESULTADOS DO PRÉ-PROCESSAMENTO 133

instância tempo grafo original reduzido

(s) jV j jEj jT j jV j jEj jT j

dmxa0296 0.02 233 386 12 0 0 0

dmxa0368 1.27 2050 3676 18 47 76 9

dmxa0454 0.55 1848 3286 16 15 22 5

dmxa0628 0.01 169 280 10 0 0 0

dmxa0734 0.10 663 1154 11 0 0 0

dmxa0848 0.74 499 861 16 37 60 11

dmxa0903 1.90 632 1087 10 58 99 8

dmxa1010 1.46 3983 7108 23 0 0 0

dmxa1109 0.13 343 559 17 9 13 5

dmxa1200 0.31 770 1383 21 32 48 13

dmxa1304 0.04 298 503 10 0 0 0

dmxa1516 0.12 720 1269 11 0 0 0

dmxa1721 0.24 1005 1731 18 6 8 4

dmxa1801 16.83 2333 4137 17 354 641 17

gap1307 0.19 342 552 17 0 0 0

gap1413 0.04 541 906 10 0 0 0

gap1500 0.02 220 374 17 0 0 0

gap1810 0.09 429 702 17 0 0 0

gap1904 2.39 735 1256 21 50 84 11

gap2007 1.11 2039 3548 17 36 61 9

gap2119 1.53 1724 2975 29 0 0 0

gap2740 0.60 1196 2084 14 33 56 5

gap2800 0.03 386 653 12 0 0 0

gap2975 0.02 179 293 10 0 0 0

gap3036 0.16 346 583 13 28 42 9

gap3100 1.63 921 1558 11 14 22 7

gap3128 390.94 10393 18043 104 2251 4091 62

Tabela A.5: VLSI � Séries dmxa e gap

Page 146: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

APÊNDICE A. RESULTADOS DO PRÉ-PROCESSAMENTO 134

instância tempo grafo original reduzido

(s) jV j jEj jT j jV j jEj jT j

msm0580 0.23 338 541 11 12 17 6

msm0654 0.18 1290 2270 10 0 0 0

msm0709 1.06 1442 2403 16 42 68 8

msm0920 1.14 752 1264 26 13 18 7

msm1008 0.17 402 695 11 13 18 6

msm1234 0.23 933 1632 13 7 9 4

msm1477 0.51 1199 2078 31 12 17 6

msm1707 0.01 278 478 11 0 0 0

msm1844 0.00 90 135 10 6 8 4

msm1931 0.15 875 1522 10 0 0 0

msm2000 0.14 898 1562 10 0 0 0

msm2152 6.99 2132 3702 37 176 309 23

msm2326 0.07 418 723 14 9 12 5

msm2492 7.64 4045 7094 12 56 91 10

msm2525 1.54 3031 5239 12 11 15 6

msm2601 18.04 2961 5100 16 176 303 12

msm2705 0.24 1359 2458 13 4 5 3

msm2802 0.50 1709 2963 18 9 14 5

msm2846 15.68 3263 5783 89 395 682 61

msm3277 0.28 1704 2991 12 0 0 0

msm3676 0.16 957 1554 10 0 0 0

msm3727 14.39 4640 8255 21 45 74 4

msm3829 46.54 4221 7255 12 400 705 10

msm4038 0.03 237 390 11 0 0 0

msm4114 0.04 402 690 16 0 0 0

msm4190 0.03 391 666 16 0 0 0

msm4224 0.03 191 302 11 0 0 0

msm4312 292.91 5181 8893 10 1342 2433 10

msm4414 0.03 317 476 11 0 0 0

msm4515 0.37 777 1358 13 31 50 8

Tabela A.6: VLSI � Série msm

Page 147: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Bibliogra�a

[1] E. Aarts e J. K. Lenstra, editores. Local Search in Combinatorial Optimization.

Wiley, 1997.

[2] R. Ahuja, T. Magnanti e J. Orlin. Network Flows: Theory, algorithms, and applica-

tions. Prentice-Hall, 1993.

[3] M. P. Bastos e C. C. Ribeiro. Reactive tabu search with path-relinking for the

Steiner problem in graphs. Em Essays and Surveys in Metaheuristics, editado por

C. C. Ribeiro e P. Hansen, págs. 39�58. Kluwer, 2001.

[4] J. Beasley. OR-Library: Distributing test problems by electronic

mail. Journal of the Operational Research Society , 41:1069�1072, 1990.

http://mscmga.ms.ic.ac.uk/info.html.

[5] M. de Berg, M. van Kreveld, M. Overmars e O. Schwarzkopt. Computational Geom-

etry: Algorithms and Applications. Springer-Verlag, 1997.

[6] O. Bor·vka. P°íspev¥k k °e²ení otázky ekonomické stavby elektrovodních sítí. Elek-

trotechnicky Obzor , 15:153�154, 1926.

[7] V. Chvátal. Linear Programming . Freeman, 1983.

[8] A. Claus e N. Maculan. Une nouvelle formulation du problème de Steiner sur un

graphe. Relatório Técnico 280, Centre de Recherche sur les Transports, Université

de Montréal, 1983.

[9] T. Cormen, C. Leiserson e R. Rivest. Introduction to Algorithms. MIT Press/McGraw

Hill, 1990.

[10] E. W. Dijkstra. A note on two problems in connexion with graphs. Numerische

Mathematik , 1:269�271, 1959.

[11] K. Dowsland. Hill-climbing, simulated annealing and the Steiner problem in graphs.

Engineering Optimization, 17:91�107, 1991.

[12] C. Duin. Steiner's Problem in Graphs: Aproximation, reduction, variation. Tese de

Doutorado, Institute for Actuarial Science and Economics, University of Amsterdam,

1993.

135

Page 148: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

BIBLIOGRAFIA 136

[13] C. Duin, 2001. Personal communication.

[14] C. Duin e A. Volgenant. Reduction tests for the Steiner problem in graphs. Networks,

19:549�567, 1989.

[15] C. Duin e S. Voss. E�cient path and vertex exchange in Steiner tree algorithms.

Networks, 29:89�105, 1997.

[16] C. Duin e S. Voss. The Pilot method: A strategy for heuristic repetition with

application to the Steiner problem in graphs. Networks, 34:181�191, 1999.

[17] J. Edmonds. Optimum branchings. Journal of Research of the National Bureau of

Standards, B71:233�240, 1967.

[18] H. Esbensen. Computing near-optimal solutions to the steiner problem in a graph

using a genetic algorithm. Networks, 26:173�185, 1995.

[19] T. A. Feo e M. G. Resende. Greedy randomized adaptive search procedures. Journal

of Global Optimization, 6:109�133, 1995.

[20] M. L. Fredman e R. E. Tarjan. Fibonacci heaps and their uses in improved network

optimization algorithms. Journal of the ACM , 34(3):596�615, 1987.

[21] M. Gendreau, J.-F. Larochelle e B. Sansó. A tabu search heuristic for the Steiner

tree problem. Networks, 34:163�172, 1999.

[22] M. Goemans. The Steiner tree polytope and related polyhedra. Mathematical Pro-

gramming , 63:157�182, 1994.

[23] A. V. Goldberg e R. E. Tarjan. Expected performance of dijkstra's shortest path

algorithm. Relatório técnico, Computer Science Department, Princeton University,

1996.

[24] B. L. Golden e W. R. Stewart. Probabilistic analysis of heuristics. Em The Travelling

Salesman Problem: A Guided Tour of Combinatorial Optimization, editado por E. L.

Lawler, J. K. Lenstra, A. H. G. R. Kan e D. B. Shmoys, págs. 207�250. Wiley, 1985.

[25] M. Grötschel, L. Lovász e A. Schrijver. The ellipsoid method and its consequences

in combinatorial optimization. Combinatorica, 1:169�197, 1981.

[26] M. Grötschel, L. Lovász e A. Schrijver. Corrigendum to our paper �The ellipsoid

method and its consequences in combinatorial optimization�. Combinatorica, 4:291�

295, 1984.

[27] J. Hao e J. Orlin. A faster algorithm for �nding the minimum cut in a directed graph.

Journal of Algorithms, 17:424�446, 1994.

Page 149: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

BIBLIOGRAFIA 137

[28] F. Hwang, D. Richards e P. Winter. The Steiner tree problem, volume 53 de Annals

of Discrete Mathematics. North-Holland, Amsterdam, 1992.

[29] ILOG. Using the CPLEX Callable Library Version 5 , 1997.

[30] A. Kapsalis, V. J. Rayward-Smith e G. D. Smith. Solvign the graphical steiner

tree problem using genetic algorithms. Journal of the Operational Research Society ,

44:397�406, 1993.

[31] R. Karp. Reducibility among combinatorial problems. Em Complexity of Computer

Computations, editado por R. Miller e J. Thatcher, págs. 85�103. Plenum Press, New

York, 1972.

[32] T. Koch e A. Martin. Solving Steiner tree problems in graphs to optimality. Networks,

32:207�232, 1998.

[33] T. Koch, A. Martin e S. Voss. SteinLib: An updated library on Steiner tree problems

in graphs. Relatório Técnico ZIB-Report 00-37, Konrad-Zuse-Zentrum für Informa-

tionstechnik Berlin, 2000. http://elib.zib.de/steinlib.

[34] J. B. Kruskal. On the shortest spanning tree of a graph and the traveling salesman

problem. Proceedings of the American Mathematical Society , 7:48�50, 1956.

[35] A. Lucena e J. Beasley. A branch and cut algorithm for the Steiner problem in

graphs. Networks, 31:39�59, 1998.

[36] N. Maculan. The Steiner problem in graphs. Annals of Discrete Mathematics, 31:185�

212, 1987.

[37] U. Manber. Introduction to Algorithms: A Creative Approach. Addison-Wesley, 1989.

[38] S. L. Martins, P. M. Pardalos, M. G. C. Resende e C. C. Ribeiro. A parallel GRASP

for the Steiner tree problem in graphs using a hybrid local search strategy. Journal

of Global Optimization, 17:267�283, 2000.

[39] K. Melhorn. A faster approximation algorithm for the Steiner problem in graphs.

Information Processing Letters, 27:125�128, 1988.

[40] M. Minoux. E�cient greedy heuristics for Steiner tree problems using reoptimization

and supermodularity. INFOR, 28:221�233, 1990.

[41] B. M. E. Moret e H. D. Shapiro. An empirical assessment of algorithms for con-

structing a minimum spanning tree. DIMACS Monographs in Discrete Mathematics

and Theoretical Computer Science, 15:99�117, 1994.

[42] G. Nemhauser e L. Wolsey. Integer and Combinatorial Optimization. Wiley, New

York, 1988.

Page 150: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

BIBLIOGRAFIA 138

[43] M. Poggi de Aragão, C. C. Ribeiro, E. Uchoa e R. F. Werneck. Hybrid local search

for the Steiner problem in graphs. Em Extended Abstracts of the 4th Metaheuristics

International Conference, págs. 429�433, Porto, Portugal, 2001.

[44] M. Poggi de Aragão, E. Uchoa e R. F. Werneck. Dual heuristics on the exact solution

of large Steiner problems. Em Proceedings of the Brazilian Symposium on Graphs,

Algoritms and Combinatorics, volume 7 de Electronic Notes in Discrete Mathematics,

Fortaleza, Brazil, 2001.

[45] T. Polzin e S. V. Daneshmand. A comparison of Steiner tree relaxations. Discrete

Applied Mathematics, 112(1�3):241�261, 2001.

[46] T. Polzin e S. V. Daneshmand. Improved algorithms for the Steiner problem in

networks. Discrete Applied Mathematics, 112(1�3):263�300, 2001.

[47] F. P. Preparata e M. I. Shamos. Computational Geometry: An Introduction.

Springer-Verlag, 1985.

[48] R. C. Prim. Shortest connection networks and some generalizations. Bell System

Tech. Journal , 36:1389�1401, 1956.

[49] C. C. Ribeiro e M. C. Souza. Tabu search for the Steiner problem in graphs. Networks,

36:138�146, 2000.

[50] C. C. Ribeiro, E. Uchoa e R. F. Werneck. A hybrid GRASP with perturbations

and adaptive path-relinking for the Steiner problem in graphs. Em Proceedings of

the Workshop on Algorithm Engineering as a New Paradigm, págs. 76�116. Kyoto

University, 2000.

[51] I. Rosseti, M. Poggi de Aragão, C. C. Ribeiro, E. Uchoa e R. F. Werneck. New

benchmark instances for the Steiner problem in graphs. Em Extended Abstracts

of the 4th Metaheuristics International Conference, págs. 557�561, Porto, Portugal,

2001.

[52] G. Skorobohatyj. MATHPROG: A collection of codes

for solving various mathematical programming problems.

http://elib.zib.de/pub/Packages/mathprog/index.html.

[53] P. M. Spira e A. Pan. On �nding and updating spanning trees and shortest paths.

SIAM Journal on Computing , 4(3):375�380, 1975.

[54] H. Takahashi e A. Matsuyama. An approximate solution for the Steiner problem in

graphs. Math. Japonica, 24:573�577, 1980.

[55] R. E. Tarjan. E�ciency of a good but not linear set union algorithm. Journal of the

Association for Computing Machinery , 2:212�225, 1975.

Page 151: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

BIBLIOGRAFIA 139

[56] R. E. Tarjan. Data Structures and Network Algorithms. SIAM Press, Philadelphia,

PA, 1983.

[57] E. Uchoa. Algoritmos para Problemas de Steiner com Aplicações em Projeto de

Circuitos VLSI . Tese de Doutorado, Department of Informatics, Catholic University

of Rio de Janeiro, 2001.

[58] E. Uchoa, M. Poggi de Aragão e C. C. Ribeiro. Preprocessing Steiner problems from

VLSI layout. Relatório Técnico MCC 32/99, Department of Informatics, Catholic

University of Rio de Janeiro, 1999.

[59] M. G. A. Verhoeven, M. E. M. Severens e E. H. L. Aarts. Local search for Steiner trees

in graphs. Em Modern Heuristic Search Methods, editado por V. J. Rayward-Smith,

I. H. Osman e C. R. Reeves. Wiley, 1996.

[60] S. Voss. Steiner-Probleme in Graphen. Anton Hain, 1990.

[61] S. Voss. Steiner's problem in graphs: Heuristic methods. Discrete Applied Math-

meatics, 40:45�72, 1992.

[62] P. Winter. Steiner problems in networks: A survey. Networks, 17:129�167, 1987.

[63] P. Winter. Reductions for the rectlinear Steiner tree problem. Networks, 26:187�198,

1995.

[64] L. Wolsey. Integer Programming . Wiley-Interscience, 1998.

[65] R. Wong. A dual ascent approach for Steiner tree problems on a directed graph.

Mathematical Programming , 28:271�287, 1984.

Page 152: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

Índice

Ackermann (função inversa), 6

�(�; �), 6

arborescência, 86

aresta de fronteira, 16, 26

árvore geradora mínima, 6

algoritmo de Bor·vka, 7

algoritmo de Kruskal, 6

algoritmo de Prim, 6

B&A (algoritmo exato), 116

B&C (algoritmo exato), 116

Bor·vka

algoritmo para MST, 7

heurística construtiva, 19

branch-and-ascent, 78, 111, 115

branch-and-bound, 111

branch-and-cut, 111, 112

branching, 112

no branch-and-ascent, 116

no branch-and-cut, 114

strong (forte), 116, 121

variável de, 112

busca local, 47

estratégia geral, 51

implementação, 51

na metaeurística HGP+PR, 69

por caminhos-chaves, 54

por vértices de Steiner, 52

por vértices-chaves, 56

caminhos mínimos

dualidade, 91

caminhos mínimos, 7

complementaridade de folga, 88, 105

componente-raiz, 96

critérios de seleção, 98

corte, 86

custo reduzido, 88

estendido, 94

�xação, 89

custos das arestas, 4

desvio relativo percentual, 31

Diagrama de Voronoi, 15

Dijkstra (algoritmo), 7, 16, 92

diversi�cação, 67, 70

DNH (Distance Network Heuristic), 15

DNH-Bor·vka, 18

DNH-Prim, 17

DNHz, 19

dual adjustment, 89, 105

dual ascent, 86, 95

dual scaling, 104

dualidade, 88

enumeração implícita, 111

�xação por custos reduzidos, 89

�xação ativa, 106

formulação por cortes direcionados, 86

FT (metaeurística), 77

gap de dualidade, 85

grafo de distâncias, 15

grafo de saturação, 91

GRASP, 66

heap, 5

binário, 5

Fibonacci, 5

heurísticas construtivas

na metaeurística HGP+PR, 68

HGP (metaeurística), 67, 71

140

Page 153: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

ÍNDICE 141

HGP+PR (metaeurística), 12, 66, 67, 121

implementaçao de referência, 76

resultados experimentais, 76

Incidência (instâncias), 10

intensi�cação, 67, 70

KM (algoritmo exato), 116

Kruskal

algoritmo para MST, 6, 53

heurística construtiva, 25

Kruskal-B, 25

Kruskal-E, 26

Kruskal-V, 28

Método Piloto (metaeurística), 78

metaeurísticas, 66

para o problema de Steiner, 66

MST, ver árvore geradora mínima

Multispan, 30

nós cruciais, 48

OR-Library (instâncias), 9

oscilação estratégica, 67

ótimo local, 47, 51, 64

path-relinking, ver religamento

PD (algoritmo exato), 116

perturbação

na metaeurística HGP+PR, 67, 70

no religamento, 74

vantagens, 83

pré-processamento, 12

Prim

algoritmo para MST, 6

heurística construtiva, 21

Prim-D, 22

Prim-T, 21

pruning

de uma solução, 30

no branch-and-bound, 112

PUC (instâncias), 11

melhores soluções conhecidas, 12

rami�cação, ver branching

rank, 32

relaxação linear, 85

religamento, 71

adaptativo, 74

critérios de parada, 75

movimentos complementares, 73

por perturbações, 74

reverse delete step, 97

rotina de separação, 87

RTS (metaeurística), 77

saturação, 88

scaling, 104

separação

para o problema de Steiner, 113

Shortest Path Heuristic (SPH), 21

soluções de elite, 71, 72

gerações, 72

lista, 72

solução dual

inviável, 88

maximal, 104

solução primal, 85

SPG (Steiner problem in graphs), 4

SteinLib, 9

melhores soluções conhecidas, 12

strong branching, 116

superaresta, 15

SV (metaeurística), 77

tempo relativo, 36

TS (metaeurística), 77

union-�nd, 5

UPR (algoritmo exato), 116

vértices cruciais, 48

vértices de Steiner, 48

vértices-chaves, 48

vizinhança, 47

para o problema de Steiner, 49

por caminhos-chaves, 50

por vértices de Steiner, 49

por vértices-chaves, 50

Page 154: renatowerneck.files.wordpress.com · tos Agradecimen os A Professores Marcus oggi P de Aragão, Eduardo hoa Uc e Celso Rib eiro, p or não me deixarem esquecer de que sempre é pel

ÍNDICE 142

VLSI (instâncias), 11

Voronoi, 15