• Nenhum resultado encontrado

Até agora o nosso estudo sobre complexidade tem se concentrado em contar ou estimar o número de opera­ ções executadas por um algoritmo dado. Nesta seção adotaremos um ponto de vista diferente: dada uma tarefa (por exemplo, ordenar uma lista), o que é o melhor que podemos esperar que um algoritmo qualquer faça? De forma mais específica, dados conjuntos de condições prévias e posteriores, qual é uma cota inferior para a complexidade em pior caso de um algoritmo que satis­ faça essas condições prévias e posteriores?

Em geral, essa pergunta é muito mais difícil do que a p ergunta de como será o desempenho de um algo­ ritmo. P ara respondê-la, devemos focar na dificuldade intrínseca d a tarefa proposta, e não no algoritmo. Esse tipo de pergunta pertence ao estudo da complexidade

computacional. Embora a maioria das técnicas da teoria

da complexidade computacional esteja além do escopo deste livro, esta seção apresenta alguns exemplos relati­ vamente simples que agora estão ao nosso alcance.

5.4.1 Algoritm os como Decisões

Algumas vezes podemos pensar em um algoritmo como uma sequência de decisões. Um programa aceita alguns valores de entrada e então, através de uma sequência de operações matemáticas, decide sobre alguns valores de saída. Se entendemos os tipos de decisões necessárias para resolver um problema, podemos determinar — em alguns casos -— se um algoritmo está funcionando da forma mais eficiente possível.

P ara ilustrar essa ideia, considere o problema de identificar um a espécie específica de pássaro. Suponha que nos é dado um pássaro desconhecido B para identi­ ficarmos, e por simplicidade suponha que sabemos que

B deve pertencer a uma destas quatro espécies: Steller’s

Jay, Western Scrub Jay, Califórnia Thrasher e Califórnia Towhee. São-nos dados os seguintes fatos a respeitos dessas espécies.

Especie Fatos

Steller’s Jay Quase todo azul, com penacho preto. Western Scrub Jay Quase todo azul, sem penacho. California Thrasher Quase todo marrom, com bico curvo. California Towhee Quase todo marrom, com bico cônico.

Os dois algoritmos a seguir apresentam duas maneiras de identificarmos o pássaro B.

A lgoritm o 5.16 Identificando um pássaro B. se B tem um penacho então

im prim ir B é um Steller’s Jay. senão

se B é quase todo azul então

im prim ir B é um Western Scrub Jay. senão

se B tem um b ico curvo então

im prim ir B é um Califórnia Thrasher. senão

im prim ir B é um Califórnia Towhee.

A lgoritm o 5.17 Identificando um pássaro B. se B é quase todo azul então

r se B tem um penacho então im prim ir B é um Steller’s Jay. senão

l im prim ir B é um Western Scrub Jay. senão

r se 5 tem um bico curvo então

im prim ir B é um Califórnia Thrasher. senão

u im prim ir B é um Califórnia Towhee.

Ambos os algoritmos identificam o pássaro através de uma sequência de perguntas “sim ou não”; são deci­ sões com dois resultados possíveis. Entretanto, eles a fazem de formas ligeiramente diferentes. Para comparar esses algoritmos, considere as árvores de decisão na Figura 5.15.

Ambas as árvores de decisão têm quatro folhas; estas correspondem aos quatro possíveis resultados diferentes do algoritmo: o pássaro B pertence a uma das quatro espécies. No entanto, a altura da árvore para o Algo­ ritmo 5.16 é maior do que a altura da árvore para o Algoritmo 5.17, então o Algoritmo 5.16 deve responder a mais perguntas para identificar corretamente o pássaro. O pior caso do número de perguntas respondidas pelo Algoritmo 5.16 é três, enquanto que o Algoritmo 5.17 precisa responder no máximo a duas perguntas.

Se medirmos eficiência pelo pior caso do número de perguntas respondidas, então o Algoritmo 5.17 é mais eficiente. Mas podemos dizer mais. A análise da árvore de decisão mostra que o Algoritmo 5.17 é o algoritmo mais eficiente possível para resolver esse problema, porque a sua árvore de decisão tem a menor altura possível. Qualquer algoritmo que responde a perguntas “sim ou

F ig u ra 5.15

penacho? azul?

Modelos de árvores de decisão para o Algoritmo 5.16 (à esquerda) e para o Algoritmo 5.17 (à direita).

não” pode ser modelado com uma árvore binária, como na Figura 5.15. Uma vez que identificar B requer distin­ guir entre quatro possíveis resultados, tal árvore deve ter (pelo menos) quatro folhas. A árvore para o Algoritmo 5.17 é a árvore binária mais baixa possível com quatro folhas; não podemos fazer melhor do que isso.

Definição 5.7 Um algoritmo que, no pior caso, resolve um problema dado usando o menor número possível de operações de um tipo dado é chamado de ótimo.

O Algoritmo 5.17 é uma solução para o nosso problema (artificial) de identificação do pássaro que é ótima no que diz respeito ao número de operações das perguntas “sim ou não”. Em geral, provar a otimalidade de um algoritmo é bastante difícil, mas os exemplos a seguir exploram alguns casos para os quais temos as ferramentas necessárias.

E x em plo 5.18 Considere o problema de identificar uma moeda falsificada entre um conjunto de 10 moedas usando apenas uma balança simples de dois pratos. Suponha que todas as moedas genuínas têm o mesmo peso, mas a moeda falsificada pesa um pouco menos do que as moedas genuínas. Quantas pesagens devemos fazer para identificarmos a falsa?

Solução: Cada pesagem é uma operação com três resul­

tados possíveis: ela pode inclinar para a esquerda, inclinar

para a direita ou se equilibrar. Poderíamos tentar um algoritmo dividir-e-conquistar para encontrar a moeda falsificada: divida as moedas em dois grupos de cinco e pese-os. O grupo mais leve contém a moeda falsificada. Repita até você encontrar a moeda. Se você precisar pesar um número ímpar de moedas, mantenha uma moeda à parte e pese o resto; se a balança ficar equili­ brada, a moeda que foi separada é a falsificada.

A Figura 5.16 ilustra esse processo. O galho da esquerda representa o evento de que o lado esquerdo é mais leve, o galho da direita representa a direita sendo o lado mais leve, e o galho do meio representa os dois lados em equilíbrio. Note que esse método requer três pesagens, no pior caso.

Essa abordagem de dividir-e-conquistar não é a única maneira de resolvermos o problema. Por exemplo, pode­ ríamos ter começado deixando duas ou mais moedas de lado, na esperança de encontrarmos mais rápido a moeda falsificada. Uma vez que existem várias outras maneiras de executarmos essa tarefa, devemos nos perguntar se é possível identificar a moeda com menos de três pesa­ gens. Mas qualquer método que criarmos deverá produzir uma árvore de decisão com 10 folhas, porque existem 10 escolhas para a moeda falsificada.

Uma vez que pesar em uma balança de dois pratos é uma operação 3-ária (ou ternária), uma sequência de duas pesagens pode produzir uma árvore com no máximo nove folhas. Portanto, não importa quão espertos sejamos, não existe nenhuma maneira de distinguirmos

k n c2) vs {c3, c4 } {c6, C-j} VS {Cg, c9)

ki}vsk2} c5 S \

k 31 vs k 4} kôl vs k7l cio ksl vs k 9)

C] c2 C3 c4 c5 c7 Cg c9

entre 10 diferentes resultados usando apenas duas pesa­ gens. Por isso a solução esboçada na Figura 5.16 usando

três pesagens é ótima. C*

5.4.2 Uma Cota Inferior

Tanto no exemplo da identificação do pássaro quanto no da moeda falsificada, precisamos saber o número máximo possível de folhas em uma árvore de decisão. O número de filhos de cada vértice é igual ao número de possíveis opções para cada decisão; uma árvore de decisão em que cada decisão tem m opções produz uma árvore m-ária. Um argumento padrão de indução irá estabelcer a seguinte observação.

Lem a 5.1 Seja m > 2 e p > 0 números inteiros. Uma árvore m-ária com altura p tem no máximo mP folhas.3 D em onstração Exercício. (Use indução em p.) Em outras palavras, uma sequência de p decisões, em que cada uma delas tem rn escolhas, pode produzir no máximo mp resultados diferentes. Usamos esse lema implicitamente nas soluções anteriores. O teorema a seguir descreve a nossa técnica de forma mais general. Teorema 5.1 Suponha que n meça o tamanho da entrada

de uma certa tarefa, e suponha que qualquer algoritmo que resolva essa tarefa deve distinguir entre f(n) possi­ bilidades diferentes. Se um algoritmo é baseado em uma operação X que tem m resultados diferentes, então o pior caso do número de operações X que esse algoritmo

executa deve ser no mínimo logTO (/ (n)).

D em onstração O trabalho do algoritmo pode ser mode­ lado em termos de uma árvore de decisão m-ária: toda vez que o algoritmo executa a operação X , ele faz uma decisão entre m escolhas. Uma vez que existem f{n) resultados possíveis, o algoritmo deve executar operações X sufi­ cientes para que essa árvore tenha no mínimo j[n) folhas. Seja p o pior caso do número de vezes que a operação

X é executada. Então a árvore de decisão tem altura p.

Pelo Lema 5.1, essa árvore de decisão tem no máximo

mp folhas. Portanto, f(n) < mP, então logm (/(n)) < p.

□ Esse teorema tende a dar uma cota inferior bastante conservadora; na maioria dos casos um algoritmo irá executar um número muito maior de operações do que o garantido pelo teorema. Entretanto, para dois exem-

3 Lembre que a altura de uma árvore é o número de arestas no caminho mais longo da raiz até a folha. Então uma árvore de altura p repre­ senta uma sequência de no máximo p decisões.

pios importantes — procurar e ordenar — já vimos algo­ ritmos que são tão eficientes quanto possível, no sentido de que a complexidade em pior caso está na mesma 0-classe que a cota inferior dada pelo Teorema 5.1. D efinição 5.8 Suponha que o pior caso do número de operações de um determinado tipo necessárias para resolver um dado problema é no mínimo w{n). Um algo­ ritmo é chamado assintoticamente ótimo se o número de operações que ele usa para. resolver o problema está em 0(w(n)).

Em outras palavras, um algoritmo assintoticamente ótimo é ótimo a menos de uma estimativa 0-grande.

5.4.3 Busca em um Vetor

Recorde dos dois algoritmos para busca em um vetor: a busca sequencial (Algoritmo 5.1) e a busca binária (Algoritmo 5.3). Ambos os algoritmos eram baseados em comparações binárias, ou seja, operações com dois resul­ tados diferentes. No Exemplo 5.9, contamos as opera­ ções A para mostrar que o pior caso em complexidade da busca sequencial é 0(n). O Exemplo 5.16 analisa a operação < para estimar a complexidade da busca binária em 0(log2 rí). O próximo teorema diz que o melhor que podemos fazer é uma busca binária.

P ro posição 5.1 Qualquer algoritmo que usa compa­ rações binárias para buscar um elemento-alvo em um vetor de tamanho n requer no mínimo w(ri) G 0(log2 n) comparações, no pior caso.

D em onstração Um algoritmo em busca deve ser capaz de distinguir entre n + 1 possibilidades: o elemento-alvo pode estar em qualquer uma das posições 1, 2, ..., n, ou ele pode deixar de estar na lista. O Teorema 5.1 nos diz que o pior caso do número de comparações deve ser no mínimo log2 (n + 1), o que está em 0(log2 n). □ Uma vez que a busca binária tem complexidade em pior caso 0(log2 n), ela alcança a cota inferior estabele­ cida pela Proposição 5.1. Em outras palavras, a busca binária é uma solução assintoticamente ótima para o problema da busca, com respeito ao número de compa­ rações.

5.4.4 Ordenação

A melhor maneira de vermos o processo de ordenação de vetor como um problema de decisão é vê-lo como uma escolha de um arranjo correto dentre todos os arranjos possíveis de dados. Um algoritmo de ordenação deve rearranjar os dados, e existe somente uma maneira

de colocar a lista em ordem. Uma vez que existem n! maneiras de rearranjar um vetor de n elementos, temos o seguinte resultado.

P roposição 5.2 Todo algoritmo de ordenação baseado em comparações binárias deve executar no mínimo w(n) G ®(n log2 n) comparações no pior caso para ordenar um vetor de n elementos.

D em o n stração Pela discussão anterior, o Teorema 5.1 mostra que um algoritmo de ordenação deve executar no mínimo log2 (n!) comparações para ordenar uma lista de

n elementos, no pior caso. Uma vez que

log2(n!) = log2 1 + log2 2 H--- b log2 n

< log2 n + log2 n H--- b log2 n

'--- v--- ' n

< nlog2 n,

G 0 (n log2 n). Uma vez que

2 • 3 • • • (n — 1) • n • (ra -1 ) • ( n - 2 ) ••• 2 - 1 > n • n • • • n

n = nn

e, como log2 (n!)2 = 2 log2 (n!), segue que log2(n!) > ^ log2(nn) = in lo g 2n,

portanto log2 (n!) = íl(n log2 n). Pela Definição 4.8, mostramos que log2 (n!) G ®(n log2 n), como queríamos

mostrar. □

Já vimos um algoritmo de busca assintoticamente ótimo: a ordenação por fusão tem pior caso em comple­ xidade ®(n log2 n).

5.4.5

P versus N P

Não deixe a.discussão anterior passar a impressão de que encontrar algoritmos ótimos é sempre fácil. Não é. De fato, existem muitas questões importantes na teoria da complexidade computacional que ninguém sabe como responder. Um exemplo famoso é a pergunta, “P é igual a N P P’ Tentaremos dar sentido a essa pergunta sem entramos a fundo em detalhes técnicos.

A classe P é a coleção de todos os problemas que podem ser resolvidos com um algoritmo cuja comple­ xidade é, no máximo, polinomial: 0 (n r) para algum r. Muitos dos problemas que vimos, incluindo os de busca e ordenação, pertencem à classe P, porque resolvemos esses problemas usando algoritmos de tempo polinomial.

A classe NP é a coleção de todos os problemas cujas soluções podem ser verificadas (mas não necessariamente

encontradas) em tempo polinomial.4 Um exemplo de um

problema em NP é a tarefa de encontrar um circuito de Hamilton em um grafo. E fácil verificar que um dado circuito é hamiltoniano, mas nem sempre é fácil encon­ tramos tal circuito. Um outro exemplo é determinar se um número inteiro n dado é composto; podemos facil­ mente verificar se d divide n, mas podemos levar muito tempo para encontrar d.

Um problema x em NP é chamado de NP-completo se uma solução em tempo polinomial para x leva a uma solução em tempo polinomial para qualquer problema em

NP. Portanto, os problemas NP-completos são de certa

forma os problemas mais difíceis em NP; resolver um deles resolveria todos os outros. A seguir temos alguns problemas iVP-completos bastante conhecidos:

• Determinar se um grafo dado tem um circuito hamil­ toniano.

• Determinar se os vértices de um grafo dado podem ser coloridos com um número dado de cores. • Dada uma fórmula em lógica proposicional, deter­

minar se é possível atribuir valores verdadeiro ou falso para as suas variáveis de modo que o valor da fórmula seja verdadeiro.

• Dado um conjunto U de números inteiros, deter­ minar se existe um subconjunto de U cujos elementos somam 0.

• Dados dois grafos G: e G2, determinar se Gx é isomorfo a um subgrafo de G2.

Há centenas de outros problemas que se sabe que são AP-completos. Se se pudesse encontrar um algo­ ritmo de tempo polinomial para resolver qualquer um desses problemas, existiria uma solução em tempo poli­ nomial para todos os problemas em NP. Em outras palavras, P se igualaria a NP. Mas, até hoje, ninguém encontrou tal algoritmo. Hoje, os matemáticos em geral suspeitam que P A NP, mas nunca encontraram uma demonstração para tal afirmação. Esse é talvez o problema em aberto mais importante na matemática atual.5

4 O “iV” em NP significa “não determinístico”. Se damos um palpite aleatório (não em alguma ordem determinada) e tivermos sorte de acertar esse palpite, podemos demonstrar que a nossa solução está correta em tempo polinomial.

5 A Hipótese de Riemann é provavelmente a rival mais próxima. Dois resultados famosos, o Ultimo Teorema de Fermat e a Conjectura de Poincaré, só foram demonstrados recentemente.

temos log2 (n!) (n!)2 = 1 • n

E x e rc íc io s 5 .4

1. Use urna árvore de decisão para descrever um proce­ dimento ótimo para identificar um pássaro B dentre as seis espécies a seguir, usando apenas perguntas “sim ou não”. Explique como você sabe que o seu procedimento é ótimo.

Espécies Fatos

Yellow Warbler Quase todo amarelo, cabeça da mesma cor.

Wilson’s Warbler Quase todo amarelo, cabeça preta, dorso verde-oliva.

American Goldfinch Quase todo amarelo, cabeça preta, dorso amarelo.

Oak Titmouse Quase todo cinza, com penacho.

Hutton’s Vireo Quase todo cinza, dorso verde-oliva, sem penacho.

Blue-gray Gnatcatcher Quase todo cinza, dorso cinza-escuro, sem penacho.

2. Considere o algoritmo a seguir (bastante desele­ gante) para imprimir três números em ordem cres­ cente.

A lgoritm o 5.18 Imprimindo três números em ordem por força bruta.

Condições prévias: a, ò, c G R .

Condições posteriores: Os elementos de {a, ò, c} são impressos em ordem crescente.

se a < b então r se b < c então imprimir <2, ò, c senão r se a < c então imprimir a, c, b senão l l imprimir c, a, b senão r se a < c então imprimir ò, a, c senão r se b < c então imprimir b, c, a senão i_ l imprimir c, ò, a * 3

(a) Desenhe uma árvore de decisão para modelar as escolhas feitas por esse algoritmo.

(b) Esse algoritmo é ótimo com respeito ao número de comparações <? Explique.

3. Em uma coleção de 10 moedas, 4 moedas são falsifi­ cadas e pesam menos do que as moedas verdadeiras. Considere uma balança de dois pratos e encontre uma boa cota inferior no número de pesagens para

identificar todas as moedas falsificadas. (Suponha que a balança tem três estados: inclinada para a esquerda, inclinada para a direita ou equilibrada.) 4. Considere o problema de identificar uma moeda

falsificada usando uma balança de dois pratos. Suponha, como fizemos no Exemplo 5.18, que 1 moeda de um conjunto de 10 é falsa, mas desta vez suponha que a moeda falsificada pode ser ou mais pesada ou mais leve. O que o Teorema 5.1 diz sobre o número mínimo de pesagens neste caso?

5. Suponha que 1 moeda em um conjunto de 8 moedas é falsa, e que a moeda falsificada é mais leve do que as outras. Considere uma balança de dois pratos. (a) Use o Teorema 5.1 para encontrar uma cota

inferior no número de pesagens necessárias para identificar a moeda falsificada.

(b) Encontre uma estratégia que identifique a moeda falsificada em um número ótimo de pesagens. Desenhe uma árvore de decisão para mostrar que a sua estratégia funciona.

6. Suponha que 1 moeda de um conjunto de 16 é falsa e tem um peso diferente do das outras moedas. Em vez de uma balança com três posições, você tem um aparelho que diz se duas quantidades têm ou não o mesmo peso. Em outras palavras, o seu aparelho tem apenas duas posições: “mesma” ou “diferente”. (a) Use o Teorema 5.1 para encontrar uma cota infe­

rior do número de vezes que você precisa usar esse aparelho até identificar a moeda falsa. (b) Encontre uma estratégia que identifique a moeda

falsa no número ótimo de pesagens. Desenhe uma árvore de decisão para mostrar como a sua estratégia funciona.

7. Seja X um conjunto de n números naturais. Consi­ dere a tarefa de determinar se existe um par de números em X cuja diferença é 100. Use o Teorema 5.1 para encontrar uma cota inferior do pior caso do número de comparações binárias necessárias para realizar esta tarefa. Dê uma resposta exata, e também uma estimativa 0-grande.

8. Um fio com 24 luzes de Natal tem uma lâmpada com defeito e uma lâmpada especial. O fio de luzes pode ser testado removendo qualquer subconjunto das 24 lâmpadas, deixando o resto conectado. Se a lâmpada com defeito está conectada, nenhuma das luzes irá funcionar. Se a lâmpada especial está conectada (e a com defeito não está conectada), então todas as lâmpadas irão piscar. Se nem a lâmpada com defeito nem a lâmpada especial estão conectadas, todas as luzes irão acender normalmente. Use o Teorema 5.1

para encontrar uma boa cota inferior para o número 18. de testes necessários para identificar a lâmpada com defeito e a lâmpada especial. Explique o seu racio­ cínio. (Não desenhe a árvore inteira!)

Existe um a a t r i b u i ç ã o d e valores verdadeiros ou falsos p a ra as v a r i á v e i s p, q, r, s e t tal que a

fórmula

[(p V q) A ( - p V - r ) ] — I(s V í) A (- 8 V - i) ]

9. Considere a tarefa de selecionar de forma aleatória uma pessoa em um grupo com n pessoas lançando repetidamente um único dado de seis lados.

(a) Use o Teorema 5.1 para encontrar uma cota inferior do pior caso do número de lances neces­ sários para selecionar uma pessoa em um grupo de n = 72 pessoas.

(b) Descreva um algoritmo ótimo para a seleção de uma pessoa em um grupo de n = 72 pessoas. (c) Qual o maior valor de n para o qual uma pessoa

pode ser selecionada aleatoriamente usando cinco lances?

10. Calcule o melhor caso do número de questões respon­ didas pelos Algoritmos 5.16 e 5.17.

11. Calcule o caso médio do número de questões respondidas pelos Algoritmos 5.16 e 5.17. Suponha que cada uma das quatro espécies é igualmente provável.

12. A ordenação por bolhas é assintoticamente ótima? Explique por que sim ou por que não. 13 14 15 16 17

13. O Quicksort é um algoritmo recursivo de ordenação que tem o caso médio em complexidade 0 (n log2 n) e o pior caso em complexidade 0 (n 2). O Quicksort é assintoticamente ótimo? Explique por que sim ou por que não.

14. Demonstre o Lema 5.1 usando indução em p. 15. Suponha que s e t são duas cadeias de comprimento