OBSERVAÇÕES: 1. Esta lista de exercícios poderá ser resolvida individualmente ou em grupos de 2 pessoas. 2. A lista possui 25 exercícios, destes você deve responder os 5 primeiros exercícios e os outros 10 podem ser escolhidos livremente entre os exercícios de número 6 ao 25. 3. Caso você ache que falta algum detalhe nas especificações, você deverá fazer as suposições que julgar necessárias e escrevê-las com as suas respostas. Pode acontecer também de algum enunciado conter dados e/ou especificações supérfluas para a solução de alguma pergunta específica. Utilize sua capacidade de julgamento para separar o supérfluo do necessário. 4. A data final para entrega desta lista de exercícios é o dia 11/07/2013, no início da aula. 5. A solução dessa lista de exercícios deverá ser manuscrita e não digital. 6. Listas plagiadas serão desconsideradas, sendo atribuída nota 0 (zero) a todos os envolvidos. 7. O valor dessa lista de exercícios é 2 pontos. EXERCÍCIOS 1) Para cada uma das afirmações abaixo, justifique formalmente (usando definições, manipulações algébricas e implicações) se for verdade ou dê um contraexemplo se for falso. a) 2 n + 1 = O (2 n ) b) 2 2n = O (2 n ) c) Se f(n) = O (u(n)) e g(n) = O (v(n)), então f(n) - g(n) = O (u(n)) - O (v(n)) d) Se f(n) = O (g(n)) e g(n) = O (h(n)), então f(n) = O (h(n)) e) Se f(n) = O (h(n)) e g(n) = O (h(n)), então f(n) = g(n) As questões das letras a, b, c foram retiradas do livro do Nívio Ziviani [ZIV]. 2) Demonstre as seguintes propriedades da notação Big O. a) f(n) = O (f(n)) b) c * O (f(n)) = O (f(n)), onde c é uma constante c) O (f(n)) + O (f(n)) = O (f(n)) d) O (f(n)) * O (g(n)) = O (f(n) * g(n)) e) f (n) * O(g(n)) = O (f(n) * g(n)) 3) Analise a complexidade dos códigos abaixo. Para cada código calcule: 1. a quantidade total de operações executadas 2. identifique a operação elementar/básica. Justifique sua escolha.
3. estabeleça uma soma que indique quantas vezes a operação elementar/básica foi executada. Considere o pior caso. 4. defina uma função de complexidade e expresse sua ordem de complexidade. Justifique sua resposta. a) soma <- 0; para j de 1 ate n faça soma <- soma + 1; b) soma1 <- 0; para j de 1 ate i faça soma1 <- soma1 + 1; c) soma2 <- 0; para j de 1 até n faça para i de 1 ate j faça soma2 <- soma2 + 1; d) para i de 1 até n-1 faça para j de i+1 ate n faça para k de 1 ate j faça alguma instrução executa com complexidade O(1) e) x <- 0; para j de 1 até i faça para k de 1 até j faça x <- x + 1; 4) [CLRS- Exercício 2.2-4] Como podemos modificar praticamente qualquer algoritmo para ter um bom tempo de execução no melhor caso? Você acha que analisar um algoritmo pelo seu melhor caso é uma boa escolha? Justifique sua resposta. 5) [CLRS- Exercício 3.1-3] Explique por que a afirmação: O consumo de tempo do algoritmo A é pelo menos O(n²) não faz sentido.
6) Suponha que estamos estudando o desempenho de um algoritmo em função do tamanho n das instâncias de um problema. Considere as seguintes afirmações: 1. o consumo de tempo do algoritmo é O(n²) no pior caso; 2. o consumo de tempo do algoritmo é O(n²) para toda instância do problema. Qual a diferença entre as afirmações 1 e 2? 7) [CLRS- Exercício 1.2-3] Qual é o menor valor de n tal que um algoritmo A cujo tempo de execução é 100 n² é mais rápido que um algoritmo B com tempo de execução igual a 2 n numa mesma máquina? 8) Suponha um algoritmo com complexidade O(n*lg n) para todas as instâncias do problema. Considere que para N = 10.000.000, o tempo necessário para executar o programa equivalente a este algoritmo é de 8 segundos. Assuma que exista memória suficiente para executá-lo quando N = 1.000.000.000. Qual o tempo de execução desse programa para N = 1.000.000.000? Dê sua resposta em segundos e em horas. Obs: lg representa o logaritmo na base 2. 9) Suponha que um processador possa executar 10 15 operações por segundo. Assuma a existência de dois algoritmos, denominado A e B, para testar se um número é primo. O algoritmo A executa 100*n 2 operações para testar se um número de n dígitos decimais é primo. O algoritmo B executa 2 n operações para testar se um número de n dígitos decimais é primo. Usando o algoritmo A, quanto tempo, em segundos, esse processador gastará para determinar se um número de 1.000 dígitos decimais é primo? Usando o algoritmo B, quanto tempo, em segundos, esse processador gastará para determinar se um número de 1.000 dígitos decimais é primo? 10) [ZIV- Exercício 1.5] Qual algoritmo você prefere: um algoritmo que requer n 5 passos ou um que requer 2 n passos. Justifique sua resposta. 11) [ZIV- Exercício 1.2] O que significa dizer que g(n) é O (f(n)). 12) Uma métrica para avaliar algoritmos é a métrica empírica. Ela consiste em escolher um critério de análise e um conjunto de entradas variadas. Após tais decisões implementa-se o algoritmo numa linguagem de programação. Finalmente executa-se o programa com as entradas e faz-se uma análise dos resultados. Esse procedimento pode ser utilizado para comparar dois algoritmos ou mais programas. Critique essa métrica. 13) Por muitas vezes damos atenção apenas à análise do pior caso dos algoritmos. Explique o porquê. 14) Um algoritmo A com tempo de execução O(n*lg n), onde n é o tamanho da sequencia de entrada, é sempre mais rápido que um algoritmo B com tempo de execução O(n²)?
15) Faça um algoritmo que verifique se os elementos de um vetor estão ordenados de forma ascendente. Qual a complexidade de pior, melhor e caso médio do seu algoritmo? 16) Considere um algoritmo para percorrer uma lista não ordenada para encontrar um número inteiro. a) Qual é o melhor caso desse algoritmo? b) Qual é o pior caso desse algoritmo? c) O que deve ser levado em conta no cálculo do caso médio? d) Os cálculos realizadas nas alternativas a, b, c seriam diferentes se o número procurado não estivesse presente na lista? Justifique sua resposta. 17) Considere o problema de percorrer um vetor não ordenado para encontrar um determinado elemento. Calcule a complexidade assintótica do caso médio nas seguintes condições: a) o elemento procurado encontra-se no vetor e a probabilidade de encontrá-lo em quaisquer posição do vetor é a mesma e igual 1/n; b) o elemento procurado encontra-se no vetor e a probabilidade de encontrá-lo na primeira posição do vetor é ½, a probabilidade de encontrá-lo na segunda posição é ¼ e a probabilidade de encontrá-lo em quaisquer das outras posições é a mesma e igual a 1/(4n-8); c) o elemento procurado encontra-se no vetor em 50% das vezes e a probabilidade de encontrá-lo em quaisquer posições vetor é a mesma e igual 1/n; 18) [ZIV- Exercício 1.1] Dê o conceito de: a) algoritmo; b) tipos de dados; c) tipo abstrato de dados; 19) Conceitue estrutura de dados. 20) [ZIV- Exercício 1.3] O que significa dizer que um algoritmo executa em tempo proporcional a n? 21) [ZIV- Exercício 1.4] Explique a diferença entre O(1) e O(2). 22) [ZIV- Exercício 1.6] Prove que 1 2 + 2 2 + 3 2 + + n 2 = n 3 /3 + O(n 2 ). 23) [CLRS- Exercício 1.1-2] Além da velocidade, que outras medidas de eficiência poderiam ser usadas em uma configuração real? 24) [CLRS- Exercício 1.1-3] Selecione uma estrutura de dados que você já tenha visto e discuta seus pontos fortes e suas limitações.
25) Considere que existam dois algoritmos, denominados A e B, para resolver um determinado problema. O algoritmo A exige 10 8 *n operações e o algoritmo B exige 10*n 2. a) Calcule a complexidade assintótica de cada um desses algoritmos b) Pode-se afirmar que o algoritmo A é sempre melhor que o algoritmo B? c) Que conclusões este exemplo lhe permite tirar a respeito do uso da complexidade assintótica e da notação Big O na análise da complexidade de algoritmos. Bibliografia: [ZIV] ZIVIANI, Nivio. Projeto de Algoritmos Com implementação em Pascal e C. 3. ed. Revisada e Ampliada. São Paulo: Cengage Learning, 2011. [CLRS] CORMEN, T. et al. Algoritmos: Teoria e Prática. Editora Campus, 2002.