Anda di halaman 1dari 12

AULA

E FICINCIA

DE ALGORITMOS E
PROGRAMAS

Medir a eficincia de um algoritmo ou programa significa tentar predizer os recursos necessrios para seu funcionamento. O recurso que temos mais interesse neste momento o tempo
de execuo embora a memria, a comunicao e o uso de portas lgicas tambm podem ser de
interesse. Na anlise de algoritmos e/ou programas alternativos para soluo de um mesmo
problema, aqueles mais eficientes de acordo com algum desses critrios so em geral escolhidos como melhores. Nesta aula faremos uma discusso inicial sobre eficincia de algoritmos e
programas tendo como base as referncias [1, 2, 8].

2.1 Algoritmos e programas


Nesta aula, usaremos os termos algoritmo e programa como sinnimos. Dessa forma, podemos dizer que um algoritmo ou programa, como j sabemos, uma seqncia bem definida
de passos descritos em uma linguagem de programao especfica que transforma um conjunto de valores, chamado de entrada, e produz um conjunto de valores, chamado de sada.
Assim, um algoritmo ou programa tambm uma ferramenta para solucionar um problema
computacional bem definido.
Suponha que temos um problema computacional bem definido, conhecido como o problema da busca, que certamente j nos deparamos antes. A descrio mais formal do problema
dada a seguir:
Dado um nmero inteiro n, com 1 6 n 6 100, um conjunto C de n nmeros inteiros
e um nmero inteiro x, verificar se x encontra-se no conjunto C.
O problema da busca um problema computacional bsico que surge em diversas aplicaes prticas. A busca uma operao bsica em computao e, por isso, vrios bons programas que a realizam foram desenvolvidos. A escolha do melhor programa para uma dada
aplicao depende de alguns fatores como a quantidade de elementos no conjunto C e da complexidade da estrutura em que C est armazenado.
Se para qualquer entrada um programa pra com a resposta correta, ento dizemos que o
mesmo est correto. Assim, um programa correto soluciona o problema computacional associado. Um programa incorreto pode sequer parar, para alguma entrada, ou pode parar mas com
uma resposta indesejada.
9

2.2 A NLISE

DE ALGORITMOS E PROGRAMAS

10

O programa 2.1 implementa uma busca de um nmero inteiro x em um conjunto de n


nmeros inteiros C armazenado na memria como um vetor. A busca se d seqencialmente
no vetor C, da esquerda para direita, at que um elemento com ndice i no vetor C contenha o
valor x, quando o programa responde que o elemento foi encontrado, mostrando sua posio.
Caso contrrio, o vetor C todo percorrido e o programa informa que o elemento x no se
encontra no vetor C.
Programa 2.1: Busca de x em C.
#include <stdio.h>
#define MAX 100
/* Recebe um nmero inteiro n, com 1 <= n <= 100, um conjunto C de n
nmeros inteiros e um nmero inteiro x, e verifica se x est em C */
int main(void)
{
int n, i, C[MAX], x;
printf("Informe n: ");
scanf("%d", &n);
for (i = 0; i < n; i++) {
printf("Informe um elemento: ");
scanf("%d", &C[i]);
}
printf("Informe x: ");
scanf("%d", &x);
for (i = 0; i < n && C[i] != x; i++)
;
if (i < n)
printf("%d est na posio %d de C\n", x, i);
else
printf("%d no pertence ao conjunto C\n", x);
return 0;
}

2.2 Anlise de algoritmos e programas


Antes de analisar um algoritmo ou programa, devemos conhecer o modelo da tecnologia de
computao usada na mquina em que implementamos o programa, para estabelecer os custos
associados aos recursos que o programa usa. Na anlise de algoritmos e programas, consideramos regularmente um modelo de computao genrico chamado de mquina de acesso aleatrio (do ingls random acess machine RAM) com um processador. Nesse modelo, as instrues
so executadas uma aps outra, sem concorrncia. Modelos de computao paralela e distribuda, que usam concorrncia de instrues, so modelos investigativos que vm se tornando
realidade recentemente. No entanto, nosso modelo para anlise de algoritmos e programas no
leva em conta essas premissas.

FACOM

UFMS

2.2 A NLISE

DE ALGORITMOS E PROGRAMAS

11

A anlise de um programa pode ser uma tarefa desafiadora envolvendo diversas ferramentas matemticas tais como combinatria discreta, teoria das probabilidades, lgebra e etc.
Como o comportamento de um programa pode ser diferente para cada entrada possvel, precisamos de uma maneira que nos possibilite resumir esse comportamento em frmulas matemticas simples e de fcil compreenso.
Mesmo com a conveno de um modelo fixo de computao para analisar um programa,
ainda precisamos fazer muitas escolhas para decidir como expressar nossa anlise. Um dos
principais objetivos encontrar uma forma de expresso abstrata que simples de escrever
e manipular, que mostra as caractersticas mais importantes das necessidades do programa e
exclui os detalhes mais tediosos.
No difcil notar que a anlise do programa 2.1 depende do nmero de elementos fornecidos na entrada. Isso significa que procurar um elemento x em um conjunto C com milhares
de elementos certamente gasta mais tempo que procur-lo em um conjunto C com apenas trs
elementos. Alm disso, importante tambm notar que o programa 2.1 gasta diferentes quantidades de tempo para buscar um elemento em conjuntos de mesmo tamanho, dependendo de
como os elementos nesses conjuntos esto dispostos, isto , da ordem como so fornecidos na
entrada. Como fcil perceber tambm, em geral o tempo gasto por um programa cresce com
o tamanho da entrada e assim comum descrever o tempo de execuo de um programa como
uma funo do tamanho de sua entrada.
Por tamanho da entrada queremos dizer, quase sempre, o nmero de itens na entrada.
Por exemplo, o vetor C com n nmeros inteiros onde a busca de um elemento ser realizada
tem n itens ou elementos. Em outros casos, como na multiplicao de dois nmeros inteiros, a
melhor medida para o tamanho da entrada o nmero de bits necessrios para representar essa
entrada na base binria. O tempo de execuo de um programa sobre uma entrada particular
o nmero de operaes primitivas, ou passos, executados por ele. Quanto mais independente
da mquina a definio de um passo, mais conveniente para anlise de tempo dos algoritmos
e programas.
Considere ento que uma certa quantidade constante de tempo necessria para executar
cada linha de um programa. Uma linha pode gastar uma quantidade de tempo diferente de
outra linha, mas consideramos que cada execuo da i-sima linha gasta tempo ci , onde ci
uma constante positiva.
Iniciamos a anlise do programa 2.1 destacando que o aspecto mais importante para sua
anlise o tempo gasto com a busca do elemento x no vetor C contendo n nmeros inteiros,
descrita entre a entrada de dados (leitura) e a sada (impresso dos resultados). As linhas
restantes contm diretivas de pr-processador, cabealho da funo main , a prpria entrada
de dados, a prpria sada e tambm a sentena return que finaliza a funo main . fato
que a entrada de dados e a sada so, em geral, inerentes aos problemas computacionais e,
alm disso, sem elas no h sentido em se falar de processamento. Isso quer dizer que, como a
entrada e a sada so inerentes ao programa, o que de fato damos mais importncia na anlise
de um programa no seu tempo gasto no processamento, isto , na transformao dos dados
de entrada nos dados de sada. Isto posto, vamos verificar a seguir o custo de cada linha no
programa 2.1 e tambm o nmero de vezes que cada linha executada. A tabela a seguir ilustra
esses elementos.

FACOM

UFMS

2.2 A NLISE

12

DE ALGORITMOS E PROGRAMAS

#include <stdio.h>
#define MAX 100
int main(void)
{
int n, i, C[MAX], x;
printf("Informe n: ");
scanf("%d", &n);
for (i = 0; i < n; i++) {
printf("Informe um elemento: ");
scanf("%d", &C[i]);
}
printf("Informe x: ");
scanf("%d", &x);
for (i = 0; i < n && C[i] != x; i++)
;
if (i < n)
printf("%d est na posio %d de C\n", x, i);
else
printf("%d no pertence ao conjunto C\n", x);
return 0;
}

Custo
c1
c2
c3
0
c4
c5
c6
c7
c8
c9
0
c10
c11
c12
0
c13
c14
c15
c16
c17
0

Vezes
1
1
1
1
1
1
1
n+1
n
n
n
1
1
ti
ti 1
1
1
1
1
1
1

O tempo de execuo do programa 2.1 dado pela soma dos tempos para cada sentena
executada. Uma sentena que gasta ci passos e executada n vezes contribui com ci n no tempo
de execuo do programa. Para computar T (n), o tempo de execuo do programa 2.1, devemos somar os produtos das colunas Custo e Vezes , obtendo:
T (n) = c1 + c2 + c3 + c4 + c5 + c6 + c7 (n + 1) + c8 n + c9 n+
c10 + c11 + c12 ti + c13 + c14 + c15 + c16 + c17 .
Observe que, mesmo para entradas de um mesmo tamanho, o tempo de execuo de um
programa pode depender de qual entrada desse tamanho fornecida. Por exemplo, no programa 2.1, o melhor caso ocorre se o elemento x encontra-se na primeira posio do vetor C.
Assim, ti = 1 e o tempo de execuo do melhor caso dado por:
T (n) = c1 + c2 + c3 + c4 + c5 + c6 + c7 (n + 1) + c8 n + c9 n+
c10 + c11 + c12 + c13 + c14 + c15 + c16 + c17
= (c7 + c8 + c9 )n+
(c1 + c2 + c3 + c4 + c5 + c6 + c7 + c10 + c11 + c12 + c13 + c14 + c15 + c16 + c17 ) .
Esse tempo de execuo pode ser expresso como uma funo linear an + b para constantes
a e b, que dependem dos custos ci das sentenas do programa. Assim, o tempo de execuo
dado por uma funo linear em n. No entanto, observe que as constantes c7 , c8 e c9 que
multiplicam n na frmula de T (n) so aquelas que tratam somente da entrada de dados. Evidentemente que para armazenar n nmeros inteiros em um vetor devemos gastar tempo an,
para alguma constante positiva a. Dessa forma, se consideramos apenas a constante c12 na frmula, que trata propriamente da busca, o tempo de execuo de melhor caso, quando ti = 1,
FACOM

UFMS

2.2 A NLISE

DE ALGORITMOS E PROGRAMAS

13

dado por:
T (n) = c12 ti = c12 .
Por outro lado, se o elemento x no se encontra no conjunto C, temos ento o pior caso do
programa. Alm de comparar i com n, comparamos tambm o elemento x com o elemento C[i]
para cada i, 0 6 i 6 n 1. Uma ltima comparao ainda realizada quando i atinge o valor
n. Assim, ti = n + 1 e o tempo de execuo de pior caso dado por:
T (n) = c12 ti = c12 (n + 1) = c12 n + c12 .
Esse tempo de execuo de pior caso pode ser expresso como uma funo linear an + b para
constantes a e b que dependem somente da constante c12 , responsvel pelo trecho do programa
que realiza o processamento.
Na anlise do programa 2.1, estabelecemos os tempos de execuo do melhor caso, quando
encontramos o elemento procurado logo na primeira posio do vetor que representa o conjunto, e do pior caso, quando no encontramos o elemento no vetor. No entanto, estamos em
geral interessados no tempo de execuo de pior caso de um programa, isto , o maior tempo
de execuo para qualquer entrada de tamanho n.
Como o tempo de execuo de pior caso de um programa um limitante superior para seu
tempo de execuo para qualquer entrada, temos ento uma garantia que o programa nunca
vai gastar mais tempo que esse estabelecido. Alm disso, o pior caso ocorre muito freqentemente nos programas em geral, como no caso do problema da busca.

2.2.1 Ordem de crescimento de funes matemticas


Acabamos de usar algumas convenes que simplificam a anlise do programa 2.1. A primeira abstrao que fizemos foi ignorar o custo real de uma sentena do programa, usando as
constantes ci para representar esses custos. Depois, observamos que mesmo essas constantes
nos do mais detalhes do que realmente precisamos: o tempo de execuo de pior caso do
programa 2.1 an + b, para constantes a e b que dependem dos custos ci das sentenas. Dessa
forma, ignoramos no apenas o custo real das sentenas mas tambm os custos abstratos ci .
Na direo de realizar mais uma simplificao, estamos interessados na taxa de crescimento, ou ordem de crescimento, da funo que descreve o tempo de execuo de um algoritmo ou programa. Portanto, consideramos apenas o maior termo da frmula, como por
exemplo an, j que os termos menores so relativamente insignificantes quando n um nmero
grande. Tambm ignoramos o coeficiente constante do maior termo, j que fatores constantes
so menos significativos que a taxa de crescimento no clculo da eficincia computacional para
entradas grandes. Dessa forma, dizemos que o programa 2.1, por exemplo, tem tempo de
execuo de pior caso O(n).
Usualmente, consideramos um programa mais eficiente que outro se seu tempo de execuo de pior caso tem ordem de crescimento menor. Essa avaliao pode ser errnea para
pequenas entradas mas, para entradas suficientemente grandes, um programa que tem tempo
de execuo de pior caso O(n) executar mais rapidamente no pior caso que um programa que
tem tempo de execuo de pior caso O(n2 ).
Quando olhamos para entradas cujos tamanhos so grandes o suficiente para fazer com que
somente a taxa de crescimento da funo que descreve o tempo de execuo de um programa
FACOM

UFMS

2.2 A NLISE

14

DE ALGORITMOS E PROGRAMAS

seja relevante, estamos estudando na verdade a eficincia assinttica de um algoritmo ou programa. Isto , concentramo-nos em saber como o tempo de execuo de um programa cresce
com o tamanho da entrada no limite, quando o tamanho da entrada cresce ilimitadamente.
Usualmente, um programa que assintoticamente mais eficiente ser a melhor escolha para
todas as entradas, excluindo talvez algumas entradas pequenas.
As notaes que usamos para descrever o tempo de execuo assinttico de um programa
so definidas em termos de funes matemticas cujos domnios so o conjunto dos nmeros
naturais N = {0, 1, 2, . . .}. Essas notaes so convenientes para descrever o tempo de execuo
de pior caso T (n) que usualmente definido sobre entradas de tamanhos inteiros.
No incio desta seo estabelecemos que o tempo de execuo de pior caso do programa 2.1
T (n) = O(n). Vamos definir formalmente o que essa notao significa. Para uma dada funo
g(n), denotamos por O(g(n)) o conjunto de funes
O(g(n)) = {f (n) : existem constantes positivas c e n0 tais que
0 6 f (n) 6 cg(n) para todo n > n0 } .

A funo f (n) pertence ao conjunto O(g(n)) se existe uma constante positiva c tal que f (n)
no seja maior que cg(n), para n suficientemente grande. Dessa forma, usamos a notao
O para fornecer um limitante assinttico superior sobre uma funo, dentro de um fator constante. Apesar de O(g(n)) ser um conjunto, escrevemos f (n) = O(g(n)) para indicar que f (n)
um elemento de O(g(n)), isto , que f (n) O(g(n)).

A figura 2.1 mostra a intuio por trs da notao O. Para todos os valores de n direita de
n0 , o valor da funo f (n) est sobre ou abaixo do valor da funo g(n).

cg(n)

f (n)

n
n0
Figura 2.1: f (n) = O(g(n)).
Dessa forma, podemos dizer, por exemplo, que 4n + 1 = O(n). Isso porque existem constantes positivas c e n0 tais que
4n + 1 6 cn

FACOM

UFMS

2.3 A NLISE

DA ORDENAO POR TROCAS SUCESSIVAS

15

para todo n > n0 . Tomando, por exemplo, c = 5 temos


4n + 1 6 5n
16n,
ou seja, para n0 = 1, a desigualdade 4n + 1 6 5n satisfeita para todo n > n0 . Certamente,
existem outras escolhas para as constantes c e n0 , mas o mais importante que existe alguma
escolha. Observe que as constantes dependem da funo 4n + 1. Uma funo diferente que
pertence a O(n) provavelmente necessita de outras constantes.
A definio de O(g(n)) requer que toda funo pertencente a O(g(n)) seja assintoticamente
no-negativa, isto , que f (n) seja no-negativa sempre que n seja suficientemente grande.
Conseqentemente, a prpria funo g(n) deve ser assintoticamente no-negativa, caso contrrio o conjunto O(g(n)) vazio. Portanto, vamos considerar que toda funo usada na notao
O assintoticamente no-negativa.
A ordem de crescimento do tempo de execuo de um programa ou algoritmo pode ser
denotada atravs de outras notaes assintticas, tais como as notaes , , o e . Essas
notaes so especficas para anlise do tempo de execuo de um programa atravs de outros
pontos de vista. Nesta aula, ficaremos restritos apenas notao O. Em uma disciplina mais
avanada, como Anlise de Algoritmos, esse estudo se aprofunda e ateno especial dada a
este assunto.

2.3 Anlise da ordenao por trocas sucessivas


Vamos fazer a anlise agora no de um programa, mas de uma funo que j conhecemos
bem e que soluciona o problema da ordenao. A funo trocas_sucessivas faz a ordenao de um vetor v de n nmeros inteiros fornecidos como parmetros usando o mtodo das
trocas sucessivas ou o mtodo da bolha.
/* Recebe um nmero inteiro n > 0 e um vetor v com n nmeros inteiros e rearranja o vetor v em ordem crescente de seus elementos */
void trocas_sucessivas(int n, int v[MAX])
{
int i, j, aux;
for (i = n-1; i > 0; i--)
for (j = 0; j < i; j++)
if (v[j] > v[j+1]) {
aux = v[j];
v[j] = v[j+1];
v[j+1] = aux;
}
}

Conforme j fizemos antes, a anlise linha a linha da funo trocas_sucessivas descrita abaixo.

FACOM

UFMS

2.3 A NLISE

16

DA ORDENAO POR TROCAS SUCESSIVAS

void trocas_sucessivas(int n, int v[MAX]


{
int i, j, aux;
for (i = n-1; i > 0; i--)
for (j = 0; j < i; j++)
if (v[j] > v[j+1]) {
aux = v[j];
v[j] = v[j+1];
v[j+1] = aux;
}
}

Custo
c1
0
c2
c3
c4
c5
c6
c7
c8
0
0

Vezes
1
1
1
n
Pn1
(i + 1)
i=1
Pn1
i=1 i
Pn1
i=1 ti
Pn1
i=1 ti
Pn1
ti
Pi=1
n1
i=1 i
1

Podemos ir um passo adiante na simplificao da anlise de um algoritmo ou programa se


consideramos que cada linha tem custo de processamento 1. Na prtica, isso no bem verdade
j que h sentenas mais custosas que outras. Por exemplo, o custo para executar uma sentena
que contm a multiplicao de dois nmeros de ponto flutuante de preciso dupla maior que
o custo de comparar dois nmeros inteiros. No entanto, ainda assim vamos considerar que o
custo para processar qualquer linha de um programa constante e, mais ainda, que tem custo
1. Dessa forma, a coluna com rtulo Vezes nas anlises acima representam ento o custo de
execuo de cada linha do programa.
O melhor caso para a funo trocas_sucessivas ocorre quando a seqncia de entrada
com n nmeros inteiros fornecida em ordem crescente. Observe que, nesse caso, uma troca
nunca ocorrer. Ou seja, ti = 0 para todo i. Ento, o tempo de execuo no melhor caso dado
pela seguinte expresso:
T (n) = n +

n1
X

n1
X

i=1
n1
X

i=1

(i + 1) +

=n+2

=n+2

i=1
n1
X
i=1

i+

n1
X

i+

n1
X

i+

n1
X

1+3

i=1
n1
X

1+3

i=1
n1
X

i=1

i=1

ti +

n1
X
i=1

ti +

n1
X

ti

i=1

ti
0

i=1

n(n 1)
+n1
2
= n2 + n 1 .

=n+2

Ento, sabemos que o tempo de execuo da funo trocas_sucessivas dado pela expresso T (n) = n2 + n 1. Para mostrar que T (n) = O(n2 ) devemos encontrar duas constantes
positivas c e n0 e mostrar que
n2 + n 1 6 cn2 ,

para todo n > n0 . Ento, escolhendo c = 2 temos:

n2 + n 1 6 2n2
n 1 6 n2

FACOM

UFMS

2.3 A NLISE

17

DA ORDENAO POR TROCAS SUCESSIVAS

ou seja,
n2 n + 1 > 0 .

Observe ento que a inequao n2 n + 1 > 0 sempre vlida para todo n > 1. Assim,
escolhendo c = 2 e n0 = 1, temos que
n2 + n 1 6 cn2
para todo n > n0 , onde c = 2 e n0 = 1. Portanto, T (n) = O(n2 ), ou seja, o tempo de execuo
do melhor caso da funo trocas_sucessivas quadrtico no tamanho da entrada.
Para definir a entrada que determina o pior caso para a funo trocas_sucessivas devemos notar que quando o vetor contm os n elementos em ordem decrescente, o maior nmero
possvel de trocas realizado. Assim, ti = i para todo i e o tempo de execuo de pior caso
dado pela seguinte expresso:
T (n) = n +

n1
X

n1
X

=n+

i=1
n1
X

i=1
n1
X

i=1
n1
X

i=1

(i + 1) +
(i + 1) +

=n+5

i=1

i+

n1
X

i+3

n1
X

ti

i+3

i=1
n1
X

i=1

i=1

n(n 1)
=n+5
+n1
2
5
5
= n2 n + 2n 1
2
2
5 2 1
= n n1.
2
2
Agora, para mostrar que o tempo de execuo de pior caso T (n) = O(n2 ), escolhemos
c = 5/2 e temos ento que
5 2 1
5
n n 1 6 n2
2
2
2
1
n160
2
ou seja,

1
n+1 > 0
2
e, assim, a inequao (1/2)n + 1 > 0 para todo n > 1. Logo, escolhendo c = 5/2 e n0 = 1 temos
que
5 2 1
n n 1 6 cn2
2
2
para todo n > n0 , onde c = 5/2 e n0 = 1. Assim, T (n) = O(n2 ), ou seja, o tempo de execuo do
pior caso da funo trocas_sucessivas quadrtico no tamanho da entrada. Note tambm
que ambos os tempos de execuo de melhor e de pior caso da funo trocas_sucessivas
tm o mesmo desempenho assinttico.
FACOM

UFMS

2.4 M ORAL

DA HISTRIA

18

2.4 Moral da histria


Esta seo basicamente uma cpia traduzida da seo correspondente do livro de Cormen
et. al [1] e descreve um breve resumo a moral da histria sobre eficincia de algortimos e
programas.
Um bom algoritmo ou programa como uma faca afiada: faz o que suposto fazer com a
menor quantidade de esforo aplicada. Usar um programa errado para resolver um problema
como tentar cortar um bife com uma chave de fenda: podemos eventualmente obter um
resultado digervel, mas gastaremos muito mais energia que o necessrio e o resultado no
dever ser muito agradvel esteticamente.
Programas alternativos projetados para resolver um mesmo problema em geral diferem
dramaticamente em eficincia. Essas diferenas podem ser muito mais significativas que a diferena de tempos de execuo em um supercomputador e em um computador pessoal. Como
um exemplo, suponha que temos um supercomputador executando o programa que implementa o mtodo da bolha de ordenao, com tempo de execuo de pior caso O(n2 ), contra um
pequeno computador pessoal executando o mtodo da intercalao. Esse ltimo mtodo de
ordenao tem tempo de execuo de pior caso O(n log n) para qualquer entrada de tamanho
n e ser visto na aula 5. Suponha que cada um desses programas deve ordenar um vetor de
um milho de nmeros. Suponha tambm que o supercomputador capaz de executar 100
milhes de operaes por segundo enquanto que o computador pessoal capaz de executar
apenas um milho de operaes por segundo. Para tornar a diferena ainda mais dramtica,
suponha que o mais habilidoso dos programadores do mundo codificou o mtodo da bolha na
linguagem de mquina do supercomputador e o programa usa 2n2 operaes para ordenar n
nmeros inteiros. Por outro lado, o mtodo da intercalao foi programado por um programador mediano usando uma linguagem de programao de alto nvel com um compilador
ineficiente e o cdigo resultante gasta 50n log n operaes para ordenar os n nmeros. Assim,
para ordenar um milho de nmeros o supercomputador gasta
2 (106 )2 operaes
= 20.000 segundos 5,56 horas,
108 operaes/segundo
enquanto que o computador pessoal gasta
50 106 log 106 operaes
1.000 segundos 16,67 minutos.
106 operaes/segundo
Usando um programa cujo tempo de execuo tem menor taxa de crescimento, mesmo com
um compilador pior, o computador pessoal 20 vezes mais rpido que o supercomputador!
Esse exemplo mostra que os algoritmos e os programas, assim como os computadores, so
uma tecnologia. O desempenho total do sistema depende da escolha de algoritmos e programas eficientes tanto quanto da escolha de computadores rpidos. Assim como rpidos avanos
esto sendo feitos em outras tecnologias computacionais, eles esto sendo feitos em algoritmos
e programas tambm.

FACOM

UFMS

2.4 M ORAL

19

DA HISTRIA

Exerccios
2.1 Qual o menor valor de n tal que um programa com tempo de execuo 100n2 mais
rpido que um programa cujo tempo de execuo 2n , supondo que os programas foram
implementados no mesmo computador?
2.2 Suponha que estamos comparando as implementaes dos mtodos de ordenao por
trocas sucessivas e por intercalao em um mesmo computador. Para entradas de tamanho n, o mtodo das trocas sucessivas gasta 8n2 passos enquanto que o mtodo da intercalao gasta 64n log n passos. Para quais valores de n o mtodo das trocas sucessivas
melhor que o mtodo da intercalao?
2.3 Expresse a funo n3 /1000 100n2 100n + 3 na notao O.
2.4 Para cada funo f (n) e tempo t na tabela abaixo determine o maior tamanho n de um
problema que pode ser resolvido em tempo t, considerando que o programa soluciona o
problema em f (n) microssegundos.
1
segundo

1
minuto

1
hora

1
dia

1
ms

1
ano

1
sculo

log n

n
n
n log n
n2
n3
2n
n!
2.5 verdade que 2n+1 = O(2n )? E verdade que 22n = O(2n )?
2.6 Suponha que voc tenha algoritmos com os cinco tempos de execuo listados abaixo.
Quo mais lento cada um dos algoritmos fica quando voc (i) duplica o tamanho da
entrada, ou (ii) incrementa em uma unidade o tamanho da entrada?
(a) n2
(b) n3
(c) 100n2
(d) n log2 n
(e) 2n
2.7 Suponha que voc tenha algoritmos com os seis tempos de execuo listados abaixo. Suponha que voc tenha um computador capaz de executar 1010 operaes por segundo
e voc precisa computar um resultado em no mximo uma hora de computao. Para
cada um dos algoritmos, qual o maior tamanho da entrada n para o qual voc poderia
receber um resultado em uma hora?
(a) n2
FACOM

UFMS

2.4 M ORAL

20

DA HISTRIA

(b) n3
(c) 100n2
(d) n log2 n
(e) 2n
(f) 22

2.8 Rearranje a seguinte lista de funes em ordem crescente de taxa de crescimento. Isto ,
se a funo g(n) sucede imediatamente a funo f (n) na sua lista, ento verdade que
f (n) = O(g(n)).
f1 (n) = n2.5

f2 (n) = 2n
f3 (n) = n + 10
f4 (n) = 10n
f5 (n) = 100n
f6 (n) = n2 log2 n
2.9 Considere o problema de computar o valor de um polinmio em um
ponto. Dados n
Pn1
coeficientes a0 , a1 , . . . , an1 e um nmero real x, queremos computar i=0
ai xi .
(a) Escreva um programa simples com tempo de execuo de pior caso O(n2 ) para solucionar este problema.
(b) Escreva um programa com tempo de execuo de pior caso O(n) para solucionar
este problema usando o mtodo chamado de regra de Horner para reescrever o polinmio:
n1
X
ai xi = ( (an1 x + an2 )x + + a1 )x + a0 .
i=1

2.10 Seja A[0..n 1] um vetor de n nmeros inteiros distintos dois a dois. Se i < j e A[i] > A[j]
ento o par (i, j) chamado uma inverso de A.
(a) Liste as cinco inverses do vetor A = h2, 3, 8, 6, 1i.

(b) Qual vetor com elementos no conjunto {1, 2, . . . , n} tem a maior quantidade de inverses? Quantas so?
(c) Escreva um programa que determine o nmero de inverses em qualquer permutao de n elementos em tempo de execuo de pior caso O(n log n).

FACOM

UFMS