• Nenhum resultado encontrado

Complexidade exponencial O(c n )

No documento Apostila de Programação Estatística (páginas 80-86)

9.3 Exemplos B´ asicos de Complexidade

9.3.7 Complexidade exponencial O(c n )

Um t´ıpico exemplo da complexidade exponencial ´e o c´alculo do n elemento da s´erie de Fibonacci a partir do algoritmo recursivo. Tamb´em temos a torre de hanoi. Em geral um algoritmo recursivo que depende de n que faz duas chamas recursiva simplificando para n − 1 ou n − 2 ´e de complexidade exponencial. Repare que a ordena¸c˜ao r´apida n˜ao ´e, apesar de ter duas chamas recursivas cada uma delas foi diminu´ıda de forma que a soma das duas ainda ´e menor que n.

Complexidade de Algoritmos

Exerc´ıcios - 9ª Semana

9.1 Considere os algoritmos a seguir. Para cada um deles encontre a sua ordem de complexidade. Justifique a sua resposta. Se quiser, implemente os algoritmos para facilitar a sua an´alise.

a) Algoritmo n˜ao recursivo que retorna a soma dos elementos de um vetor de tamanho n passado como entrada.

b) Algoritmo recursivo que retorna a soma dos elementos de um vetor de tamanho n passado como entrada.

c) Algoritmo n˜ao recursivo que retorna a soma dos elementos de uma matriz de tamanho n × n passada como entrada.

d) Algoritmo n˜ao recursivo que busca a posi¸c˜ao de um elementos passado como en- trada em uma matriz de tamanho n × n tamb´em passada como entrada.

e) Algoritmo n˜ao recursivo que fornece o produto interno entre dois vetores de ta- manho n passados como entrada.

f) Algoritmo n˜ao recursivo que fornece o produto entre uma matriz de tamanho n×n e um vetor de tamanho n passados como entrada.

g) Algoritmo n˜ao recursivo que verifica se uma matriz de tamanho n × n passada como entrada ´e sim´etrica ou n˜ao.

h) Algoritmo recursivo que retorna todas as permuta¸c˜oes de um array de tamanho n passado como entrada (ex. 7.12)

9.2 Considere os dois pseudo-c´odigos a seguir. Ambos recebem como entrada um n´umero natural n e retorna o n-´esimo termo da sequˆencia xn = 2xn−1+ n, com x0 = 1.

Entrada: n Sa´ıda: xn Nome: Seq1 Se n = 0, retorne 1; Retorne 2×Seq1(n − 1) + n Entrada: n Sa´ıda: xn Nome: Seq2 Se n = 0, retorne 1;

Retorne Seq2(n − 1)+Seq2(n − 1) + n

(a) Implemente cada um dos pseudo-c´odigos acima no R.

(b) Teste as duas implementa¸c˜oes para n = 15. Percebeu alguma diferen¸ca no tempo de execu¸c˜ao?

(c) Vamos agora fazer um gr´afico dos tempos de execu¸c˜ao em fun¸c˜ao do valor de entrada em cada fun¸c˜ao. Para isso use os comandos plot e Sys.time(), este ´

ultimo retorna o instante de tempo em que o comando foi chamada. Analise os gr´aficos gerados e deduza a ordem de complexidade de cada uma das implemen- ta¸c˜oes.

OBS: Veja uma sugest˜ao de c´odigo para o gr´afico no final desta lista.

(d) O que tem de diferente nas duas implementa¸c˜oes para uma ser t˜ao mais demorada que a outra?

9.3 Fibonacci com Recurs˜ao:

Complexidade de Algoritmos

(a) Refa¸ca a fun¸c˜ao que retorna o n-´esimo elemento da sequˆencia de Fibonacci usando recurs˜ao.

(b) Verifique o tempo de execu¸c˜ao para n = 1, 2, . . . , 30, ou seja, o tempo que a fun¸c˜ao demora para rodar. Para isso crie um vetor de tamanho 30 que guarda o tempo de execu¸c˜ao para cada n = 1, 2, . . . , 30. Para isso use o comando Sys.time() sugerido anteriormente.

(c) Fa¸ca um gr´afico de n versus o tempo de execu¸c˜ao.

(d) Analisando o gr´afico, o que vocˆe diria da ordem desse algoritmo?

(e) Esse algoritmo ´e de ordem O(2n). Essa informa¸c˜ao est´a de acordo com o gr´afico? (f) Veja que para n um pouco maior que 30 j´a demora muito para rodar.

OBS: Se fizermos as contas podemos ver que para n = 100 o algoritmo j´a fica im- poss´ıvel de rodar. Considerando que uma opera¸c˜ao leva um picosegundo (1 × 10−12 segundos), 2100 opera¸c˜oes levam 2100× 10−12 s = 30.000.000.000.000 anos!!!

9.4 Fibonacci sem Recurs˜ao:

(a) Implemente o passo-a-passo a seguir e verifique que ele fornece o n-´esimo termo da sequˆencia de Fibonacci sem usar recurs˜ao.

Se n = 1 ou n = 2 retorne 1. 1 Defina penultimo = 1; 2 Defina ultimo = 1; 3 Inicie i = 3; 4

Defina atual = ultimo + penultimo;

5

Atualize penultimo = ultimo;

6

Atualize ultimo = atual;

7

Incremente i = i + 1;

8

Se i ≤ n, volte para a linha 5;

9

Retorne atual.

10

(b) Analisando o c´odigo implementado, qual a ordem desse algoritmo? (c) Como na quest˜ao anterior, gere um vetor com os tempos de execu¸c˜ao. (d) Fa¸ca um gr´afico de n versus o tempo de execu¸c˜ao.

(e) Analisando o gr´afico, o que vocˆe diria da ordem desse algoritmo?

(f) Para o gr´afico ficar mais explicativo, gere um vetor que guarda os tempos de exe- cu¸c˜ao para n = 1, 2001, 4001, 6001, ..., 40001 e em seguida fa¸ca um novo gr´afico. 9.5 Vamos agora comparar o tempo de execu¸c˜ao para o pior caso entre os dois algoritmos

de ordena¸c˜ao vistos na semana passada.

(a) Escolha um dos algoritmos j´a implementados que ordenam um vetor passado como entrada pelo m´etodo de Ordena¸c˜ao Bolha. Veja que para esse m´etodo o pior caso ´e quando o vetor est´a na ordem inversa, por exemplo (1, 2, 3, 4, 5). Ent˜ao, com base no c´odigo ao final dessa lista de exerc´ıcios, dentro do for para cada i defina um vetor v = (i, i − 1, . . . , 2, 1) e rode o m´etodo bolha nesse vetor.

Complexidade de Algoritmos

Fa¸ca ao final o gr´afico do tempo de execu¸c˜ao em fun¸c˜ao do tamanho do vetor de entrada. Em vez de subir o tamanho do vetor de entrada de um em um use um while e suba de 10 em 10.

(b) Fa¸ca o mesmo para a Ordena¸c˜ao R´apida, mas veja que nesse caso o pior caso j´a ´

e o vetor ordenado. Ent˜ao o vetor v definido dentro do for ser´a v = (1, 2, . . . , i). Fa¸ca ao final o gr´afico do tempo de execu¸c˜ao em fun¸c˜ao do tamanho do vetor de entrada.

Sugest˜ao de c´odigo para fazer o gr´afico do tempo de execu¸c˜ao de uma fun¸c˜ao f em fun¸c˜ao do argumento de entrada, supondo este inteiro.

> Temp <- NULL > for(i in 1:20){ + ta <- Sys.time()

+ f(i)

+ td <- Sys.time()

+ Temp <- c(Temp,td - ta) + }

> plot(Temp)

Parte III

Uma Introdu¸c˜ao ao C´alculo

Num´erico

Semana 10:

Aproxima¸c˜ao de Fun¸c˜oes por

S´eries de Taylor

Na terceira parte do curso ser˜ao vistos alguns m´etodos num´ericos. Nessa primeira semana vamos aprender de que forma o computador calcula fun¸c˜oes como exp(x), log(x), sin(x), entre outras. Para isso vamos estudar a aproxima¸c˜ao de fun¸c˜ao pela S´erie de Taylor.

10.1

S´erie de Taylor

Defini¸c˜ao 10.1.1 Se uma fun¸c˜ao f ´e definida em 0 e n vezes diferenci´avel em 0, isto ´

e existe f (0) e f(i)(0) para i = 1, 2, . . . , n, definimos o n-´esimo Polinˆomio de Maclaurin

para f como sendo:

pMn (x) = f (0) + f0(0)x + f 00(0)x2 2! + f000(0)x3 3! + . . . + f(n)(0)xn n! = n X i=0 f(i)(0)xi i!

Veja que o n-´esimo Polinˆomio de Maclaurin para f ´e um polinˆomio de grau n que satisfaz as seguintes propriedades:

ˆ pM

n (0) = f (0).

ˆ pM (i)

n (x)|x=0 = f(i)(x)|x=0.

ˆ pM

1 (x) ´e a aproxima¸c˜ao linear local de f em torno de x = 0; pM2 (x) ´e a aproxima¸c˜ao

quadr´atica local de f em torno de x = 0; e assim por diante. ˆ Ent˜ao para pontos x perto de 0 pM

n (x) ´e uma aproxima¸c˜ao para f (x).

ˆ Quanto mais pr´oximo x est´a de 0, melhor ´e a aproxima¸c˜ao. ˆ Quanto maior o valor de n, melhor ser´a a aproxima¸c˜ao.

O Polinˆomio de Maclaurin ´e um caso particular do Polinˆomio de Taylor quando x0 = 0.

Veja a defini¸c˜ao formal do Polinˆomio de Taylor.

Defini¸c˜ao 10.1.2 Se uma fun¸c˜ao f ´e definida em x0 e n vezes diferenci´avel em x0, isto

´

e existe f(i)(x0) para i = 1, 2, . . . , n, definimos o n-´esimo Polinˆomio de Taylor para f em

torno de x0 como sendo:

pTn(x) = f (x0) + f0(x0)(x − x0) + . . . + f(n)(x0)(x − x0)n n! = n X i=0 f(i)(x0)(x − x0)i i! 80

Aproxima¸c˜ao de Fun¸c˜oes por S´eries de Taylor

Assim como o Polinˆomio de Maclaurin, o n-´esimo Polinˆomio de Taylor para f em torno de x0 ´e um polinˆomio de grau n que satisfaz as seguintes propriedades:

ˆ pT n(x0) = f (x0). ˆ pT (i) n (x)|x=x0 = f (i)(x)| x=x0.

ˆ p1(x) ´e a aproxima¸c˜ao linear local de f em torno de x = x0; p2(x) ´e a aproxima¸c˜ao

quadr´atica local de f em torno de x = x0; e assim por diante.

ˆ Ent˜ao para pontos x perto de x0 pTn(x) ´e uma aproxima¸c˜ao para f (x).

ˆ Quanto mais pr´oximo x est´a de x0, melhor ´e a aproxima¸c˜ao.

ˆ Quanto maior o valor de n, melhor ser´a a aproxima¸c˜ao.

O que vamos fazer nessa semana ´e usar os polinˆomios acima para aproximar as fun¸c˜oes que n˜ao sabemos fazer as contas “na m˜ao”. Veja algumas aplica¸c˜oes nas se¸c˜oes a seguir.

No documento Apostila de Programação Estatística (páginas 80-86)