Generador de números pseudoaleatorios

Programa generador de números pseudoaleatorios en Java

¿Qué es un GNA?

Un GNA (Generador de números aleatorios) es un programa que crea números de de forma aleatoria. En informática comúnmente se usan algoritmos pseudoaleatorios, es decir, programas que a partir de una semilla (un número), crea una secuencia de números.

Posiblemente, el algoritmo de números pseudoaleatorios más extendido sea el Congruencial. En este artículo veremos una modificación del mismo. Se generarán 3 congruenciales. El primero servirá para decidir cual de los dos siguientes usar.

Semillas que pasan los tests

Existen varias pruebas o tests para determinar si un algoritmo es pseudoaleatorio. En nuestro ejemplo se han pasado los tests de Frecuencias, Serie, GAP, Yule-Walker, Distancias, Autocorrelación (casi todas las celdas), Kolmogorov, Maxmin-up y Maxmin-down. Por lo que podemos afirmar que es un algoritmo aceptablemente bueno.

A continuación se muestra un conjunto de 5 semillas que pasaron los tests:

c1 = new congruencial(2147483647,8363,13259,45646);
c2 = new congruencial(2147483647,94781,52859528,4420567);
c3 = new congruencial(2147483647,86341,33107542,33107);

c1 = new congruencial(2147483647,2441,19183,437693);
c2 = new congruencial(2147483647,403681,486641,42773);
c3 = new congruencial(2147483647,449851,611549,14087);

c1 = new congruencial(2147483647,2441,19183,437693);
c2 = new congruencial(2147483647,548489,486641,42773);
c3 = new congruencial(2147483647,562753,611549,611953);

c1 = new congruencial(2147483647,376891,19183,437693);
c2 = new congruencial(2147483647,548489,486641,467353);
c3 = new congruencial(2147483647,562753,611549,611953);

c1 = new congruencial(2147483647,3498013,3552463,437693);
c2 = new congruencial(2147483647,4050589,3938927,3722491);
c3 = new congruencial(2147483647,3621617,3574819,3498419);

Programa generador de números pseudoaleatorios en Java

Este programa genera una secuencia de 3000 números pseudoaleatorios. Para obtener distintas tiras de números basta con cambiar las semillas que se han especificado anteriormente.

public class Composite {

    private congruencial c1;
    private congruencial c2;
    private congruencial c3;

    private double [] vector;
    private int index;

    public Composite() {
        index = 0;
        c1 = new congruencial(2147483647,8363,13259,45646);
        c2 = new congruencial(2147483647,94781,52859528,4420567);
        c3 = new congruencial(2147483647,86341,33107542,33107);

        vector = new double[3000];

        for (int i=0; i < vector.length; i++){
            vector[i] = c1.next();
        }
    }
    public double next(){
        if(vector[index] > 0.5){
            return c2.next();
        } else {
            return c3.next();
        }
    }

    public congruencial getC1() {
        return c1;
    }

    public congruencial getC2() {
        return c2;
    }

    public congruencial getC3() {
        return c3;
    }

    class congruencial{
       private int m;
       private int a;
       private int c;
       private int seed;
       private double prev=0;

       public congruencial(int m, int a, int c, int seed){
           this.m = m;
           this.a = a;
           this.c = c;
           this.seed = seed;
       }

       public double next(){
           prev = (a * prev + c )%m;
           return  prev/m;
       }
    }

    public static void main(String [] args){
        Composite composite = new Composite();
        for (int i=0; i < 3000; i++){
            System.out.println(composite.next());
        }
    }
}

Si deseamos usar este algoritmo en otros programas podemos utilizar la función .next() que nos devuelve el siguiente número de la tira generada.