Manual de Basic Spectrum 48k.

Capítulo 11

Números aleatorios

Resumen

  • RANDOMIZE
  • RND

Este capítulo trata de la función RND y de la palabra clave RANDOMIZE. Se utilizan ambas en relación con los números aleatorios, por lo que debe tener cuidado en no mezclarlas. Las dos están en la misma tecla (T), habiéndose tenido que abreviar RANDOMIZE en RAND.

En algunas formas, RND es como una función: realiza cálculos y da lugar a un resultado. No es habitual por cuanto que no necesita un argumento.

Cada vez que la utiliza, su resultado es un nuevo número aleatorio entre 0 y 1 (a veces, puede tomar el valor 0, pero nunca 1).

Pruebe:

10 PRINT RND
20 GO TO 10

para ver cómo varía la respuesta. ¿Puede detectar alguna configuración determinada? No será capaz pues "random" significa que es una función aleatoria.

Realmente, RND no es verdaderamente aleatoria, porque sigue una secuencia fija de 65536 números. Sin embargo, es tan profundamente complicada la secuencia que no se tienen pautas obvias y por ello diremos que RND es pseudoaleatoria.

RND da un número aleatorio entre 0 y 1, pero fácilmente puede obtener números aleatorios en otros intervalos. Por ejemplo, 5 * RND está entre 0 y 5 y 1.3 + 0.7 * RND está entre 1.3 y 2. Para obtener números enteros, utilice INT (recordando que INT siempre se redondea por defecto) como en 1 + INT (RND * 6) que utilizaremos en un programa para simular dados. RND * 6 está en el intervalo de 0 a 6, pero puesto que nunca llega realmente a 6, INT (RND * 6) es 0, 1, 2, 3, 4 ó 5.

Veamos el programa:

10 REM programa de tirada de dados
20 CLS
30 FOR n = 1 TO 2
40 PRINT 1 + INT (RND * 6);" ";
50 NEXT n
60 INPUT A$: GO TO 20

Pulse ENTER cada vez que quiera tirar los dados.

La sentencia RANDOMIZE se utiliza para hacer que RND comience en un lugar definido en su secuencia de números, como puede ver con el programa siguiente:
10 RANDOMIZE 1
20 FOR n = 1 TO 5: PRINT RND,: NEXT n
30 PRINT: GO TO 10

Después de cada ejecución de RANDOMIZE 1, la secuencia RND vuelve a iniciarse con 0.0022735596. Puede utilizar otros números entre 1 y 65535 en la sentencia RANDOMIZE para comenzar la secuencia RND en lugares diferentes.

Si tuviera un programa con RND en el mismo y también tuviera algunos errores que no hubiera encontrado, entonces sería de utilidad el empleo de RANDOMIZE como tal, de modo que el programa se comportara de la misma forma cada vez que lo ejecutara.

RANDOMIZE por sí misma (y RANDOMIZE 0 tiene el mismo efecto) es diferente, porque realmente hace la función de aleatorizar RND. Puede constatarlo en el programa siguiente:

10 RANDOMIZE
20 PRINT RND: GO TO 10

La secuencia que consigue en este caso no es muy aleatoria, porque RANDOMIZE utiliza el tiempo desde que se puso en servicio el ordenador. Puesto que esto se produce en la misma magnitud cada vez que se ejecuta RANDOMIZE, la siguiente RND hace más o menos lo mismo. Conseguiría un efecto más aleatorio sustituyendo GO TO 10 por GO TO 20.

Observación: La mayoría de las versiones de BASIC utilizan RND y RANDOMIZE para obtener números aleatorios, pero no todas las utilizan de la misma manera.

Veamos un programa para lanzar monedas y contar los números de caras y cruces.

10 LET caras = 0: LET cruces = 0
20 LET moneda = INT (RND * 2)
30 IF moneda = 0 THEN LET caras = caras + 1
40 IF moneda = 1 THEN LET cruces = cruces + 1
50 PRINT caras;",";cruces
60 IF cruces <> 0 THEN PRINT caras / cruces;
70 PRINT: GO TO 20

La relación caras/cruces debe llegar a ser aproximadamente 1 si prosigue durante un período de tiempo suficientemente largo, porque, a largo plazo, debe esperar igual número de caras que de cruces.

Ejercicios

  1. Pruebe esta regla:

    Supongamos que elige un número entre 1 y 872 y teclee:

    RANDOMIZE su número

    Entonces, el siguiente valor de RND será:

    (75 * (su número + 1) -1) / 65536
  2. (Para matemáticos solamente)

    Sea p un número primo (grande) y sea a una raíz primitiva de módulo p.

    Entonces, si Bi es el resultado de Ai módulo p (1 =< Bi =< p - 1), la secuencia:

    Bi - 1
    --------
     p - 1

    es una secuencia cíclica de p - 1 números distintos en el intervalo 0 a 1 (excluyendo 1). Eligiendo a adecuadamente, estos números pueden aparecer como bastante aleatorios.

    65537 es un primo de Fermat, 2 16 + 1. Habida cuenta de que el grupo multiplicativo de resto distinto de no cero del módulo 65537 tiene una potencia de 2 como su orden, un resto es una raíz primitiva si, y solamente si, no es un resto cuadrático. Utilice la ley de Gauss de reciprocidad cuadrática para demostrar que 75 es una raíz primitiva módulo 65537.

    El ZX Spectrum utiliza p = 65537 y a = 75 y almacena algunos valores Bi - 1 en memoria. RND obliga la sustitución de Bi - 1 en memoria por Bi + 1 - 1 y proporciona el resultado (Bi + 1 - 1), (p - 1). RANDOMIZE n (con 1 < n < 65535) hace Bi igual a n + 1.

    RND está casi uniformemente distribuida en el intervalo 0 a 1.


Manual de Basic Spectrum 48k.