semestre_2/Introdução à Análise de Alg.../Lista 1/Resolução Lista 1 - IAA.md

155 lines
6.1 KiB
Markdown
Raw Normal View History

2021-10-13 03:19:03 +02:00
# Respostas à [Lista 1](https://drive.google.com/file/d/1bOWYihTvIgRx1qOnv2WR7uIQDZSzxZ7a/view?usp=drive_web&authuser=0) da disciplina de Introdução à Análise de Algoritmos
> Feita por Guilherme de Abreu Barreto[^1]
## Exercício 1
```c
m ← 0 // c_2
2021-11-21 23:26:48 +01:00
for i ← 1 até n // c_2 + c_5 + (n - 1) c_1
do for j ← 1 até n // c_2 + c_5 + (n - 1)² c_1
do for k ← 1 até n // c_2 + c_5 + (n - 1)³ c_1
2021-10-17 22:56:35 +02:00
if a_i + b_j + c_k = 0 // n³ (2 c_3 + c_5)
2021-11-21 23:26:48 +01:00
then m ← m + 1 // 0 (c_2 + c_3) até n³ (c_2 + c_3)
2021-10-13 03:19:03 +02:00
return m // c_4
```
2021-11-21 23:26:48 +01:00
> **Obs:** Admite-se
2021-10-13 03:19:03 +02:00
$$
2021-11-21 23:26:48 +01:00
c_1 (\text{iteração})= c_3 (\text{soma}) + c_2 (\text{atribuição}) + c_5 (\text{comparação com o valor }n)
2021-10-13 03:19:03 +02:00
$$
2021-11-21 23:26:48 +01:00
Assim o sendo, temos que este algoritmo, na ausência de valores capazes de satisfazer a condição de acréscimo da variável $m$ (melhor caso) tem um tempo de execução equivalente à:
2021-10-13 03:19:03 +02:00
$$
2021-11-21 23:26:48 +01:00
(n^3 - 2n^2 + n - 1)c_1 + 4c_2 + 2n^3 c_3 + c_4 + (n^3 + 3)c_5
$$
Enquanto quando este encontra apenas valores compatíveis (pior caso), este tem um tempo de execução equivalente à:
$$
(n^3 - 2n^2 + n - 1)c_1 + (n^3 + 4)c_2 + 3n^3 c_3 + c_4 + (n^3 + 3)c_5\ \blacksquare
2021-10-13 03:19:03 +02:00
$$
2021-10-17 22:56:35 +02:00
## Exercício 2
2021-10-13 03:19:03 +02:00
2021-10-17 22:56:35 +02:00
Segundo Márcio Ribeiro (2021, p. 32), temos que:
2021-10-13 03:19:03 +02:00
> [...] funções crescem de maneira similar uma vez que abstraímos as constantes.
>
> A notação $\Theta$ formaliza matematicamente essa ideia. [...] $\Theta(g(n))$ é o conjunto de todas as funções que crescem de maneira parecida com $g$, que são *assintoticamente equivalentes* a $g$.
2021-10-17 22:56:35 +02:00
O autor então exprime este conceito na seguinte fórmula matemática:
2021-10-13 03:19:03 +02:00
$$
0 \le c_1g(n) \le f(n) \le c_2g(n)
$$
2021-11-21 23:26:48 +01:00
Assim sendo, temos que em nosso caso $g(n) = n^3$, enquanto a função equivalente ao pior caso, igualando as constantes à 1, e substituindo $c_1$ por $c_2 + c_3 + c_5$ é $f(n) = 8n^3 - 6 n^2 + 3n + 5$, para qualquer $n \ge 1$. Assim sendo, tem-se:
2021-10-13 03:19:03 +02:00
$$
2021-11-21 23:26:48 +01:00
0 \le c_1n^3 \le 8n^3 - 6n^2 + 3n + 5 \le c_2n^3
2021-10-13 03:19:03 +02:00
$$
2021-11-21 23:26:48 +01:00
Utilizando-se de uma calculadora eletrônica, obtemos que $0 \le c_1 ⪅ 2.16$ e $10 \le c_2$.
2021-10-13 03:19:03 +02:00
De fato, vemos que este resultado se concretiza para valores de $n \ge 1$:
2021-11-21 23:26:48 +01:00
<img title="" src="file:///home/user/Public/USP/Sistemas%20de%20Informação/2º%20semestre/Introdução%20à%20Análise%20de%20Algoritmos/Imagens/2021-10-18-13-22-07-image.png" alt="" width="485" data-align="center">
2021-10-13 03:19:03 +02:00
2021-11-21 23:26:48 +01:00
> Linha azul: $f(n)$; linha verde: $2.16\,g(n)$; e linha vermelha: $10\,g(n)$
2021-10-13 03:19:03 +02:00
2021-11-21 23:26:48 +01:00
Portanto, o tempo de processamento do algoritmo 3Soma é $\Theta(n^3)$ no pior caso. $\blacksquare$
2021-10-13 03:19:03 +02:00
2021-10-17 22:56:35 +02:00
## Exercício 3
2021-10-13 03:19:03 +02:00
```c
insertionSort (A, n)
2021-10-17 22:56:35 +02:00
if (n ≤ 1)
then return
insertionSort (A, n - 1)
tmp ← A[n]
i ← n - 1
while i > 0 and A[i] > tmp do
A[i + 1] ← A[i]
i ← i - 1
end
A[i + 1] ← tmp
2021-10-13 03:19:03 +02:00
end
binarySearch (A, n, key)
2021-10-17 22:56:35 +02:00
i ← ⌊n + 1 / 2⌋
if (A[i] = key)
then return true
if (n ≤ 1)
then return false
if (A[i] < key)
then return binarySearch(A[i + 1], n - i, key)
return binarySearch(A, i - 1, key)
2021-10-13 03:19:03 +02:00
end
3Soma (A, B, C)
2021-10-17 22:56:35 +02:00
m ← 0
insertionSort (C, sizeof(C))
2021-11-21 23:26:48 +01:00
for i ← 1 to sizeof(A)
do for j ← 1 to sizeof(B)
2021-10-17 22:56:35 +02:00
do if binarySearch (C, sizeof(C), -(A[i] + B[j]))
then m ← m + 1
return m
2021-10-13 03:19:03 +02:00
end
```
2021-10-17 22:56:35 +02:00
> **Obs:** Os algoritmos `insertionSort` e `binarySearch` acima expostos admitem listas cujos índices encontram-se numerados $1, 2, \dots, n$.
Conforme demonstra Ribeiro (Ibid., p. 45), o tempo de execução $T$ do algoritmo *Insertion Sort* é
$$
T(n) \in \Theta(n^2)
$$
Enquanto o tempo de execução $T$ do algoritmo de busca binária (Ibid. p. 35) é
$$
T(n) \in \Theta(\log(n))
$$
Com isso e a modificação na função `3Soma` que reduz o número de repetições do tipo `for` de três para duas ($T(n) \in \Theta(n^2)$), é possível afirmar que o tempo de execução $T$ no pior caso para a 32ª linha do código (`do if binarySearch (C, sizeof(C), -(A[i] + B[j]))`), é tal que
$$
T(n) \in \Theta(n^2\log n)
$$
2021-11-21 23:26:48 +01:00
Sendo esta a linha com maior número de iterações no algoritmo `3Soma`, podemos, por extensão, afirmar que a notação $\Theta$ anteriormente descrita é representativa do tempo de execução do algoritmo como um todo. $\blacksquare$
2021-10-17 22:56:35 +02:00
## Exercício 4
Conforme a hipótese, o algoritmo proposto é correto se este retorna para qualquer sequência $A[1], \dots , A[n]$ a mesma ordenada de forma crescente.
Ora, ao longo de toda sua execução, é invariável que os elementos em $A[1], \dots, A[i]$ encontram-se ordenados em ordem crescente.
- Na inicialização, quando $A[i] = A[1]$, a base da hipótese;
- Nos passos seguintes, seja quando$A[1]\ e\ A[2]$ encontram-se ordenados e $A[3]$ é relocado na linha 6 se avaliado necessário na linha 5, seja para qualquer valor $i + 1$ que se segue, o que constitui a manutenção da propriedade invariável;
- Seja ao término do programa, quando $i + 1 = n$ e o programa finalmente retorna a sequência ordem crescente.
O programa descrito é portanto, correto. Ainda que bastante ineficiente, mas isso não cabe aqui avaliar. $\blacksquare$
## Exercício 5
O algoritmo proposto é correto se
- havendo um ou mais valores $a_i + b_j + c_k = 0$, onde $a_i \in \{a_1, ..., a_n\}$, $b_j \in \{b_1, ..., b_n\}$ e $c_k \in \{a_1, ..., a_n\}$, este retorna um valor $m \ge 1$;
- senão este retorna um valor $m = 0$.
Ao longo de sua execução, é invariável que $m$ equivale ao número de somas possíveis iguais a 0 entre todos os números em $\{a_1, ..., a_i\}$, com $\{b_1, ..., b_j\}$ e $\{c_1, ..., c_k\}$ desde a inicialização $(a_1,b_1,c_1)$ (base da hipótese), para cada valor $(a_i,b_j,c_k)$ (passo da indução), e ao ser alcançada a condição de término onde $(a_n,b_n,c_n)$. Assim, ao término deste programa todas as combinações possíveis foram avaliadas e este é, portanto, correto. $\blacksquare$
## Referências
RIBEIRO, M. **Introdução à Análise de Algoritmos**. Disponível em: <https://github.com/marciomr/apostila-iaa/blob/master/apostila-iaa.pdf>. Acesso em: 13 out. 2021.
2021-10-13 03:19:03 +02:00
2021-11-21 23:26:48 +01:00
[^1]: nUSP: 12543033; Turma 04