MAC 5710 - Estruturas de Dados e sua Manipulação
URL: http://www.ime.usp.br/song/mac5710.html
Eficiência ou complexidade de algoritmos
(Daremos aqui um tratamento informal sobre o assunto. Maiores
detalhes devem ser obtidos em cursos de Análise de Algoritmos.)
Costuma-se analisar um algoritmo em termos de tempo e espaço (ou memória). Para o tempo, diversas medidas são em princípio possíveis:
Três casos podem ser considerados: o melhor caso, o caso
médio e o pior caso. O estudo do caso médio depende
do conhecimento ou suposição da distribuição
das entradas ao problema. Em geral o pior caso é
o mais fácil de se analisar.
Por exemplo, se temos 2 métodos para resolver um
mesmo problema, cuja entrada tem tamanho , podemos
ter:
Método 1:
operações
Método 2:
operações
Dependendo do valor de , método 1 pode requerer mais
ou menos operações que método 2.
Notação O
Para estudarmos o comportamento assintótico - para grande -
interessa-nos o termo de ordem superior:
Método 1:
Método 1:
A notação O pode ser formalizada como se segue:
Dizemos que
se existirem inteiro
e
constante
tais que
Isto é, para valores de suficientemente grandes,
não cresece mais rapidamente que
.
A importância da complexidade pode ser observada pelo
seguinte exemplo, que mostra 5 algoritmos a
para resolver um mesmo problema, de complexidades
diferentes. Supomos que uma operação leva 1 ms para ser
efetuada. A tabela seguinte dá o tempo necessário por
cada um dos algoritmos. (Sempre suporemos logaritmos na base 2.)
![]() |
![]() |
![]() |
![]() |
![]() |
|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
16 | 0.016s | 0.064s | 0.256s | 4s | 1m 4s |
32 | 0.032s | 0.16s | 1s | 33s | 46 dias |
512 | 0.512s | 9s | 4m 22s | 1 dia 13h | ![]() |
Podemos muitas vezes melhorar o tempo de execução de um
programa (que implementa um algoritmo dado) fazendo otimizações
locais (e.g. usar ao invés de
, em máquinas
em que a multiplicação é mais demorada que a adição).
Entretanto, melhorias substanciais são muitas vezes obtidas
se usarmos um algoritmo diferente, com outra complexidade de tempo,
e.g. obter um algoritmo de ao invés de
.
Cota superior ou limite superior (``upper bound'')
Seja dado um problema, por exemplo, multiplicação de duas
matrizes quadradas de ordem .
Conhecemos um algoritmo para resolver este problema
(pelo método trivial) de complexidade
.
Sabemos assim que a complexidade deste problema não deve
superar
, uma vez que existe um algoritmo desta
complexidade que o resolve.
Uma cota superior (ou ``upper bound'') deste problema é
.
A cota superior de um problema pode mudar se alguém
descobrir um outro algoritmo melhor. Isso de fato
aconteceu com o algoritmo de Strassen que é
de
.
Assim a cota superior do problema de multiplicação
de matrizes passou a ser
.
Outros pesquisadores melhoraram ainda este resultado.
Atualmente o melhor resultado é o de Coppersmith
e Winograd - de
.
Notem que a cota superior de um problema depende do algoritmo.
A cota superior de um problema é parecida com o record mundial de uma modalidade de atletismo. Ela é estabelecida pelo melhor atleta (algoritmo) do momento. Assim como o record mundial, a cota superior pode ser melhorada por um algoritmo (atleta) mais veloz.
``Cota Superior'' dos 100 metros rasos:
Ano | Atleta (Algoritmo) | Tempo |
1988 | Carl Lewis | 9s92 |
1993 | Linford Christie | 9s87 |
1993 | Carl Lewis | 9s86 |
1994 | Leroy Burrell | 9s84 |
1996 | Donovan Bailey | 9s84 |
1999 | Maurice Greene | 9s79 |
2002 | Tim Montgomery | 9s78 |
Cota inferior ou limite inferior (``lower bound'')
As vezes é possível demonstrar que para um dado problema,
qualquer que seja o algoritmo a ser usado, o problema
requer pelo menos um certo número de operações.
Essa complexidade é chamada cota inferior ou ``lower bound''
do problema. Veja que a cota inferior depende do problema
mas não do particular algoritmo. Usamos a letra
em lugar de
para denotar uma cota inferior.
Para o problema de multiplicação de matrizes de
ordem , apenas para ler os elementos das duas matrizes
de entrada leva tempo
. Assim uma cota inferior
trivial é
.
Na analogia anterior, uma cota inferior
de uma modalidade de atletismo não dependeria mais
do atleta. Seria algum tempo mínimo que a modalidade exige,
qualquer que seja o atleta.
Uma cota inferior trivial para os 100 metros rasos
seria o tempo que a velocidade da luz leva para percorrer
100 metros no vácuo.
Se um algoritmo tem uma complexidade que é igual
a cota inferior do problema, então ele é
ótimo. O algoritmo de Coppersmith e Winograd é
de mas a cota inferior é de
.
Portanto não podemos dizer que ele é ótimo.
Pode ser que esta cota superior possa ainda ser melhorada.
Pode também ser que a cota inferior de
possa ser melhorada (isto é ``aumentada''). Muitos
pesquisadores desta área dedicam seu tempo
tentando encurtar este intervalo (``gap'') até
encostar uma da outra.