Dada una serie de datos (X, Y) donde X no se repite, se busca la expresión Y = F(X) que genere esa serie de datos.
El algoritmo es el siguiente:
1. Generar una ecuación al azar del tipo Y=a*SENO(b*X+c) + d*SENO(e*X+f) + ...... + p*SENO(q*X+r). Dónde a, b, c, d, e, f, ....p, q, r son valores aleatorios.
2. Con esa ecuación dar origen a N valores (X, Y). X no debe repetirse.
3. Normalizar los valores (X, Y). Multiplicarlos luego por 1000 y truncar para que sean enteros, finalmente restarle 500 (para que queden valores positivos y negativos). Ese será los datos a buscarle un patrón. Se eliminan los valores X, Y donde X esté repetido.
4. Generar un arreglo bidimensional de M columnas * N filas (la N del punto 2).
5. Cada columna de ese arreglo bidimensional representa una ecuación del tipo Y = s*COSENO(t*X+u). Dónde s, t, u son valores aleatorios. Con esa ecuación, se llenan las N filas donde la parte de X debe ser el mismo que usado en el punto 2. Cada valor se multiplica por 100 y se trunca para que sean enteros.
6. Un individuo es un arreglo unidimensional, donde cada casilla es un valor aleatorio entre 0 y M (la M del punto 4). Por ejemplo: 7, 2, 8, 1, 3, 0, 2, 4, 0, 3
7. Cada valor del arreglo unidimensional del individuo representa una columna del arreglo bidimensional.
8. Se procede a sumar cada columna que señala el individuo. Siguiendo el ejemplo anterior, habría que sumar los valores de cada fila de las columnas 7, 2, 8, 1, 3, 0, 2, 4, 0, 3
9. Se compara el resultado (diferencia absoluta) de cada suma con cada dato Y del ambiente. Se acumulan esas diferencias.
10. Se cambia en forma aleatoria algún valor del arreglo unidimensional del individuo, repite los puntos 8 en adelante. Si el acumulado es menor se mantiene el cambio, en caso contrario se retorna al valor anterior del arreglo bidimensional.
11. Después de ejecutar por lo menos decena de miles de veces los puntos 8 a 10, se habrá obtenido un individuo (arreglo unidimensional) cercano al ambiente. Aquí una serie de ejemplos donde se generan ambientes (línea azul) y luego se muestra el mejor individuo (línea naranja):
Conclusiones:
Este algoritmo ha mostrado un buen ajuste y una buena velocidad. Faltaría optimizarlo y probarlo con datos reales de tipo cíclico.
¿Y la colaboración? Como el individuo es una serie de sumas (y el orden de los sumandos no altera el resultado), abre las puertas a poder usar el operador cruce entre dos o más individuos, aumentando la variedad.
Descargue el programa en C# dando clic aquí.