lunes, 19 de abril de 2010

RANDOMIZE - RND

El programa juego Solitario, que acompaña Windows, baraja un mazo de cartas. En los juegos de cartas y en la mayoría de los juegos, el resultado es impredecible. Esto es lo que se conoce como juego de azar. Por otro lado, las computadoras son máquinas, y el comportamiento de las máquinas puede ser predecible. Para escribir programas en Visual Basic que le permitan, por ejemplo, simular la tirada de un dado, necesita una función que haga que el comportamiento de la computadora parezca aleatorio. Puede realizar esto mediante la función Rnd(aleatorio). Por ejemplo, ejecute en el procedimiento Form_Click(al pulsar el ratón) el código siguiente en un formulario en blanco.

Private Sub Form_Click()
Cls
Dim I As Integer
For I = 1 To 5
Print Rnd
Next I
End Sub


Y APARECEN IMPRESOS EN EL FORM


Como puede ver, se han generado cinco números entre 0 y 1, cada uno de ellos con seis o siete decimales(decimales es lo que está después del punto). Estos números parecen no seguir una serie: a esto se le suele denomilar aleatorio. Estos números tiene muchas, pero no todas, las propiedades estadísticas que los matemáticos esperarían de los números aleatorios.
Por ejemplo ejecute este código en el evento Form_Click...

Dim Numero
Numero = Rnd * 7
Print Numero

Esto hace que nunca Numero(la variable que contiene Rnd * 7) pueda llegar a 7. Como vio, se presentan muchos decimales, pero puede quitarlos con la sentencia Int. Ejemplo:
Dim Numero
Numero = Int(Rnd * 7) 'Sentencia Int...
Print Numero

Si ejecuta esto en el evento Click de algún formulario, verá que sólo se presentan numeros entre 0 y 6. Para que aparescan 7, hay que hacer esto:
Dim Numero
Numero = Int(Rnd * 7 + 1)
Print Numero

¿Vió el cambio? Sólo le sumé 1 al valor de Numero, ahora si se pueden presentar numeros entre 0 y 7 efectivamente
Cada vez que la computadora procesa una línea que contiene las sentencias Print Rnd aparece un número entre 0 y 1. En teoría, el número puede ser cero, pero nunca puede ser uno.
Es natural pensar que un número con siete cifras decimales es un buen número. Por ejemplo, suponga que desea escribir un programa que sumule el lanzamiento de una moneda. Hay tres posibilidades: puede salir cara, puede salir cruz, o la moneda puede caer de canto(no espere que esto ocurra). Un fragmento que simulará el lanzamiento de una moneda podría ser como el siguiente:

Private Sub Form_Click()
LanzarMoneda = Rnd
Select Case LanzarMoneda
Case Is < 0.5
Print "Cara"
Case 0.5
Print "La moneda esta de canto"
Case Else
Print "Cruz"
End Select
End Sub

Suponga que escribe éste código en un procedimiento Form_Click y lo ejecuta...
Private Sub Form_Load()
'Un simulador de lanzamiento de una moneda
Dim Tiradas As Integer, NumeroDeCaras As Integer
Dim NumeroDeCruces As Integer
Dim Increible As Integer
Dim I As Integer
Dim Resultado As Single
Show
Tiradas = Val(InputBox$("Introduzca el numero de tiradas"))
NumeroDeCaras = 0
NumeroDeCruces = 0
Increible = 0

For I = 1 To Tiradas
Resultado = Rnd
Select Case Resultado
Case Is < 0.5
NumeroDeCaras = NumeroDeCaras + 1
Case 0.5
Print "La moneda es de canto" 'Pueden pasar miles de años
Increible = Increible + 1
Case Else
NumeroDeCruces = NumeroDeCruces + 1
End Select
Next I
Cls

Print "El numero de caras ha sido: "; NumeroDeCaras
Print "el numero de cruces ha sido: "; NumeroDeCruces
If Increible > 0 Then
Print "La moneda ha salido de canto"
End If
End Sub

Ahora ejecute este programa con un número de tiradas diferentes.
Compruebe que el número de caras y el número de cruces es aproximadamente el mismo y que no aparecen monedas de canto. Ahora termine de ejecutar el programa y vuelva a ejecutarlo de nuevo, utilizando el mismo número de tiradas que antes. Si lo hace, observará que obtiene el mismo número de caras y de curces. Esto puede ser un poco extraño para una moneda honesta :) ¿Qué esta pasando?
De hecho, los números que obtiene con la función Rnd son sólo números pseudoaleatorios. Pseudo suele significar falso y acaba de ver uno de los problemas de los números pseudoaleatorios. Cada vez que inicie el programa utilizando números pseudoaleatorios, obtendrá la misma secuencia de números. El programa funciona como si la memoria de la computadora tuviese un libro con estos números, y cada vez que el programa termina, el libro volviese a la página 1.
Necesita una forma de seleccionar la página de inicio cada vez que inicie el programa. Puede realizar esto de varias formas, pero la más fácil es añadir : Randomize.
La sentencia Randomize también puede ser una potente herramienta para depurar. Esto es debido a que en las sentecias Randomize se puede utilizar cualquier expresión númerica. Después de una orden Randomize Número, el programa utilizará siempre la misma sencuecia de números aleatorios.
Para crear números aleatorios realmente(en su mayoría), se suele utilizar la sentencia Randomize junto a la sentencia Timer. Vamos con un ejemplo.
Cree un nuevo projecto. Ahora, añada un control ListBox y un CommandButton al formulario. Deje nos nombres por omisión. En el procedimiento de evento Click del CommandButton, esbribe esto:

Private Sub Command1_Click()
Dim Numero As Integer
Dim Resultado As Variant
Randomize Timer
Numero = (Rnd * 32000) + 1
List1.AddItem Numero
End Sub

Ahora, pulsa varias veces el CommandButton, y verá que los resultados son aleatorios. Termine de ejecutar el programa, y vuela a ejecutarlo de nuevo, verá que ahora los no son tan iguales como en las otras ocaciones.