viernes, 11 de mayo de 2018

Máquina de Galton en Excel

Puede descargar el archivo maquinaGalton.xlsm

La máquina de Galton nos permite ver cómo una distribución binomial tiende a una distribución normal cuando el número de tiradas va creciendo.


La máquina se puede ver en algunos museos de ciencias. También podríamos construirla nosotros con un tablero inclinado con una ranura superior por la que van cayendo bolitas que rebotan en una serie de clavos o pivotes. En cada rebote la bola tiene probabilidad 1/2 de ir hacia la izquierda o hacia la derecha. Esto se repite una y otra vez hasta que al final la bola termina en una cierta posición y cae por un carril que hemos construido con unas tablas verticales para separar unos de otros. Lo que vemos, si lanzamos un gran número de bolitas, es que los carriles de abajo forman una campana de Gauss. La distribución normal se forma como si de un histograma de frecuencias se tratara.

Vamos a construir una máquina de Galton virtual utilizando Excel y una macro que nos permite hacer el trabajo de la iteraciones de una forma rápida.

Hoja1

Primero creamos la macro que hace la que bolita baje rebotando entre los pivotes. En cada movimiento hacia abajo la bola tiene una probabilidad del 50% de ir hacia la izquierda y otro 50% de ir hacia la derecha. Es similar a un árbol binomial.



La macro que hace que la bola baje es la siguiente.

 Sub baja()  
 'árbol binomial de 32 etapas  
 Dim col As Byte  
 Worksheets("Hoja1").Activate  
 Randomize  
 Range("B2:BN68").Font.Bold = False  
 col = 34  
 Cells(2, 34) = "O"  
 Cells(4, 34) = "O"  
 Cells(4, 34).Font.Bold = True  
 For i = 1 To 32  
  If Rnd < 0.5 Then  
   col = col - 1  
  Else  
   col = col + 1  
  End If  
  Cells(i * 2 + 4, col) = "O"  
  Cells(i * 2 + 4, col).Font.Bold = True  
 Next i  
 End Sub  

Hoja2

Creamos un bucle FOR...NEXT que lanza un gran número de bolas, por ejemplo, 1000. De esta forma podemos ver en que columna ha quedado cada una de ellas al realizar el recorrido hacia abajo.

Veamos el código, similar al anterior pero incluyendo el bucle.

 Sub baja2()  
 Call BorraO  
 'árbol binomial de 32 etapas  
 Dim n As Long 'nº de tiradas  
 Dim col As Byte  
 Worksheets("Hoja2").Activate  
 Randomize  
 n = 1000  
 Application.ScreenUpdating = False  
 For j = 1 To n  
  col = 34  
  Cells(2, 34) = "O"  
  Cells(4, 34) = "O"  
  For i = 1 To 32  
   'una forma alternativa de sumar o restar 1 de forma aleatoria  
   col = col + WorksheetFunction.RandBetween(0, 1) * 2 - 1  
   Cells(i * 2 + 4, col) = "O"  
  Next i  
  'anotamos en la fila 99 los resultados  
  Cells(99, col) = Cells(99, col) + 1  
 Next j  
 Application.ScreenUpdating = True  
 End Sub  

Este es un proceso que puede tardar bastante tiempo en función del valor que demos a n. Para intentar reducir el tiempo de proceso podemos incluir al inicio la siguiente línea.

Application.ScreenUpdating = False


Con ella lo que hacemos el anular el envío de refresco a la pantalla de nuestro ordenador. Al final de la macro, dejamos el refresco activado para poder ver el resultado.

Application.ScreenUpdating = True

Veamos el resultado tras lanzar 10.000 veces la bola.



Hoja3

Nos gustaría poder ver la campana de Gauss que se forma con las tiradas. En la Hoja3 hemos creado unas columnas que se van rellenando con las bolas en vertical hasta que la columna más alta llegue a una altura de 30 bolas.


Con algo de imaginación podemos ver el bosquejo de una campana de Gauss. Para que veamos algo que nos recuerde más a la curva de una distribución normal tendríamos que usar muchas más tiradas.

Veamos el código.

 Sub baja3()  
 'árbol binomial de 32 etapas  
 Dim col As Byte  
 Call BorraO  
 Worksheets("Hoja3").Activate  
 Randomize  
 Do  
  col = 34  
  Cells(2, 34) = "O"  
  Cells(4, 34) = "O"  
  For i = 1 To 32  
   If Rnd < 0.5 Then  
    col = col - 1  
   Else  
    col = col + 1  
   End If  
   Cells(i * 2 + 4, col) = "O"  
  Next i  
  Cells(99, col) = Cells(99, col) + 1  
  miMax = Application.WorksheetFunction.Max(Range("Z99:AP99"))  
  Call BorraTri  
  Cells(98 - Cells(99, col), col) = "O"  
 Loop While miMax < 30  
 End Sub  


Hoja4 y Gráfico

En la Hoja4 lo que hacemos es traernos los valores obtenidos en la Hoja2, y presentarlos en forma de columna. Para ello usamos la siguiente expresión en la celda C4.

=INDIRECTO("Hoja2!"&"F99C"&B4*2;0)

Podemos ver aquí un potente uso de la función indirecto que toma valores de otra hoja para trasponerlos.

Con los valores obtenidos hacemos un histograma de frecuencias que se asemeja a una campana de Gauss. La apariencia será tanto mejor cuanto mayor sea el valor de tiradas (n).



1 comentario:

  1. No me canso de comentar su blog este como el otro que es excelente. Muchas gracias por compartir su conocimiento.

    ResponderEliminar