Vamos analisar uma relaxação linear do programa inteiro:
minimize cx
sob as restriçõesx(δG(S)) ≥ 1, para cada S em A, x ≥ 0,
Podemos agora apresentar o dual do programa linear acima. Nesse caso, y é um vetor indexado por A.
maximize y(A)
sob as restriçõesy(A(e)) ≤ ce, para cada e em EG, y ≥ 0,
onde y(A) = P
S∈AyS e A(e) ={S ∈ A:e∈δG(S)}.
Observando a expressão do programa dual, dizemos que uma aresta e é justa por y se temos a igualdadey(A(e)) =ce.
5.3 Algoritmo de Goemans-Williamson
Nessa seção apresentaremos o algoritmo para o PAS proposto por Michael Xavier Goe-mans e David Paul Williamson em seu artigo [GW95]. O algoritmo de GoeGoe-mans-Williamson consiste de uma 2-aproximação para o PAS que utiliza a técnica primal dual.
O algoritmo de Goemans-Williamson é composto por duas etapas. A primeira etapa é executada através do algoritmo pasExpansao, que será descrita ainda nesse capítulo e utiliza a metodologia primal-dual. O algoritmo devolve uma árvore de Steiner T e um vetor dual viável y tal que todas as arestas em T são justas por y. Já a segunda etapa é desempenhada pelo algoritmo pasPoda que foi descrito na seção 5.1.
Vamos agora estudar o algoritmo iterativo pasExpansao.
O algoritmo parte de uma solução viável y do programa dual e uma oresta F de Gtal que o vetor característico de F não satisfaz ao menos uma restrição do programa primal.
Isso implica que F tem pelo menos uma componente ativa.
Em cada iteração o algoritmo tenta obter um vetor mais próximo da solução ótima do problema, aumentando o valor das posições dey correspondentes às componentes ativas da oresta F, até que alguma aresta que justa.
Quando isso ocorre, a aresta em questão é incluída na oresta F e uma nova iteração é iniciada. O algoritmo termina quando não houver nenhuma componente de F ativa.
Descreveremos mais detalhadamente o algoritmo pasExpansao na próxima seção.
Ideia do algoritmo
SejaLF a coleção laminar constituída pelos conjuntos de vértices que pertenceram à um componente de F em algum instante do algoritmo. Notemos que LF depende apenas de F
e A depende exclusivamente de Ge dos vértices em R.
Temos então queL∗F∩ A é a coleção de conjuntos de vértices dos componentes ativos de F. Notemos que cada elementoS deL∗F ∩ Aa restrição do problema primalx(δG(S))≥1é violada, onde x é o vetor característico de F.
A primeira iteração começa uma oresta geradora F que não possui nenhuma aresta, sendo composta por |VG| componentes. Cada componente de F é composta por um vértice distinto do grafo G. Além disso, no início da primeira iteração, o vetory é o vetor nulo.
Dizemos que uma aresta deGé externa aF se possui seus vértices extremos em elemen-tos distinelemen-tos de L∗F. Ou seja, se os seus pontos extremos pertencem a componentes distintos deF.
Em cada iteração o algoritmo inclui uma aresta externa à F. A regra de decisão sobre qual aresta deve ser incluída é baseada em um valor numérico denominado folga das arestas externas. O algoritmo aumenta uniformemente os valores deyS comS emL∗F∩ Amantendo a viabilidade. A folga de uma aresta e é então valor máximo que podemos acrescentar a y(A(e)) até que alguma aresta que justa por y.
Dessa forma podemos denir os valores das folgas do seguinte modo: dada uma aresta externa uv, denimos a folga de uv, denotada por f olga(uv)como:
f olga(uv) =
cuv−P
S:uv∈δ(S)yS
2 , seu e v pertencem a componentes ativas;
cuv−P
S:uv∈δ(S)yS, se ou u ouv pertence a uma componente ativa;
∞, seu e v pertencem a componentes inativas.
A aresta escolhida para ser inserida em F é a que possui folga com valor mínimo dentre todas as arestas externas. Após incluir a nova aresta emF, o vetoryé atualizado, somando-se a folga da aresta insomando-serida ao valor das posições de y que correspondem às componentes deF que eram ativas antes da inclusão da aresta.
Após a atualização de y, uma nova iteração é iniciada.
O algoritmo naliza sua execução quando não houverem mais conjuntos ativos em F. Então existe um componente T0 de F que contém todos os vértices terminais e os demais componentes são unitários [Mat12].
Algoritmo pasExtensao(G, c, R): Recebe um grafo conexo G, um vetor de custo c que a cada aresta e de EG associa um valor inteiro positivo ce e um conjunto Rde vértices terminais com |R| ≥2. Devolve uma árvore de SteinerT0 e um vetor y indexado por A tal que toda aresta em T0 é justa pory.
Então o algoritmo de Goemans-Williamson utilizado para o PAS é composto por dois passos:
(1) Utilizo o algoritmopasExtensao(G, c, R)e encontro uma árvore de Steiner T0 e um vetor y indexado por A.
5.3 ALGORITMO DE GOEMANS-WILLIAMSON 59 (2) Executo o algoritmo pasPoda(T0, c, R)e encontro uma árvore de Steiner T. Devolvo
T ey.
Em [GW95], Goemans e Williamson demonstraram que o algoritmo proposto por eles possui um consumo de tempo de O(|VG|2log|VG|). Além disso, em Matsubara [Mat12], é demonstrado detalhadamente que o algoritmo de Goemans-Williamson é uma 2-aproximação para o PAS.
Ilustração do algoritmo de Goemans-Williamson
Vamos agora ilustrar a execução do algoritmo de Goemans-Williamson através de um exemplo. Para facilitar o entendimento, tomaremos um grafo G completo tal que o custo associado a cada aresta é igual à distância euclideana entre suas extremidades. Omitiremos a exibição das arestas na gura. As arestas que serão representadas são as arestas justas pory que foram inseridas na orestaF. Os vértices terminais serão representados por bolas de coloração preta e os demais vértices serão representadas por bolas de coloração branca.
Representaremos a oresta F gerada pelo algoritmo apenas pelo seu conjunto de arestas.
Figura 5.4: Algoritmo de Goemans Williamson (fase de expansão) - passos 1 e 2
O grafo utilizado nesse exemplo está representado na gura 5.4(a). Notemos que o con-junto de vértices VG do grafo e de terminaisR são:
VG = {a, b, c, d, e, f, g, h, i};
R = {b, d, f, g, i}. .
Então na primeira iteração temos os conjuntos:
F = ∅;
y = 0;
LF = {{a},{b},{c},{d},{e},{f},{g},{h},{i}};
L∗F = {{a},{b},{c},{d},{e},{f},{g},{h},{i}};
L∗F ∩ A = {{b},{d},{f},{g},{i}}.
O crescimento uniformes dos componentes de y é evidenciado nas guras pelo crescimento das molduras ao redor dos elementos de L∗F ∩ A. Esse crescimento ocorre até que alguma aresta que justa. Na gura 5.4(b) notamos que a primeira aresta a car justa é a aresta f g. Então f g é adicionada à oresta F, e o passo 2 é nalizado.
Figura 5.5: Algoritmo de Goemans Williamson (fase de expansão) - passos 3 e 4
No início do passo 3, temos os conjuntos:
F = {f g};
LF = {{a},{b},{c},{d},{e},{f},{g},{h},{i},{f, g}};
L∗F = {{a},{b},{c},{d},{e},{f, g},{h},{i}};
L∗F ∩ A = {{b},{d},{f, g},{i}}.
Após o incremento uniforme dos componentes de y em L∗F ∩ A vemos na gura 5.5(a) que a arestahi cou justa. Daí segue que:
F = {f g, hi};
LF = {{a},{b},{c},{d},{e},{f},{g},{h},{i},{f, g},{h, i}};
L∗F = {{a},{b},{c},{d},{e},{f, g},{h, i}}.
5.3 ALGORITMO DE GOEMANS-WILLIAMSON 61 Então, no início do passo 4, temos:
L∗F ∩ A = {{b},{d},{f, g},{h, i}}.
Notamos agora que a aresta justa é a arestacg, conforme gura5.5 (b). Ela é então incluída na oresta F e o passo é nalizado. No início do passo 5 temos,
Figura 5.6: Algoritmo de Goemans Williamson (fase de expansão) - passos 5 e 6
F = {cg, f g, hi};
LF = {{a},{b},{c},{d},{e},{f},{g},{h},{i},{f, g},{h, i},{c, f, g}};
L∗F = {{a},{b},{d},{e},{c, f, g},{h, i}};
L∗F ∩ A = {{b},{d},{c, f, g},{h, i}}.
Na gura5.6 (a) podemos ver que a arestade cou justa conectando dois conjuntos ativos.
Então é essa a aresta candidata que incluiremos emF nesse passo. Obtemos assim, F = {cg, de, f g, hi};
LF = {{a},{b},{c},{d},{e},{f},{g},{h},{i},{d, e},{f, g},{h, i},{c, f, g}};
L∗F = {{a},{b},{d, e},{c, f, g},{h, i}};
L∗F ∩ A = {{b},{d, e},{c, f, g},{h, i}}.
O passo 6 é exibido na gura 5.6 (b). Note que agora incluímos a aresta dg à F. Então, F = {cg, dg, de, f g, hi};
LF = {{a},{b},{c},{d},{e},{f},{g},{h},{i},{d, e},{f, g},{h, i},{c, f, g},{c, d, e, f, g}};
L∗F = {{a},{b},{c, d, e, f, g},{h, i}};
L∗F ∩ A = {{b},{c, d, e, f, g},{h, i}}.
Figura 5.7: Algoritmo de Goemans Williamson (fase de expansão) - passos 7 e 8
Na gura 5.7 (a) descrevemos o passo 7. Nesse passo a aresta ad ca justa e é inserida à oresta.
F = {ad, cg, dg, de, f g, hi};
LF = {{a},{b},{c},{d},{e},{f},{g},{h},{i},{d, e},{f, g},{h, i},{c, f, g},{c, d, e, f, g}, {a, c, d, e, f, g}};
L∗F = {{b},{a, c, d, e, f, g},{h, i}};
L∗F ∩ A = {{b},{a, c, d, e, f, g},{h, i}}.
Já no passo 8, a aresta incluída é a aresta ab. Com isso, ela é incluída em F e os dois conjuntos ativos são unidos. Daí,
F = {ad, cg, dg, de, f g, hi};
LF = {{a},{b},{c},{d},{e},{f},{g},{h},{i},{d, e},{f, g},{h, i},{c, f, g},{c, d, e, f, g}, {a, c, d, e, f, g},{a, b, c, d, e, f, g}};
L∗F = {{a, b, c, d, e, f, g},{h, i}}.
Então, no início do passo 9, temos:
L∗F ∩ A = {{a, b, c, d, e, f, g},{h, i}}.
Como L∗F ∩ A 6=∅, o algoritmo continua a sua execução. Observe que agora a aresta justa
5.3 ALGORITMO DE GOEMANS-WILLIAMSON 63
Figura 5.8: Algoritmo de Goemans Williamson (fase de expansão) - passo 9
é gh. Incluímos ela à oresta. Agora, temos:
F = {ad, cg, dg, de, f g, gh, hi};
LF = {{a},{b},{c},{d},{e},{f},{g},{h},{i},{d, e},{f, g},{h, i},{c, f, g},{c, d, e, f, g}, {a, c, d, e, f, g},{a, b, c, d, e, f, g},{a, b, c, d, e, f, g, h, i}};
L∗F = {{a, b, c, d, e, f, g, h, i}};
L∗F ∩ A = ∅.
Como L∗F ∩ A = ∅, então o algoritmo de Goemans-Williamson naliza a execução de pasExtensao (fase de extensão). Então T0 = F é uma árvore de Steiner. A partir daqui dá-se início a fase de poda com o algoritmo pasPoda aplicado à árvore T0
Figura 5.9: Algoritmo de Goemans Williamson (fase de poda)
A gura 5.9(a) exibe a árvore de Steiner T devolvida pelo algoritmo pasExtensao. Notemos que o conjunto de vértices folha de T0 é dado por {b, c, e, f, i}. Como o conjunto de vértices terminais éR ={b, d, f, g, i}, então o algoritmo elimina as folhasc ee. A aresta única ligada a c écg e a aresta ligada ae é de, então:
T =T0− {cg} − {de}.
Agora o conjunto de vértices folha de T é {b, f, i}. Como agora todos os vértices folha são terminais, então o algoritmo pasPoda é nalizado, concluindo também a execução do algoritmo de Goemans-Williamson.
Como o algoritmo é uma 2-aproximação para o PAS então temos que:
c(T)≤2 opt(G, c, R),
onde opt(G, c, R) representa o valor ótimo para o PAS.
Capítulo 6
Considerações nais
Inicialmente nossa intenção para este trabalho era estudar o problema da árvore de Steiner com coleta de prêmios.
Tomemos um grafo G = (VG, EG) com custos não negativos nas arestas. Ao invés de denir um conjunto de vértices terminais, vamos tomar uma função penalidade πv que associa a cada vértice v de VG um valor não negativo denominado penalidade associada ao vérticev. Dada uma T subárvore de G, a penalidade paga pelos vértices não conectados por T é
π( ¯T) =π(VG\VT) = X
v6∈VT
πv.
Podemos então denir o problema da árvore de Steiner com coleta de prêmios, abreviado por PASCP do seguinte modo.
PASCP(G, c, π): Dados um grafo conexo G, uma função custo ce que a cada arestaeem EGassocia um custo não negativo e uma função penalidadeπv que a cada vérticev deVGassocia uma penalidade não negativa, encontrar uma árvore T que minimizec(T) +π( ¯T).
Notemos que o problema da árvore de Steiner é um caso particular de problema da árvore de Steiner com coleta de prêmios onde a penalidade dos vértices terminais é igual a innito.
Entretanto, durante a elaboração do trabalho percebemos que os objetivos iniciais eram audaciosos demais tendo em vista os prazos a cumprir em um trabalho de conclusão de curso.
Na verdade, estudar o problema da árvore de Steiner já se mostrou bastante desaador.
Direcionamos então, os esforços no estudo do problema da árvore de Steiner, apontando a diculdade de se encontrar o solução ótima para o problema e exibindo os casos particulares em que isso é possível.
Observamos que quando o conjunto de vértices terminais é composto de apenas dois vértices o PAS resume-se ao problema dos caminhos mínimos (PCM) que foi denida no capítulo 3. Nesse capítulo, apresentamos duas formas clássicas de resolver o PCM: os algo-ritmos de Dijkstra e de Bellman-Ford. Mostramos ainda que o algoritmo de Dijkstra exige
65
que os custos associados aos arcos seja não negativo, restrição essa que é contornada se utilizarmos o algoritmo de Bellman-Ford.
Um outro caso particular estudado é quando o conjunto de vértices terminais coincide com o conjunto de vértices do grafo. Nesse caso o PAS é equivalente ao problema da árvore geradora mínima (PAGM), discutida no capítulo 4. Apresentamos ainda duas formas de resolver esse problema: os algoritmos de Prim e de Kruskal.
A diculdade de resolver o PAS nos demais casos tem justicado a decisão de sacricar a solução ótima para o problema visando buscar uma solução que garantidamente se aproxime da solução ótima e que seja computada em tempo razoável. Utilizando essa abordagem, introduzimos o algoritmo de Goemans-Williamson que é uma 2-aproximação para o PAS que utiliza a metodologia primal-dual.
A tabela 6.1resume os casos particulares do PAS, os respectivos algoritmos para resolvê-lo, bem como seus consumos de tempo. Nela, o número de vértices do digrafo é representado por n e o número de arcos, ou arestas no caso de grafos, é representada por m.
terminais problema equivalente algoritmo consumo de tempo
|R|= 2 PCM Dijkstra O(n2)
|R|= 2 PCM Bellman-Ford O(n m)
|R|=n PAGM Prim O(mlogn)
|R|=n PAGM Kruskal O(mlogn)
2<|R|< n PAS Goemans-Williamson O(n2logn) Tabela 6.1: Algoritmos estudados nesse trabalho
Para todos os algoritmos em que a solução ótima do problema é atingida, foi criada um programa de teste que verica a validade dos algoritmos implementados através de um certicado de otimalidade. Isso garante que as implementações dos programas elaborados neste trabalho estão corretos.