Você está na página 1de 4

T198 – Construção e Análise de Algoritmos

Prof. Napoleão Nepomuceno


AV3 - Lab02

Exercício 1

Passo 1: Implementar o seguinte código em Java ou equivalente em outra linguagem de programação.


public class Exercicio1 {

static int[] qtde;

public static void main(String[] args) {


int troco = 33;
int[] padrao = {1, 7, 17, 25};
double inicio, fim, tempo;
int q;

inicio = System.currentTimeMillis();
q = trocoDinamico(troco, padrao);
fim = System.currentTimeMillis();
tempo = fim - inicio;
if (q == Integer.MAX_VALUE) {q = -1;}
System.out.printf("%-15s%10s%10s\n", "Método", "Qtde", "Tempo");
System.out.printf("%-15s%10d%10.2f\n\n", "Dinâmico", q, tempo);

inicio = System.currentTimeMillis();
qtde = new int[troco+1];
for (int t = 0; t <= troco; t++) {
qtde[t] = -1;
}
q = trocoMemoization(troco, padrao);
fim = System.currentTimeMillis();
tempo = fim - inicio;
if (q == Integer.MAX_VALUE) {q = -1;}
System.out.printf("%-15s%10s%10s\n", "Método", "Qtde", "Tempo");
System.out.printf("%-15s%10d%10.2f\n\n", "Memoization", q, tempo);

inicio = System.currentTimeMillis();
q = trocoRecursivo(troco, padrao);
fim = System.currentTimeMillis();
tempo = fim - inicio;
if (q == Integer.MAX_VALUE) {q = -1;}
System.out.printf("%-15s%10s%10s\n", "Método", "Qtde", "Tempo");
System.out.printf("%-15s%10d%10.2f\n\n", "Recursivo", q, tempo);
}

static int trocoRecursivo(int troco, int[] padrao) {


if (troco != 0) {
int qMin = Integer.MAX_VALUE;
for (int i = 0; i < padrao.length; i++) {
if (troco - padrao[i] >= 0) {
int q = trocoRecursivo(troco - padrao[i], padrao) + 1;
if (q < 0) {q = Integer.MAX_VALUE;}
if (q < qMin) {qMin = q;}
}
}
return qMin;
}
return 0;
}

static int trocoMemoization(int troco, int[] padrao) {


// to do
return 0;
}

static int trocoDinamico(int troco, int[] padrao) {


int[] q = new int[troco + 1];
int[] c = new int[troco + 1];
for (int t = 1; t <= troco; t++) {
q[t] = Integer.MAX_VALUE;
for (int p = 0; p < padrao.length; p++) {
// to do
}
}
// imprimeTroco(c, troco);
System.out.println();
return q[troco];
}

static void imprimeTroco(int[] c, int troco) {


// to do
}

}
Passo 2: Considere o problema do troco que, dados um padrão de cédulas P e um valor de troco t, deseja-
se determinar a quantidade mínima de cédulas necessárias para perfazer o troco. Seja q[t] a quantidade
mínima de cédulas necessárias para satisfazer o troco t no padrão de cédulas P. Dada a definição
recursiva de q[t] abaixo e sua implementação na função trocoRecursivo, explique:

a) O que significa pi ∈ P : p i ≤ t ? (5%)


Entre todas as moedas do vetor padrão, contanto que o valor da moeda seja menor ou igual ao troco.
b) O que significaq [t− p i]+ 1? (5%)
Calcula o valor da expressão, que é uma da moeda que está se entregando, mais a quantidade mínima de
moedas do troco resultante.
c) Para que serve o teste if (q < 0) q = Integer.MAX_VALUE; ? (5%)
Verifica se o valor de q retornado é menor que zero, se for ele seta o valor máximo que o inteiro pode
assumir, ou nesse caso o “infinito”, isso acontece porque queremos encontrar o valor mínimo real que o
troco pode assumir, valores negativos não são válidos e atrapalham.
d) Para que serve o teste if (q < qMin) qMin = q; ? (5%)
Verifica se o valor de q retornado, é menor do que o valor de q mínimo encontrado até o momento
naquela execução, se o valor do q retornado for menor, ele sobrescreve o valor do q mínimo, para o q
atual, indicando que agora o valor mínimo de q é o q retornado.

0, se t=0 ;
q [t]={ min {q[t− pi ]+1 }, caso contrário.
pi ∈ P : p i ≤ t

static int trocoRecursivo(int troco, int[] padrao) {


if (troco != 0) {
int qMin = Integer.MAX_VALUE;
for (int i = 0; i < padrao.length; i++) {
if (troco - padrao[i] >= 0) {
int q = trocoRecursivo(troco - padrao[i], padrao) + 1;
if (q < 0) q = Integer.MAX_VALUE;
if (q < qMin) qMin = q;
}
}
return qMin;
}
return 0;
}

Passo 3: Faça uma implementação recursiva para o problema utilizando memoization. (15%)

static int trocoMemoization(int troco, int[] padrao) {


if (troco != 0) { // verifica se foi resolvido

int qMin = Integer.MAX_VALUE;


for (int i = 0; i < padrao.length; i++) {
if (troco - padrao[i] >= 0) {
int q = trocoMemoization(troco - padrao[i], padrao) + 1;

if (q < 0) {
q = Integer.MAX_VALUE;
}
if (q < qMin) {
qMin = q;
}
}
}
return qMin;
}
return 0;
}
Passo 4: Faça uma implementação em programação dinâmica para o problema, onde os vetores q[t] e c[t]
são utilizados, respectivamente, para armazenar a quantidade de cédulas e o valor da última cédula
escolhida para perfazer um troco de valor t. (30%)

static int trocoDinamico(int troco, int[] padrao) {


int[] q = new int[troco + 1]; // armazenar a quantidade de cédulas
int[] c = new int[troco + 1]; // valor da última cédula escolhida para o
troco de valor t
for (int t = 1; t <= troco; t++) {
q[t] = Integer.MAX_VALUE;

for (int p = 0; p < padrao.length; p++) {

if (t >= padrao[p]) {

int j = q[t - padrao[p]] + 1;

if (q[t - padrao[p]] < q[t]) {


q[t] = j;
c[t] = padrao[p];
}
}
}
}

imprimeTroco(troco, c);

return q[troco];
}

Passo 5: Faça uma implementação do método imprimirTroco para imprimir as cédulas utilizadas para
perfazer o troco t do algoritmo de programação dinâmica. (15%)

static void imprimeTroco(int troco, int[] c) {


int coin = troco;
int thisCoin = 0;
while (coin > 0) {
thisCoin =troco,
static int trocoDinamico(int c[coin];
int[] padrao) {
int[] qSystem.out.println(thisCoin);
= new int[troco + 1];
int[] ccoin = coin
= new - thisCoin;
int[troco + 1];
}
for (int t = 1; t <= troco; t++) {
} q[t] = Integer.MAX_VALUE;

for (int p = 0; p < padrao.length; p++) {

if (t >= padrao[p]) {

int j = q[t - padrao[p]] + 1;

if (q[t - padrao[p]] < q[t]) {


q[t] = j;
c[t] = padrao[p];
}
}
}
}

imprimeTroco(troco, c);

return q[troco];
}
Passo 6: Realize a análise de complexidade da função trocoDinamico, assumindo como parâmetro de
tamanho do problema o valor do troco (já que, na prática, a quantidade de cédulas do padrão geralmente é
constante). (10%)

Passo 7: Modifique o padrão de cédulas para {7, 17, 25}. Exiba a saída do programa para valor de troco
igual a 33. O que quer dizer esta saída? (5%)

Método Qtde Tempo


Dinâmico -1 0,00

Método Qtde Tempo


Memoization -1 0,00

Método Qtde Tempo


Recursivo -1 0,00

R: Significa que não há uma forma de pagar o valor exato do troco com as cédulas disponíveis.

Passo 8: O que acontece com a execução do programa, utilizando o padrão de cédulas {1, 7, 17, 25}, caso
o valor do troco seja mudado para 100? Explique porque o programa se comporta desta maneira. (5%)

Método Qtde Tempo


Dinâmico 4 0,00

Método Qtde Tempo


Memoization 4 102215,00

Método Qtde Tempo


Recursivo 4 92654,00

R: Os métodos que usam recursividade demoraram mais para executar do que o método dinâmico, isso
acontece pois os métodos recursivos são mais complexos que o dinâmico.

Passo 9: Indicar o nome dos integrantes da equipe que participaram efetivamente na resolução deste
laboratório. (0%)

Você também pode gostar