Generador de congruencia lineal Multiplicativo
Enviado por mememe21 • 19 de Enero de 2019 • Práctica o problema • 3.738 Palabras (15 Páginas) • 119 Visitas
Deber#2
2do Parcial
Generador de congruencia lineal Multiplicativo
Nombre: Allan Orellana Valenzuela
Instrucciones:
- Usando el programa que a usted le convenga, diseñe un Generador de Congruecia Lineal Multiplicativo.
- Considere el caso que ‘m’ sea potencia de 2; variando los valores de a indique cual es el periodo maximo que obtiene usando este tipo de generadores.
- Considere el caso que ‘m’ no sea potencia de 2; variando los valores de a indique cual es el periodo maximo que obtiene usando este tipo de generadores.
- Que tipo de generador provee el mayor periodo?
- Presente una funcion con la cual se genere una secuencia psudoaleatoria con periodo maximo. Que tipo de generador usaria? Indique el procedimiento usado para obtener ese resultado. Considera usted este requerimiento un problema de analisis o de diseño.
- Considera usted que el programa utilizado para hacer la simulacion es el optimo? O deberia usar otro programa?
Software:
Python 3.6
Procedimiento:
- Usando el programa que a usted le convenga, diseñe un Generador de Congruecia Lineal Multiplicativo.
Primero se importaron las librerias necesarias y despues se creo una funcion de ayuda que nos permitrá saber si un numero es potencia de dos o no:
[pic 1]
Despues se creo la función que obtendrá la lista de números aleatorios:
[pic 2]
En la función se toma los valores correspondientes de a, x0, y m. Se realiza la verificación de las condiciones iniciales y comienza a llenarse una lista con los valores obtenidos de:
En = (a*Xn-1) mod m
hasta que se cumpla un periodo (hasta que algún número se repita) o si este excede del valor máximo que es igual a m-1, si m no es potencia de 2, o igual a 2^k-2 donde m = 2^k , esto ultimo debido a los valores oscilantes.
La función devuelve la lista de numero aleatorios y el periodo de la mima. En caso de falla se devuelve una lista vacía y un periodo negativo.
[pic 3]
- Considere el caso que ‘m’ sea potencia de 2; variando los valores de a indique cual es el periodo maximo que obtiene usando este tipo de generadores.
Tanto para el tema 2 y el tema 3 se utilizó la siguiente función:
[pic 4]
[pic 5]
La función realiza un barrido de las variables a, m y x y se obtendrá por cada combinación una lista de números aleatorios de la cual se almacenará su periodo y la combinación [a, x0, m] en un diccionario para su posterior visualización. En este caso se mantendrá constante el valor de la semilla. El valor de a varia de 0 a y m 100.
[pic 6]
Se observa solo los parámetros que generan su máximo periodo, y como se observa el periodo es 4 veces menor que el valor de 4, esto comprueba la teoría cuando m es potencia de dos.
- Considere el caso que ‘m’ no sea potencia de 2; variando los valores de a indique cual es el periodo maximo que obtiene usando este tipo de generadores.
Se utilizará el mismo código que en el tema 2 pero esta vez se mostraran las lista con parámetros cuando m no es potencia de 2
[pic 7]
Como se observa se generar una lista de números aleatorios con periodo de m-1. Coincide con la teoria
- Que tipo de generador provee el mayor periodo?
El generador donde m no es potencia de dos
- Considera usted que el programa utilizado para hacer la simulacion es el optimo? O deberia usar otro programa?
Si porque Python maneja muy bien la memoria al momento de la creación de listas y cálculos.
- Generador
[pic 8]
Código completo en Python
import sys
from random import randint
from math import log, floor
def esPotenciaDos(numero):
if numero < 1:
return False
i = log(numero, 2)
return 0 == (i - floor(i))
def generador_multiplicativo (a,x0,m):
if (m > 0 and a>0 ): #Condiciones iniciales para un LCG multiplicativo
list = []
x0 = (a*x0) % m
list.append(x0)
x1 = x0
maxPeriod = 0
if (esPotenciaDos(m)):
k = log(m,2)
#print("aqui1")
maxPeriod = 2**(k-2)
else:
#print("aqui2")
maxPeriod = m-1
#print(maxPeriod)
while (list.count(x1) != 2 and len(list)<=maxPeriod): #Condiciones de parada, Solo tomar 1 periodo
x1 = (a*x1 ) % m #y que el periodo no sea mayor a su periodo maximo
list.append(x1)
list = list[:-1]
if len(list) >maxPeriod:
return [],-1
return list,len(list) #Se retorna la lista generada y el periodo
else:
return [],-1
#Esta función genera un barrido de los parametros a,m,x generado listas de numeros aleatorios con diferentes periodos
#si el parametro semillaFija esta habilitada, xmax pasaa ser una constante
def generador_periodo_map(amax ,xmax ,mmax, fijos=[False,False,False] ,soloMaximos = [False, False]): #El parametro semillaFija es opcional, soloMaximos = [k=2, k!=2], fijos = [a,x,m]
...