2ª Lista de Exercícios de Introdução à Análise de Algoritmos
-
Upload
levi-moreira -
Category
Documents
-
view
220 -
download
5
description
Transcript of 2ª Lista de Exercícios de Introdução à Análise de Algoritmos
2ª Lista de Exercícios de Introdução à Análise de AlgoritmosProf. Glauber Cintra – Entrega: 15/abr/2015
Esta lista deve ser feita por grupos de no mínimo3 e no máximo 4 alunos.1) (2 PONTOS) RESOLVA AS SEGUINTES FÓRMULAS DE RECORRÊNCIA:
a) T (n)=2T (n– 1)+n, T (1)=1
0 T (n)=2T (n– 1)+n1 2∗T (n−1)=4∗T (n−2)+2∗(n−1)2 4∗T (n−2)=8∗T (n−3)+4∗(n−2)...
(n−2) 2n−2∗T (2 )=2n−1∗T (1)+2n−2∗(2)(n−1) 2n−1∗T (1)=2n−1∗1
T(n) = ∑k=1
n
k∗2n−k=2n+1−2−n
b)T (n )=T ( n2 )+n ,T (1)=1
Suponha que n = 2k, o que após um tempo se mostrará uma boa aproximação.Podemos reescrever a fórmula como0 T (2k )=T (2k−1)+2k
1 T (2k−1)=T (2k−2)+2k−1
2 T (2k−2)=T (2k−3)+2k−2
.
.
.
k−1T (2)=T (1)+2k−(k−1)
k T (1 )=2k−k
∑j=0
k
2k− j=2k+1−1=2∗2k−1=2n−1
2) CONSIDERE O ALGORITMO BUSCABINÁRIA DESCRITO A SEGUIR:
Algoritmo buscabináriaEntrada: um número x, um vetor v em ordem crescente e as posições inicio e fimSaída: verdadeiro, se x ocorre entre as posições início e fim de v;
falso, caso contráriose (inicio > fim) devolva falso /* devolva finaliza a execução do algoritmo */meio = (inicio + fim) / 2 /* divisão inteira */se (x = v[meio]) devolva verdadeirose (x < v[meio]) devolva buscabinária(x, v, inicio, meio – 1)devolvabuscabinária(x, v, meio + 1, fim)
a) (0,5 pontos) Seja L = 2, 5, 5, 7, 8, 9, 10, 12, 15, 16, 18, 20, 21. Simule o cálculo de buscabinária(7, L, 0, 12), exibindo os parâmetros de entrada e o valor devolvido por cada chamada ao algoritmo buscabinária. Na primeira chamada do algoritmo:Parâmetros de Entrada L, x = 7, inicio = 0, fim = 12.A verificação da base da recursão (inicio>fim) é constatada como falso e a execução segue.Meio é calculado com o valor 12/2 = 6A primeira verificação do valor de x com o valor v[meio] é falsa.Observe que x é menor que v[meio] que é 10. Uma nova chamada ao algoritmo buscabinaria será efetuada.
Na segunda chamadaParâmetros de Entrada: L, x=7. Inicio = 0, Fim = 5.A verificação da base é falsa.Meio é calculado com o valor chão de 5/2 = 2A primeira verificação do valor de x com o valor v[meio] é falsa.Observe que x é maior que v[meio] que é 5. Uma nova chamada ao algoritmo buscabinária será feita.
Na terceira chamada.Parâmetros de Entrada: L, x=7. Inicio = 3, Fim = 5.A verificação da base é falsa.Meio é calculado com o valor chão de 8/2 = 4A primeira verificação do valor de x com o valor v[meio] é falsa.Observe que x é menor que v[meio] que é 8. Uma nova chamada ao algoritmo buscabinária será feita.
Na quarta chamadaParâmetros de Entrada: L, x=7, Inicio=3, Fim=3A verificação da base é falsaMeio é calculado como sendo 3.A primeira verificação do valor de x com o valor v[meio] é verdadeira, retorna verdadeiro.
b) (1 ponto) Determine a complexidade temporal e espacial do algoritmo buscabinária(mostre os cálculos realizados para determinar tais complexidades). O algoritmo buscabinária é eficiente?
É necessário encontrar a relação de recorrência associada à busca binária. Podemos observar que o algoritmo executa uma série de instruções constantes até o momento em que a recursão ocorre.No caso em que a recursão não ocorre, quando inicio>fim, o algoritmo executa apenas instruções de tempo constante, então a base da recursão será T(1) = c,, pois o tempo para executar o algoritmo em um array de 1 elemento é constante . Em outros casos a recorrência chamará “a si mesma” sobre uma das metades do vetor. Como estamos tratando de termos assintóticos, o vetor L pode ter
muitas posições e podemos pensar que o vetor é dividido na metade para as outras iterações: n2
Assim o algoritmo iria realizar aproximadamente o seguinte número de operações:
T(n) = T(n2
) + c
Suponha que n = 2k
Utilizado o método da substituição:
0 T(2k−0) = T(2k−1) + c1 T(2k−1) = T(2k−2) + c2 T(2k−3) = T(2k−4) + c3 T(2k−4) = T(2k−5) + c.
.
.k T(2k−k ¿= C
Isso indica que T(n) = c* (k+1)Para acharmos o valor de k utilizamos o fato de que:
n=2k logo k=log2n
Isso nos indica que Logo T(n) = c* (log2(n)+1) o que simplifica para uma complexidade temporal de Ɵ(log (n)).
A complexidade temporal do algoritmo Ɵ(log (n)) não é polinomial no tamanho da entrada (n), logo o algoritmo não é eficiente.
c) (1 ponto) Prove que o algoritmo é correto.
Suponhamos que x não está no vetor. A cada chamada recursiva o valor de inicio será incrementado recursivamente (pois para a nova chamada o novo inicio será meio+1) ou o valor de fim será decrementado recursivamente (pois para a nova chamada recursiva será passado como novo valor de fim, meio -1). Chegará um momento em que os valores passados a próxima chamada recursiva serão tais que inicio>fim o que perfaz a primeira condição de parada do algoritmo. O algoritmo retornará o desejado.
Para o caso de x está no vetor.Provemos por indução forte em n, onde n é o tamanho do vetor.Observe que o tamanho do vetor passado para cada chamada se torna menor a cada chamada recursiva do algoritmo.
Seja P(n) a afirmação que o algoritmo funciona para um vetor de tamanho n = Fim-Inicio+1
O caso base da indução é quando n = 0, isso indica que Inicio = Fim+1, ou seja, Inicio>Fim. O algoritmo retornará falso.
Passo indutivo: Para n>0Assumamos primeiramente que o algoritmo retorna a resposta certa para qualquer k entre 0 e n-1. Ou seja k = Fim’ – Inicio’+1
O algoritmo computa primeiro o valor de meio que é a divisão inteira de (Inicio+Fim)/2. Por conta disso, sabemos que inicio<= meio<=fim.
Se x = v[meio], o algoritmo retornará o valor correto.
Se x<v[meio], x está no subvetor v[inicio...meio-1]. Dessa forma k = meio – inicio’, nós sabemos pela hipótese indutiva que o algoritmo funciona, pois 0<=meio-inicio<=n.
Se x>v[meio], x está no subvetorv[meio+1...fim]. Dessa forma k = fim’ – meio, nós sabemos pela hipótese indutiva que o algoritmo funciona, pois 0<=fim’ – meio<=n.
3) (2 pontos) Escreva um algoritmo recursivo que receba um número a e um número natural b e devolva ab. Prove que seu algoritmo é correto e determine a complexidade temporal e espacial do algoritmo. Você ganhará um bônus de 0,5 pontos se o seu algoritmo for eficiente.
Algoritmo PotenciaEntrada: Dois números naturais a e bSaída: ab
Se b = 0Devolva 1
Se não
aux = Potencia(a, ⌊b2⌋ )
Se b for parDevolva aux*aux
Se nãoDevolva aux*aux*a
PROVAProvemos por indução:
Sabemos que ab = ab2∗a
b2 , se bé par
¿a∗ab−1
2 ∗ab−1
2 , se bé ímpar
Para o caso de b = 0, é claro que abdevolve 1, pois ele entra diretamente na instrução se do inicio.
Utilizando uma indução forte, suponhamos que o Potencia(a , ⌊b2⌋ ) devolve a
⌊ b2⌋. Observe que se b for par o
algoritmo Potencia devolve aux*auxque é o mesmo quePotencia(a , ⌊b2⌋ ) * Potencia(a , ⌊
b2⌋ ) = a
⌊ b2⌋ * a
⌊ b2⌋
= ab.
De forma semelhante, suponhamos o caso em que b é ímpar, o Potencia devolverá aux*aux*a = Potencia(
a , ⌊ b2⌋ ) * Potencia(a , ⌊
b2⌋ ) * a = a∗a
b−12 ∗a
b−12 = ab
A complexidade temporal e espacial do algoritmo é dada pela seguinte e fórmula de recorrência:
T(x) = T(⌊x2⌋ )+c
T(0) = c
Façamos a suposição de que x = 2k, o que elimina o chão da equação.
Podemos reescrever a equação de recorrência como:0 T(2k ¿=¿)+c
1 T(2k−1 ¿=¿)+c
2 T(2k−2 ¿=¿)+c
.
.
.k−1T (2)=T (2k−k)+c
k T(1) = T(0) + ck+1 T(0) = c
C∗(K+2)=log2 x+2, ou sejaƟ(log (n))
Como a entrada é log 2n e a complexidade temporal é log(n), podemos dizer que este algoritmo é eficiente.
4) (1 PONTO) O PROBLEMA DA MEDIANA CONSISTE EM, DADA UMA LISTA DE NÚMEROS, DETERMINAR UM NÚMERO X TAL QUE PELO MENOS METADE DOS NÚMEROS DA LISTA SEJA MENOR OU IGUAL A X E PELO MENOS METADE DOS NÚMEROS DA LISTA SEJA MAIOR OU IGUAL A X. UMA FORMA DE CALCULAR A MEDIANA É COLOCAR A LISTA EM ORDEM. SE A LISTA TIVER UMA QUANTIDADE ÍMPAR DE ELEMENTOS, A MEDIANA É O ELEMENTO CENTRAL. SE A LISTA TIVER UMA QUANTIDADE PAR DE ELEMENTOS, A MEDIANA É A MÉDIA ARITMÉTICA DOS DOIS ELEMENTOS CENTRAIS. POR EXEMPLO, A MEDIANA DA LISTA (2, 4, 4, 5, 7) É 4 E A MEDIANA DA LISTA (2, 4, 4, 6, 7, 8) É 5. PESQUISE E INFORME A COTA INFERIOR DE COMPLEXIDADE DO PROBLEMA DA MEDIANA.
De acordo com T.H. Cormen, C.E. Leiserson, R.L. Rivest, C. Stein, ao fim do capítulo 9 (Medianas e Estatística de Ordem) do seu livro Introdução à Análise de Algoritmos eles afirmam a existência de diversos algoritmos lineares para encontrar a mediana de uma lista de números e que alguns indivíduos como Bentand John forneceram “limites inferiores” para o problema. Podemos então afirmar que a cota inferior desse problema é linear.
5) (1 PONTO) PESQUISE E INFORME UM ALGORITMO DE COTA SUPERIOR PARA O PROBLEMA DE FLUXOS EM REDES (MAXIMUMFLOWPROBLEM).O algoritmo sugerido por Jim Orlin's promete resolver o problema de MaxFlow em tempo O(VE), onde V é o número de vértices e E o número de arestas, o que é o melhor tempo já proposto, sendo assim não há necessidade de executá-lo em tempo maior, o que o define com um algoritmo de cota superior. Contudo existem alguns requisitos relativos a este algoritmo, então resolvemos apresentar o segundo melhor desempenho, o Push Relable que promete resolver o problema em tempo O(VE log(V2/E)).
6) (2 PONTOS) ESCREVA UM ALGORITMO DE COTA INFERIOR PARA O PROBLEMA DA SOMA DE MATRIZES. PROVE QUE SEU ALGORITMO É CORRETO E QUE É UM ALGORITMO DE COTA INFERIOR.
Algoritmo Matriz Entrada: Duas A e B matrizes de tamanho NxMSaída: Matriz C de tamanho NxM com a soma das matrizes A e B.
para i de 0 até n-1par j de 0 até m-1
C[i][j] = A[i][j]+B[i][j]
devolva C
Observando que o algoritmo executa loops finitos que não são alterados no decorrer da execução é simples observar que no final de cada iteração do loop interno a i-ésima,j-ésima posição da matriz C conterá o resultado da soma das respectivas posições das matrizes A e B. Sabendo também que i varia de 0 até n-1 garante que todas as linhas de A e B serão percorridas, do mesmo modo com j variando de 0 a m-1 garante que todas as colunas serão acessadas. Dessa forma todas as combinações de colunas e linhas serão acessadas igualmente nas 3 matrizes, pois as 3 possuem o mesmo índice de acesso em cada iteração.
O tamanho da saída que o problema produz uma matriz com o resultado da soma de duas outras matrizes nos dá uma pista sobre a cota inferior. É necessário no mínimo o tempo de salvar, ou realizar a soma para cada elemento da matriz resultado, então podemos dizer que a complexidade intrínseca deste problema é Ω(NM), assumindo uma matriz resultado de tamanho N por M.
Analisando o algoritmo sugerido vemos que a instrução de soma dentro do loop interno é uma instrução crítica e é executada N*M vezes. A complexidade temporal desse algoritmo seria então Ɵ(N*M). A complexidade temporal do algoritmo é igual a complexidade intrínseca do problema, logo este algoritmo é um algoritmo de cota inferior.