Departamento de Ciência da Computação - IME - USP

MAC2166 Introdução à Computação

Escola Politécnica - Primeiro Semestre de 2013

Prova 1


QUESTÃO 1

      O método das congruências lineares pode ser usado para gerar uma sequência X1,X2,. . ., Xi, Xi+1,. . . de números a partir de um inteiro positivo X0, conhecido como semente. O número Xi+1 da sequência é obtido a partir do número Xi pela fórmula Xi+1 = (aXi + b) mod m

      Uma maneira de obter números aleatórios no intervalo [0,1], utilizando o método das congruências lineares, é a divisão dos números da sequência por m.

      Para saber se um gerador de números aleatórios é razoavelmente bom, pode-se verificar as frequências dos números gerados.

      Escreva um programa em Python que lê os números inteiros a, b, m, X0 e n, gera n números aleatórios no intervalo [0,1] usando o método das congruências lineares, e imprime as frequências de ocorrências dos números nos intervalos [0; 0.2, [0.2; 0.4[, [0.4; 0.6[, [0.6; 0.8[, [0.8; 1.0]. A frequência em um intervalo é a quantidade de vezes que números ocorreram no intervalo, dividido por n.

SOLUÇÃO


#--------------------------------------------------------------------
# DEBUG é uma variável usada durante a fase de teste
# NÃO FAZ PARTE DA SOLUÇÃO DA QUESTÃO
#
#   DEBUG = True para programa imprimir valores calculados
#   DEBUG = False para programa ser executado "silenciosamente"
#
# Sugerimos que você faça algo semelhante durante o desenvolvimento
# dos seus programas
#--------------------------------------------------------------------
DEBUG = True # não faz parte da solução

# valores usados pelo gerador de números aleatórios
a = int(input("Digite o valor de a: "))
b = int(input("Digite o valor de b: "))
m = int(input("Digite o valor de m: "))

# semente do gerador de números aleatórios
X = int(input("Digite o valor e X0: "))

# quantidada de números aleatórios a serem gerados
n = int(input("Digite o valor de n: "))

# contadores de quantidade de número em cada intervalo 
# para serem usados nos cálculos das frequências

quant_0_2 = 0
quant_0_4 = 0
quant_0_6 = 0
quant_0_8 = 0
quant_1_0 = 0

i = 0
while i < n:
    X = (a*X + b)%m
    r = X/m
    if DEBUG: # não faz parte da solução
        print("DEBUG: X =", X)
        print("DEBUG: r =", r)

    if   r < 0.2:
        quant_0_2 = quant_0_2 + 1
    elif r < 0.4: 
        quant_0_4 = quant_0_4 + 1
    elif r < 0.6:
        quant_0_6 = quant_0_6 + 1
    elif r < 0.8: 
        quant_0_8 = quant_0_8 + 1
    else: # neste ponto vale que: 0.8 <= r and r <= 1 
        quant_1_0 = quant_1_0 + 1

    if DEBUG:  # não faz parte da solução
        print("DEBUG: quant 0   <= r and r <  0.2 =", quant_0_2)
        print("DEBUG: quant 0.2 <= r and r <  0.4 =", quant_0_4)
        print("DEBUG: quant 0.4 <= r and r <  0.6 =", quant_0_6)
        print("DEBUG: quant 0.6 <= r and r <  0.8 =", quant_0_8)
        print("DEBUG: quant 0.8 <= r and r <= 1.0 =", quant_1_0)
        input("Digite ENTER para continuar.\n")

    i = i + 1

print("Frequência no intervalo [0  ;0.2[ =", quant_0_2/n)
print("Frequência no intervalo [0.2;0.4[ =", quant_0_4/n)
print("Frequência no intervalo [0.4;0.6[ =", quant_0_6/n)
print("Frequência no intervalo [0.6;0.8[ =", quant_0_8/n)
print("Frequência no intervalo [0.8;1.0] =", quant_1_0/n)


# SUGESTÃO:
#
# teste o programa acima com os valores do EP2
#
#   a = 22695477
#   b = 1
#   m = 4294967296 (== 2**32)
#   X = 10
#   n = ?
#
# e observe os valores gerados


QUESTÃO 2

      Dada uma sequência de números inteiros, o valor absoluto (módulo) da diferença entre dois números consecutivos da sequência corresponde à altura do ``degrau'' entre eles. Por exemplo, na seguinte sequência com 7 números

 
           4    0    -1    2    2    3    8