0% encontró este documento útil (0 votos)
52 vistas32 páginas

03 Capitulo

El documento describe el método de los cuadrados medios para generar números aleatorios pseudoaleatorios. El método involucra elegir un valor inicial o "semilla", elevar ese número al cuadrado, tomar los dígitos centrales del cuadrado como el siguiente número pseudoaleatorio, y repetir el proceso las veces necesarias para generar una secuencia de números.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
52 vistas32 páginas

03 Capitulo

El documento describe el método de los cuadrados medios para generar números aleatorios pseudoaleatorios. El método involucra elegir un valor inicial o "semilla", elevar ese número al cuadrado, tomar los dígitos centrales del cuadrado como el siguiente número pseudoaleatorio, y repetir el proceso las veces necesarias para generar una secuencia de números.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 32

4/1/2021 03_Cap_NumerosAleatorios

CAPITULO III NÚMEROS ALEATORIOS

3.1 Introducción.
La simulación de cualquier sistema o proceso donde existen componentes aleatorios necesita de
números al azar, un número aleatorio es un número de una secuencia cuya probabilidad de
ocurrencia es igual a la de cualquier otro número de la secuencia. Disponer de un buen generador
de números aleatorios es fundamental en cualquier simulación. Constituye también una parte
fundamental en otras áreas, como la Informática (algoritmos aleatorizados, verificación de
algoritmos, complejidad de algoritmos, criptografía, ...), la Estadística (métodos de muestreo y
remuestreo, contrastes Montecarlo, Inferencia Bayesiana, ...), y, en general, en cualquier
problema de cálculo científico que, de manera directa o indirecta, incluya algún elemento
probabilístico incluyendo los juegos de video.

Actualmente existen múltiples generadores de números aleatorios en diferentes entornos y


compiladores lo cual supondría para un usuario de la Simulación que no es necesario su estudio.
Sin embargo, observaciones sobre algunos generadores comerciales sugieren que debemos
actuar con cuidado con el uso de ellos. Incluso, el uso progresivo de modelos de simulación cada
vez más detallados exige generadores de números aleatorios de mayor calidad. La forma de
generar números aleatorios tiene mucha historia, desde los primeros métodos que se llevaron
esencialmente a mano (Manuales) como lanzar dados, retirar cartas, agitar urnas y muchas de las
loterías en la actualidad todavía son muy utilizadas. A medida que las computadoras han
revolucionado tecnológicamente ha aumentado la atención en la generación de números
aleatorios de forma numérica, aritmética, algorítmica de formas secuenciales, como el método de
la raíz media que dio inicio a la gran cantidad de algoritmos y su utilización en los diferentes
problemas de simulación. Algunos autores siguen discutiendo que realmente los generadores por
algoritmos aritméticos no son realmente números aleatorios sino llamados pseudoaleatorios.

El inicio en la generación de números aleatorios con Métodos Manuales, los mismos que son
laboriosos y no muy prácticos se utiliza en procesos tales como:

- Ruleta
- Baraja
- Dados
- Lanzamientos de moneda
**Las DESVENTAJAS:**
- No es reproducible
- Lento
- No se pueden usar en computadores

Luego continúa con Métodos generados por Equipos Eléctricos como:

- RAND(Rand Corporation (1955) utilizado para generar una tabla de un mi


llón de números aleatorios proveniente de las mediciones del ruido eléct
rico)
- ERNIE(Electronic Random Number Indicator Equipment, utilizado para gen
erar números aleatorios para la lotería)

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 1/32
4/1/2021 03_Cap_NumerosAleatorios

Y por último los generados por Computador Digital (Algoritmos Matemáticos) que en la década del
1950 se convertiría en la época en la que se generara números aleatorios de forma aritmética,
estos métodos son secuenciales con cada número nuevo obtenido por uno o varios de sus
predecesores de acuerdo a una fórmula matemática fija. Uno de los primeros métodos propuestos
por Von Neuman y Metropolis, con el famoso método de los cuadrados medios que resumimos a
continuación, pero debemos señalar que los números aleatorios llamados propiamente
pseudoaleatorios que deben cumplir con ciertas características:

- Deben ser uniformemente distribuidos u[0,1]


- Estadísticamente independiente (La correlación entre los números gener
ados sea mínimos y se mide entre números consecutivos.
- Debe ser reproducible
- Generar a grandes velocidades
- Mínimo almacenamiento
- Sin repetición, con largos periodos

Método de los cuadrados medios


La primera técnica de generación de números pseudoaleatorios conocida como técnica del
cuadrado medio. que consta de los siguientes pasos:

- Seleccione un valor inicial o "semilla" (r ).


- Determinamos el número de dígitos
- Elévese al cuadrado el valor inicial.
- Tómense lo n dígitos centrales del cuadrado del número anterior
- Repítase el proceso cuantas veces sea necesario.

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 2/32
4/1/2021 03_Cap_NumerosAleatorios

In [10]: 1 # Método de los cuadrados medios


2 import pandas as pd
3 import numpy as np
4 import matplotlib.pyplot as plt
5 n=100
6 #r=7182 # seleccionamos el valor inicial r
7 r=171 # seleccionamos el valor inicial r
8 l=len(str(r)) # determinamos el número de dígitos
9 lista = [] # almacenamos en una lista
10 lista2 = []
11 i=1
12 #while len(lista) == len(set(lista)):
13 while i < n:
14 x=str(r*r) # Elevamos al cuadrado r
15 if l % 2 == 0:
16 x = x.zfill(l*2)
17 else:
18 x = x.zfill(l)
19 y=(len(x)-l)/2
20 y=int(y)
21 r=int(x[y:y+l])
22 lista.append(r)
23 lista2.append(x)
24 i=i+1
25
26 df = pd.DataFrame({'X2':lista2,'Xi':lista})
27 dfrac = df["Xi"]/10**l
28
29 df["ri"] = dfrac
30 #df.head()
31 df

Out[10]:
X2 Xi ri

0 29241 924 0.924

1 853776 537 0.537

2 288369 883 0.883

3 779689 796 0.796

4 633616 336 0.336

5 112896 128 0.128

6 16384 638 0.638

7 407044 70 0.070

8 4900 490 0.490

9 240100 401 0.401

10 160801 608 0.608

11 369664 696 0.696

12 484416 844 0.844

13 712336 123 0.123

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 3/32
4/1/2021 03_Cap_NumerosAleatorios

X2 Xi ri

14 15129 512 0.512

15 262144 621 0.621

16 385641 856 0.856

17 732736 327 0.327

18 106929 69 0.069

19 4761 476 0.476

20 226576 265 0.265

21 70225 22 0.022

22 484 484 0.484

23 234256 342 0.342

24 116964 169 0.169

25 28561 856 0.856

26 732736 327 0.327

27 106929 69 0.069

28 4761 476 0.476

29 226576 265 0.265

... ... ... ...

69 116964 169 0.169

70 28561 856 0.856

71 732736 327 0.327

72 106929 69 0.069

73 4761 476 0.476

74 226576 265 0.265

75 70225 22 0.022

76 484 484 0.484

77 234256 342 0.342

78 116964 169 0.169

79 28561 856 0.856

80 732736 327 0.327

81 106929 69 0.069

82 4761 476 0.476

83 226576 265 0.265

84 70225 22 0.022

85 484 484 0.484

86 234256 342 0.342

87 116964 169 0.169

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 4/32
4/1/2021 03_Cap_NumerosAleatorios

X2 Xi ri

88 28561 856 0.856

89 732736 327 0.327

90 106929 69 0.069

91 4761 476 0.476

92 226576 265 0.265

93 70225 22 0.022

94 484 484 0.484

95 234256 342 0.342

96 116964 169 0.169

97 28561 856 0.856

98 732736 327 0.327

99 rows × 3 columns

In [11]: 1 df.tail()
2

Out[11]:
X2 Xi ri

94 484 484 0.484

95 234256 342 0.342

96 116964 169 0.169

97 28561 856 0.856

98 732736 327 0.327

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 5/32
4/1/2021 03_Cap_NumerosAleatorios

In [12]: 1 ### Graficando los numeros aleatorios generados


2 # seleccionamos del dataframe los nùmeros generados
3 x1=df['ri']
4 plt.plot(x1)
5 plt.title('Generador de Numeros Aleatorios Cuadrados Medios')
6 plt.xlabel('Serie')
7 plt.ylabel('Aleatorios')
8 plt.show()

Análisis del método de cuadrados medios ¶


Como podemos observar los Numeros Aleatorios generados por los cuadrados medios con muy
pocos numeros generados no cumplen con los principios de los numeros aleatorios como: Sin
repetición, con largos periodos, por lo tanto para utilizar este método hay que ser muy
cuidadoso en la selección de la semilla.

en el código anterior podemos cambiar la cantidad de numeros n** y/o la semilla **r, donde
observaremos facilmente que este método no favorece para la simulación.

3.2 Métodos congruenciales lineales


La mayoría de los generadores de números aleatorios que se utilizan hoy son los congruenciales
lineales, Lehmer (1951) incorporo una secuencia de números enteros X1, X2,X3,X4, definida
como una formula recursiva de la siguiente forma:

- Xn+1 = (aXn + c) (modulo m)


- Xn+2 = (aXn+1 + c) (modulo m)
- Xn = Semilla
- a = multiplicador
- c = incremento
- m = modulo
- Que son enteros positivos

Propiedades:

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 6/32
4/1/2021 03_Cap_NumerosAleatorios

- 0 < m , a < m, c<m


- ri = Xn+1 / m

Como el caso anterior de los cuadrados medios se debe seleccionar cuidadosamente a,c,m,Xn
ya que de estas variables depende la calidad y el cumplimiento de los requisitos para ser
considerado un buen generador de números aleatorios.

Ejemplo

m = 1000, a = 101, c = 457 , X0 = 4

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 7/32
4/1/2021 03_Cap_NumerosAleatorios

In [8]: 1 # Generador de números aleatorios Congruencia lineal


2 n, m, a, x0, c = 20, 1000, 101, 4, 457
3 x = [1] * n
4 r = [0.1] * n
5 print (" Método de Congruencia Lineal ")
6 print("-------------------------------")
7 print ("n=cantidad de números generados : ", n)
8 print()
9 print ("m : ", m)
10 print ("a : ", a)
11 print ("c : ", c)
12 print ("Xo : ", x0 )
13
14 for i in range(0, n):
15 x[i] = ((a*x0)+c) % m
16 x0 = x[i]
17 r[i] = x0 / m
18 # llenamos nuestro DataFrame
19 d = {'Xn': x, 'ri': r }
20 df = pd.DataFrame(data=d)
21 df
22

Método de Congruencia Lineal


-------------------------------
n=cantidad de números generados : 20

m : 1000
a : 101
c : 457
Xo : 4

Out[8]:
Xn ri

0 861 0.861

1 418 0.418

2 675 0.675

3 632 0.632

4 289 0.289

5 646 0.646

6 703 0.703

7 460 0.460

8 917 0.917

9 74 0.074

10 931 0.931

11 488 0.488

12 745 0.745

13 702 0.702

14 359 0.359

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 8/32
4/1/2021 03_Cap_NumerosAleatorios

Xn ri

15 716 0.716

16 773 0.773

17 530 0.530

18 987 0.987

19 144 0.144

In [9]: 1 # Graficamos los numeros generados


2 plt.plot(r,marker='o')
3 plt.title('Generador de Numeros Aleatorios ')
4 plt.xlabel('Serie')
5 plt.ylabel('Aleatorios')
6

Out[9]: Text(0, 0.5, 'Aleatorios')

Congruenciales multiplicativo
EL método multiplicativo congruencial es otro caso especial, donde la constante c=0 quedando la
sucesión de la siguiente forma:

Xn+1 = (aXn ) (mod m)

Se ha demostrado que este método se comporta aceptablemente desde el punto de vista


estadístico. Con éste método el periodo máximo es m/4 y para asegurar esta propiedad cuando se
utilizan computadoras binarias se consideran los siguientes criterios en la selección de los
parámetros.

- La elección de *m* debe hacerse mediante la relación:


- m = 2^b , (b>2) para cumputadora binaria
- Xn o sea el valor inicial o semilla deberá ser numero primo.
- En cuanto al valor de la constante *a* su valor podrá ser de Los númer
os primos y además a<m,

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 9/32
4/1/2021 03_Cap_NumerosAleatorios

para el ejemplo vamos a utilizar los datos de un generador del la hoja electrónica Excel-03, Excel-
07 *Wichman y Hill (1982) :

- Xn+1 = (171Xn ) (mod 30264)


- Xn+1 = (172Xn ) (mod 30307)
- Xn+1 = (170Xn ) (mod 30323)

Ejemplo 1 : Xn+1 = (171Xn ) (mod 30264)

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 10/32
4/1/2021 03_Cap_NumerosAleatorios

In [10]: 1 # generador excel-03


2 # - Xn+1 = (171Xn ) (mod 30264)
3 n, m, a, x0 = 20, 1000, 747, 123
4 x = [1] * n
5 r = [0.1] * n
6 print (" Generador Congruencial multiplicativo")
7 print ("--------------------------------------")
8 for i in range(0, n):
9 x[i] = (a*x0) % m
10 x0 = x[i]
11 r[i] = x0 / m
12 d = {'Xn': x, 'ri': r }
13 df = pd.DataFrame(data=d)
14 df
15

Generador Congruencial multiplicativo


--------------------------------------

Out[10]:
Xn ri

0 881 0.881

1 107 0.107

2 929 0.929

3 963 0.963

4 361 0.361

5 667 0.667

6 249 0.249

7 3 0.003

8 241 0.241

9 27 0.027

10 169 0.169

11 243 0.243

12 521 0.521

13 187 0.187

14 689 0.689

15 683 0.683

16 201 0.201

17 147 0.147

18 809 0.809

19 323 0.323

Ejemplo 2 : Xn+1 = (172Xn ) (mod 30307)

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 11/32
4/1/2021 03_Cap_NumerosAleatorios

In [11]: 1 # generador excel-07


2 # - Xn+1 = (172Xn ) (mod 30307)
3
4 n, m, a, x0 = 20, 30307, 172, 172
5 x = [1] * n
6 r = [0.1] * n
7 print (" Generador Congruencial multiplicativo")
8 print ("--------------------------------------")
9 for i in range(0, n):
10 x[i] = (a*x0) % m
11 x0 = x[i]
12 r[i] = x0 / m
13 d = {'Xn': x, 'ri': r }
14 df1 = pd.DataFrame(data=d)
15 df1.head()
16

Generador Congruencial multiplicativo


--------------------------------------

Out[11]:
Xn ri

0 29584 0.976144

1 27179 0.896790

2 7510 0.247798

3 18826 0.621177

4 25530 0.842380

Ejemplo 3 : Xn+1 = (170Xn ) (mod 30323)

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 12/32
4/1/2021 03_Cap_NumerosAleatorios

In [12]: 1 # generador excel-07


2 # - Xn+1 = (170Xn ) (mod 30323)
3
4 n, m, a, x0 = 20, 30323, 170, 170
5 x = [1] * n
6 r = [0.1] * n
7 print (" Generador Congruencial multiplicativo")
8 print ("--------------------------------------")
9 for i in range(0, n):
10 x[i] = (a*x0) % m
11 x0 = x[i]
12 r[i] = x0 / m
13 d = {'Xn': x, 'ri': r }
14 df2 = pd.DataFrame(data=d)
15 df2.head()
16

Generador Congruencial multiplicativo


--------------------------------------

Out[12]:
Xn ri

0 28900 0.953072

1 674 0.022227

2 23611 0.778650

3 11234 0.370478

4 29754 0.981235

In [13]: 1 df2.tail()
2

Out[13]:
Xn ri

15 8516 0.280843

16 22539 0.743297

17 10932 0.360518

18 8737 0.288131

19 29786 0.982291

Gráficamos los números aleatorios generados

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 13/32
4/1/2021 03_Cap_NumerosAleatorios

In [14]: 1 plt.plot(r,'g-', marker='o',)


2 plt.title('Generador de Numeros Aleatorios ')
3 plt.xlabel('Serie')
4 plt.ylabel('Aleatorios')
5

Out[14]: Text(0, 0.5, 'Aleatorios')

In [15]: 1 x1 = df["ri"]
2 x1.plot.area()

Out[15]: <matplotlib.axes._subplots.AxesSubplot at 0x1d14a6cf4a8>

In [ ]: 1

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 14/32
4/1/2021 03_Cap_NumerosAleatorios

Graficamos los tres modelos de generadores con sus diferentes


constantes a,m,xo

In [16]: 1 import matplotlib as mpl


2 import matplotlib.pyplot as plt
3 import numpy as np
4
5 x1 = df["ri"]
6 x2 = df1["ri"]
7 x3 = df2["ri"]
8 x = np.arange(n)
9
10 #fig = plt.figure()
11 plt.figure(figsize=(15,5))
12 # Gráfico 1
13 plt.subplot(131)
14 x1 = df["ri"]
15 p1, = plt.plot(x,x1,'r-',marker='o')
16 plt.ylabel('# Aleatorios')
17 plt.title(' Xn+1 = (172Xn ) (mod 30307) ')
18
19 # Gráfico 2
20 plt.subplot(132)
21 x2 = df1["ri"]
22 p1, = plt.plot(x,x2,'b-',marker='o')
23 plt.title(' Xn+1 = (172Xn ) (mod 30307) ')
24
25 # Gráfico 2
26 plt.subplot(133)
27 x3 = df2["ri"]
28 p1, = plt.plot(x,x3,'g-',marker='o')
29 plt.title(' Xn+1 = (170Xn ) (mod 30323) ')
30
31

Out[16]: Text(0.5, 1.0, ' Xn+1 = (170Xn ) (mod 30323) ')

Conclusiones
En el gráfico podemos observar que las constantes a,m,xo son importantes en la generación de
números aleatorios
localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 15/32
4/1/2021 03_Cap_NumerosAleatorios
ú e os a eato os

3.3 Otros Generadores utilizados


David Ríos 2009, propone los siguientes ejercicios para analizar el comportamiento de estos
generadores aleatorios:

RANDU xi+1 = 65539xi mod 2^31


Sinclair ZX81 xi+1=75xi mod(2^16 + 1)
Numerical reciepes xi+1 = 1664525xi + 1013904223 mod 2^32
Borland C/C++ xi+1=22695477xi + 1 mod 2^32

En el siguiente codigo generamos los números para observar su


comportamiento,

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 16/32
4/1/2021 03_Cap_NumerosAleatorios

In [17]: 1 # Generador de números aleatorios Congruencia lineal


2 # Borland C/C++ xi+1=22695477xi + 1 mod 2^32
3
4 n, m, a, x0, c = 200, 2**32, 22695477, 4, 1
5 x = [1] * n
6 r = [0.1] * n
7 print (" Método de Congruencia Lineal Utilizado por:")
8 print("Borland C/C++ xi+1=22695477xi + 1 mod 2^32 ")
9 print ("n=cantidad de números generados : ", n)
10 print()
11 print ("m : ", m)
12 print ("a : ", a)
13 print ("c : ", c)
14 print ("Xo : ", x0 )
15
16 for i in range(0, n):
17 x[i] = ((a*x0)+c) % m
18 x0 = x[i]
19 r[i] = x0 / m
20 # llenamos nuestro DataFrame
21 d = {'Xn': x, 'ri': r }
22 dfMCL = pd.DataFrame(data=d)
23 dfMCL
24
11 2046132792 0.476402

12 221316505 0.051529

13 1000654510 0.232983

14 349316615 0.081332

15 3163423092 0.736542

16 1151313157 0.268061

17 3793137674 0.883159

18 2782494227 0.647850

19 2024432 0.000471

20 2184728753 0.508672

21 762880678 0.177622

22 4293148767 0.999577

23 2252621228 0.524479

24 3285505181 0 764966

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 17/32
4/1/2021 03_Cap_NumerosAleatorios

In [18]: 1 # Gráficos de dispersión


2 plt.title('Generador de Numeros Aleatorios ')
3 plt.xlabel('Serie')
4 plt.ylabel('Aleatorios')
5
6 #plt.scatter(df.index,df['ri'])
7 plt.plot(r,marker='o')
8 plt.show()

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 18/32
4/1/2021 03_Cap_NumerosAleatorios

In [19]: 1 rS= df['ri']


2 #rS
3 plt.figure(figsize=(10,5))
4 plt.hist(rS,bins=20,color='blue')
5 plt.xlabel('# Aleatorios generados')
6 plt.ylabel('Ocurrencias en rangos')
7 plt.show()
8
9 #Aqui podemos observar en la grafica los números generados para lo cual se h

Gráficamos la dispersión del generador

In [20]: 1 # utilizamos scatter


2 plt.scatter(df.index,df['ri'])

Out[20]: <matplotlib.collections.PathCollection at 0x1d14ab08710>

Generador random de Python np.random.rand


localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 19/32
4/1/2021 03_Cap_NumerosAleatorios

Python cuenta con el módulo random para generación de números pseudo-aleatorios.

Contiene diversos métodos que corresponden a varias formas de generar este tipo de números.
genera numeros aleatorios con una distribución uniforme [0,1] entre 0.0 excepto 1.0, la facilidad es
que puede generar diferentes numeros aleatorios con diferentes intervalos y diferentes
distribuciones que más adelante utilizaremos.

In [21]: 1 # para obtener la ayuda del módulo random debemos importar random
2 # y nos muestra la documentación completa del módulo random
3
4 import random
5 help(random)
6
Chooses k unique random elements from a population sequence or set.

Returns a new list containing elements from the population while


leaving the original population unchanged. The resulting list is
in selection order so that all sub-slices will also be valid random
samples. This allows raffle winners (the sample) to be partitioned
into grand prize and second place winners (the subslices).

Members of the population need not be hashable or unique. If the


population contains repeats, then each occurrence is a possible
selection in the sample.

To choose a sample in a range of integers, use range as an argument.


This is especially fast and space efficient for sampling from a
large population: sample(range(10000000), 60)

seed(a=None, version=2) method of Random instance


Initialize internal state from hashable object.

None or no argument seeds from current time or from an operating


t ifi d if il bl
In [22]: 1 # genera un número aleatorio con dsitribución uniforme
2 np.random.rand()
3

Out[22]: 0.6482488570713822

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 20/32
4/1/2021 03_Cap_NumerosAleatorios

In [23]: 1 # Generamos otro número aleatorio con distribución normal


2 lista=np.random.randn(100)
3 lista
4 #lista.plot.area()
5 dfl =pd.DataFrame({'X1':lista})
6 dfl.head()
7 x1.plot.hist()
8

Out[23]: <matplotlib.axes._subplots.AxesSubplot at 0x1d14ab33be0>

In [24]: 1 # generamos un arreglo de 5 números aleatorios distribución uniforme


2
3 np.random.rand(5)

Out[24]: array([0.52480589, 0.47801364, 0.56811539, 0.3635772 , 0.28420988])

In [25]: 1 # generamos una matriz de números aleatorios de 2 filas y 4 columnas


2 np.random.rand(2,4)
3

Out[25]: array([[0.70656049, 0.9610001 , 0.96418141, 0.38559339],


[0.93244932, 0.6778016 , 0.62711745, 0.09130302]])

Inicialización del generador de números mediante el método


ramdom.seed().
Aún cuando no es obligatorio, se sugiere utilizar este método para inicializar el generador de
números aleatorios.

Ejemplo:

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 21/32
4/1/2021 03_Cap_NumerosAleatorios

In [26]: 1 import random


2 # primer número generado con la misma semilla
3 random.seed(10)
4 print(random.random())
5 print("Observamos como el nuevo numero generado va a ser igual")
6 # segundo número generado con la misma semilla
7 random.seed(10)
8 print(random.random())
9

0.5714025946899135
Observamos como el nuevo numero generado va a ser igual
0.5714025946899135

Igual forma utilizando Random de numpy

In [27]: 1 # podemos cambiar la semilla de la secuencia de # aleatorios generados


2 np.random.seed(100)
3 x = np.random.rand(50)
4 df = pd.DataFrame({'Xn': x})
5 df.head()
6

Out[27]:
Xn

0 0.543405

1 0.278369

2 0.424518

3 0.844776

4 0.004719

In [28]: 1 df.plot()

Out[28]: <matplotlib.axes._subplots.AxesSubplot at 0x1d14a2ebfd0>

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 22/32
4/1/2021 03_Cap_NumerosAleatorios

los dos secuencias de numeros aleatorios es la misma igual que el grafico

1 # Serie 2
2 np.random.seed(100)
3 y = np.random.rand(61)
4 print(y)
5 dfy = pd.DataFrame({'Yn': y})
6 dfy

In [29]: 1 # Graficamos la serie 2 que va a ser igua a la primera


2
3 dfy.plot()
4

---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-29-dd2c4b9847ee> in <module>
1 # Graficamos la serie 2 que va a ser igua a la primera
2
----> 3 dfy.plot()

NameError: name 'dfy' is not defined

Obtención de un número entero aleatorio dentro de un rango


random.randint().
Generará un número aleatorio que va dentro del rango ingresado.

In [ ]: 1 # generamos 10 números aleatorios con size=10 y los numeros entre 1 y 10


2 np.random.randint(10, size=10)
3

3.4 Test de números aleatorios


Una cuestión clave para un proyecto de simulación es saber si la secuencia de números aleatorios
es suficientemente aleatoria. Como vemos en los generadores y gráficos anteriores que una
secuencia aleatoria en función de su apariencia no es suficiente para determinar si un nùmero
generado es aleatorio", la realidad nos dice que antes de que realmente se use en simulación
identifiquemos al generador, sus parámetros y que al menos se haya realizado alguna prueba que
a continuación lo desarrollaremos.

**"Ninguna cantidad de pruebas puede probar que un GNA dado sea perfect
o".**

Prueba de frecuencia en bloques


El enfoque de esta prueba es la proporción de ** 1 ** dentro de bloques de ** m ** bits. El proósito
es determinar si una frecuencia de ** 1 ** dentro de un bloque es aproximadamente m/2, como se
esperaría de la aleatoreidad.
localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 23/32
4/1/2021 03_Cap_NumerosAleatorios
espe a a de a a eato e dad
Parámetros

- m longitud de cda bloque


- n longitud de la lista de datos
- vector lista con la secuencia de bits 1 y 0

Procedimiento

Procedimiento de: Emanuel Garcia (Modelado y Simulación)

In [ ]: 1

Type Markdown and LaTeX: 𝛼2

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 24/32
4/1/2021 03_Cap_NumerosAleatorios

In [30]: 1 # Prueba de Frecuencias en bloques


2
3 import math
4 from scipy.stats import chi2
5 rS
6 lista1=np.array(rS)
7 vector = []
8 # llenamos de 0 y 1
9 for i in range (0,len(lista1)-1):
10 if lista1[i] < lista1[i+1]:
11 vector.append(0)
12 else:
13 vector.append(1)
14 #vector
15 m = 10 # numero de bloques
16 n = len(vector) # longuitud de la lista
17 N = int(n/m) # número de elementos de cada bloque
18
19 blocks = []
20 i = 0
21 while(len(blocks) != N):
22 blocks.append(vector[i:(i+m)])
23 i = i + m
24 sumas = []
25 for i in range(len(blocks)):
26 sumas.append(0)
27 for j in range(len(blocks[i])):
28 sumas[i] = sumas[i] + blocks[i][j]/float(m)
29 x_2 = 0
30 for i in range(N):
31 x_2 = x_2 + math.pow((sumas[i] - .5),2)
32 x_2 = x_2 * 4*m
33 df = m - 1
34 p_value = chi2.cdf(x_2, df)
35 if p_value < 0.01:
36 print ("Test de frecuencia en Bloques: Not Pasa")
37 else:
38 print ("Test de frecuencia en Bloques : Aprobado")
39
40 print ("Valor de P_value es %3f y el de Chi cuadrado es %3f " % (p_value, x_
41 print ("La proporción del bloque de sumas es:")
42
43 titulo = []
44 n=20
45 for i in range(n):
46 titulo.append(float(i))
47
48 print(titulo)
49 print("Sumas")
50 print (sumas)
51

Test de frecuencia en Bloques: Not Pasa


Valor de P_value es 0.000000 y el de Chi cuadrado es 0.000000
La proporción del bloque de sumas es:
[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 1

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 25/32
4/1/2021 03_Cap_NumerosAleatorios

4.0, 15.0, 16.0, 17.0, 18.0, 19.0]


Sumas
[0.5]

3.5 Variables Aleatorias


Una variable aleatoria puede concebirse como un valor numérico que está afectado por el azar.
Dada una variable aleatoria no es posible conocer con certeza el valor que tomará esta al ser
medida o determinada, aunque sí se conoce que existe una distribución de probabilidad asociada
al conjunto de valores posibles. (Wikipedia) Se emplea para nombrar a una función de valor real
definida sobre un espacio muestral, es una función cuyo valor numérico depende del resultado de
un experimento de azar.

Para definir las variables aleatorias Se utiliza letra mayúscula para la variable aleatoria y
minúscula para la función de densidad:

F(x) Función de distribución acumulada de x

f(x) función de densidad de probabilidad (f.d.p) “función de densidad”.

Existen metodos para obtener variables aleatorias:

Método de la transformada inversa


Metodo del rechazo para proposito de este libro vamos a revisar el método de la
transformada inversa

Método de la transformada inversa


Consiste en generar un numero aleatorio comprendido entre 0 y 1, luego identificarlo con la
función de distribución acumulativa F(x), a través de la función inversa obtener el valor de x

1. Sea x el valor de la variable aleatoria y f(x) la función de densidad de probabilidad


2. Obtener la función acumulativa F(x)
𝑥
𝐹(𝑥) = ∫0 𝑓(𝑡)𝑑𝑡
𝐹(𝑥) nos indica el valor del área bajo la curva
Algoritmo

1. Conocer f(x)
2. calcular
𝑥
𝐹(𝑥) = ∫0 𝑓(𝑡)𝑑𝑡
3. Generar un número aleatorio con distribución uniforme U(0,1)
𝐹(𝑥) = 𝑟 𝑟 = 𝐹(𝑥)
4. Identificarlo y aplicar la inversa o
5. 𝑋 = 𝐹 −1𝑟 entre 0 <= 𝐹(𝑥) <= 1
F(x) La función acumulativa indica la probabilidad que la variable aleat
oria tome un valor de x
localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 26/32
4/1/2021 03_Cap_NumerosAleatorios

Ejemplo 1

Generar los valores aleatorios de x con una f.d.p 𝑓(𝑥) = 2𝑥 entre 0 <= 𝑥 <= 1
1. 𝑓(𝑥) = 2𝑥𝑥
2. 𝐹(𝑥) = ∫0 𝑓(𝑡)𝑑𝑡

3. 𝐹(𝑥) = ∫−∞ 𝑓(𝑡)𝑑𝑡 + ∫0 𝑓(𝑡)𝑑𝑡


0 𝑥
4. 𝐹(𝑥) = 𝑡2 | 𝑒𝑛𝑡𝑟𝑒0 − 𝑥

5. 𝐹(𝑥) = 𝑥2

6. Generamos un número aleatorio 𝑟

7. 𝐹(𝑥) = 𝑟 por lo tanto 𝑥2 = 𝑟


8. calculamos la inversa 𝑥 = √𝑟

In [31]: 1 # Ejecución del Algoritmo


2 # Generamos numeros aleatorios por cualquiera de los metodos presentados, pa
3 # de Borland C/C++ xi+1=22695477xi + 1 mod 2^32
4 # en una DataFrame dfMCL
5 # Anexamos la columna de la transformada inversa de $x = √r$, llanadole inv
6 # tomamos los datos del DataFrame
7
8
9
10

In [32]: 1 # probamos que este correcto


2
3 inv_xp = dfMCL[:1]
4 inv_xp
5
6 print(0.021137**1/2)
7 # resultado ok
8

0.0105685

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 27/32
4/1/2021 03_Cap_NumerosAleatorios

In [33]: 1 # Graficamos los numeros


2
3 t1 = dfMCL["ri"]
4 t2 =inv_xp ## dfMCL["inv_xp"]
5
6 x=range(200)
7 plt.figure(figsize=(50,15))
8
9 plt.subplot(131)
10 p1, = plt.plot(x,t1,'r-')
11 plt.xlabel('Secuencia x de números aleatorios')
12 plt.ylabel('ALEATORIOS')
13 plt.title('# ALEATORIOS POR METODO CONGRUENCIAL y TRANSFORMADA INVERSA')
14 #print(t2)
15 #plt.subplot(132)
16 #p2, = plt.plot(x,t2,'b-')
17 #plt.ylabel('ALEATORIOS')
18 #plt.title('# ALEATORIOS POR TRANSFORMADA INVERSA')
19 #plt.show()
20 t2.plot(marker="o")
21

C:\ProgramData\Anaconda3\lib\site-packages\pandas\plotting\_core.py:1001: Use
rWarning: Attempting to set identical left==right results
in singular transformations; automatically expanding.
left=0.0, right=0.0
ax.set_xlim(left, right)

Out[33]: <matplotlib.axes._subplots.AxesSubplot at 0x1d14bf35518>

Ejemplo 2 con la función exponencial

El tiempo entre llegadas t a una instalación se representa con una distribución exponencial con
media
𝐸(𝑡) = 1/λ
unidades de tiempo; es decir,

𝑓(𝑡) = λ𝑒− λ𝑡,𝑡 > 0


Determinar una muestra aleatoria de t a partir de f(t)

La función Acumulada es la siguiente:

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 28/32
4/1/2021 03_Cap_NumerosAleatorios

𝐹(𝑡) = ∫0𝑥 λ𝑒 − λ𝑡𝑑𝑥 = 1 − 𝑒 − λ𝑡,𝑡 > 0;0𝑎𝑡


𝑅 = 𝐹(𝑡) despejar t
𝑡 = −(1/λ)𝑙𝑛(1–𝑅)
(1–𝑅) es el complemento de R “remplazar 𝑙𝑛(1 − 𝑅) por 𝑙𝑛(𝑅)”
𝑡 = −(1/λ)𝑙𝑛(𝑅)
Ejm. λ = 4 clientes x por hora R = 0,9
*T1 = - (1/4) ln (1 – 0,9) = 0,577 *
** t1 = -(1/4) ln (0.9) = 0.0263

tomado Ejemplo Taha, ejercicio 18.3-2

In [35]: 1 # comprobación del caso del libro de taha


2 import math
3 x = (1.0 - 0.9)
4 x1 = 0.9
5
6 lan=-1/4
7
8 print(math.log(x)*lan)
9 print(math.log(x1)*lan)
10
11

0.5756462732485115
0.02634012891445657

In [36]: 1 # Calculamos para los números aleatorios del ejemplo anterior


2 # Landa = 4 clientes por hora
3 landa=4
4 dfexp = dfMCL['ri']
5 # calculamos a todos los elementos la inversa
6 exp_x = dfexp.values*(-1/landa)*np.log(dfexp)
7 # anexamos al Datafram dfMCL
8 dfMCL["exp_x"] = exp_x
9 # Mostramos el resultado
10 dfMCL.head()
11

Out[36]:
Xn ri exp_x

0 90781909 0.021137 0.020380

1 4261128730 0.992121 0.001962

2 705831779 0.164339 0.074192

3 274169216 0.063835 0.043910

4 2841246593 0.661529 0.068336

Type Markdown and LaTeX: 𝛼2

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 29/32
4/1/2021 03_Cap_NumerosAleatorios

In [37]: 1 dfgrafico = dfMCL.filter(items=['ri','inv_x','exp_x'])


2
3 dfgrafico.plot(figsize=(50,15))
4
5

Out[37]: <matplotlib.axes._subplots.AxesSubplot at 0x1d14bf7c8d0>

In [38]: 1 import math


2 x = 0.1
3 lan=-1/4
4
5 print(math.log(x)*lan)
6

0.5756462732485114

3.6 Distribuciones de Frecuencia


Las dos distribuciones importantes para simulación más utilizadas son la Exponencial y la de
Poisson

Distribución de Poisson

la distribución de Poisson es una distribución discreta usadas en simulación donde el área de


oportunidad para la ocurrencia de un evento es grande, si se conoce el número promedio "éxitos"
que ocurren. se utiliza en muchos sistemas de la vida real:

Numeros de defectos de un determinado material


Las inperfecciones de una placa de vidrio
Número de accidentes automovilisticos producidos en una intersección de vehiculos
Número de multas que detecta un radar por día
La llegada de clientes a un sistemas de líneas de espera

Distribución de Poisson

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 30/32
4/1/2021 03_Cap_NumerosAleatorios

Variable aleatoria discreta, la cual con frecuencia resulta útil cuando tratamos con el número de
ocurrencias de un evento durante un intervalo específico de tiempo o espacio.

𝑓(𝑥) = 𝑒− λ λ𝑥 /𝑥!
λ = media o número medio de ocurrencias en un intervalo, Cantidad promedio de "éxitos"
𝑒 = 2.71828..
𝑥 = 𝑛ú𝑚𝑒𝑟𝑜𝑑𝑒𝑜𝑐𝑢𝑟𝑟𝑒𝑛𝑐𝑖𝑎𝑠𝑒𝑛𝑒𝑙𝑖𝑛𝑡𝑒𝑟𝑣𝑎𝑙𝑜0,1,2,3,4,5...𝑣𝑎𝑙𝑜𝑟𝑒𝑠𝑝𝑜𝑠𝑖𝑏𝑙𝑒𝑠𝑑𝑒𝑑𝑒𝑥
𝑓(𝑥) = probabilidad de x ocurrencias en el intervalo
Ejemplo

In [39]: 1 import numpy as np


2 import scipy.stats as stats
3 from scipy.stats import poisson
4 import matplotlib.pyplot as plt
5
6 landa = 5
7 poisson = stats.poisson(landa)
8 x = np.arange(poisson.ppf(0.01), poisson.ppf(0.99))
9
10 fmp = poisson.pmf(x)
11 plt.plot(x,fmp,'--')
12 plt.vlines(x,0,fmp,colors='b',lw=5,alpha=0.5)
13 plt.title('Distribución de Poisson')
14 plt.ylabel('Probabilidad')
15 plt.xlabel('Valores')
16 plt.show()
17

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 31/32
4/1/2021 03_Cap_NumerosAleatorios

In [40]: 1 fmp
2

Out[40]: array([0.03368973, 0.08422434, 0.1403739 , 0.17546737, 0.17546737,


0.14622281, 0.10444486, 0.06527804, 0.03626558, 0.01813279])

In [41]: 1 x

Out[41]: array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.])

localhost:8888/notebooks/LIBRO/03_Cap_NumerosAleatorios.ipynb 32/32

También podría gustarte