Generación de Números Aleatorios
Una parte fundamental con el trabajo de algoritmos genéticos es la generación de números al azar que son usados para crear los algoritmos y mutarlos.
Como estoy programando en Visual C++ 6.0, he usado la función rand( ) con que viene este lenguaje. Debo tener en cuenta que un generador de números pseudo-aleatorios (porque no es azar puro) debe ser inicializado apropiadamente y tiene un periodo: la secuencia de números pseudo-aleatorios se repite después de N números generados, el objetivo es tener un N muy grande.
Para la inicialización, la semilla es seleccionada según la hora exacta de la máquina y para evitar períodos cortos, cada cierto número de veces de generación o mutación de algoritmos genéticos, vuelve y se inicializa la semilla con otro valor (hora exacta de la máquina en segundos).
Sin embargo, como tengo un nuevo PC y algoritmo rápidos, al tratar de inicializar la semilla con la hora exacta de la máquina me topé con el problema que no pasaba ni un solo segundo entre inicializaciones, por lo tanto, el generador de números pseudo-aleatorios siempre arrancaba con la misma secuencia (algo que no es recomendable en simulación). Forcé que el tiempo entre inicializaciones al menos fuera de un segundo pero eso hizo que el algoritmo se tornara lento. Cambié la inicialización usando como semilla un numero generado al azar por el mismo generador. Sin embargo, esta idea no me gustó porque no se si hay una distribución uniforme estadística en la generación de los números pseudo-aleatorios y tampoco se el tamaño del periodo.
Buscando generadores de números aleatorios
En Internet me topé con variados algoritmos para la generación de números pseudo-aleatorios. Uno me llamó particularmente la atención: el MT19937 de Makoto Matsumoto y Takuji Nishimura, es un algoritmo de libre uso (GNU), tiene un período muy largo: 2^19937 y ha pasado las pruebas mas fuertes en distribución uniforme y según se lee en su página Web es más rápido que la función rand ( ) de Visual C++ 6.0.
El MT19937 es también conocido como un generador "Mersenne Twister".
¿Por que usar períodos muy largos?
El nuevo motor requiere generar 10 números pseudo-aleatorios por cada instrucción del algoritmo genético, si cada algoritmo genético tiene como máximo 150 instrucciones, se requieren 10*150 = 1500 números pseudo-aleatorios, si la simulación generara 10 millones de algoritmos genéticos, requeriría de 15.000 millones. Es decir un período sería excelente si superara los 15.000 millones o 2^34, y el algoritmo MT19937 supera dramáticamente esta cifra.
Para la siguiente actualización, el nuevo motor tendrá este generador de números pseudo-aleatorios.