/*********************************************************************** This file is part of KEEL-software, the Data Mining tool for regression, classification, clustering, pattern mining and so on. Copyright (C) 2004-2010 F. Herrera (herrera@decsai.ugr.es) L. S�nchez (luciano@uniovi.es) J. Alcal�-Fdez (jalcala@decsai.ugr.es) S. Garc�a (sglopez@ujaen.es) A. Fern�ndez (alberto.fernandez@ujaen.es) J. Luengo (julianlm@decsai.ugr.es) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/ **********************************************************************/ package keel.Algorithms.RE_SL_Methods.mogulSC; import java.lang.Math; import org.core.*; class Est_evol { public double sigma; public int n_gen_ee; public long n_mutaciones, n_exitos; public static double c = 0.9; public BaseD base_datos; public BaseR base_reglas; public Adap fun_adap; public Est_evol(BaseD base_da, BaseR base_re, Adap fun, int n_gen_ee) { this.base_datos = base_da; this.base_reglas = base_re; this.fun_adap = fun; this.n_gen_ee = n_gen_ee; } /** Calculates the new value of sigma according to the number of mutation with hit*/ public double AdaptacionSigma(double old_sigma, double p, double n) { /* if p<1/5, sigma lowers (c<1 -> sigma*c^(1/n)<sigma) */ if (p < 0.2) { return (old_sigma * Math.pow(c, 1.0 / n)); } /* if p>1/5, sigma increases (c<1 -> sigma/c^(1/n)>sigma)*/ if (p > 0.2) { return (old_sigma / Math.pow(c, 1.0 / n)); } /* if p=1/5, sigma doesn't change*/ return (old_sigma); } /** Generates a normal value with hope 0 and tipical deviation "desv */ public double ValorNormal(double desv) { double u1, u2; /* we generate 2 uniform values [0,1] */ u1 = Randomize.Rand(); u2 = Randomize.Rand(); /* we calcules a normal value with the uniform values */ return (desv * Math.sqrt( -2.0 * Math.log(u1)) * Math.sin(2.0 * Math.PI * u2)); } /** Evolution Strategy */ public void Estrategia_Evolucion(Structure Padre, Structure Hijo) { int j, variable, etiqueta, gen, it_sin_exito, fin; double x0, x1, x2, newx1, newx, S, n, new_sigma; /* Inicialization of the counters */ n_mutaciones = n_exitos = it_sin_exito = fin = 0; sigma = new_sigma = 1.0; do { for (variable = 0; variable < base_datos.tabla.n_variables; variable++) { /* we copy the C1 part of the father in the son */ Hijo.Gene[variable] = Padre.Gene[variable]; etiqueta = (int) Padre.Gene[variable]; gen = base_datos.tabla.n_variables + 3 * variable; /* we obtain the fuzzy set */ x0 = Padre.Gene[gen]; x1 = Padre.Gene[gen + 1]; x2 = Padre.Gene[gen + 2]; /* Adaptation of S and mutation of the center point */ S = Adap.Minimo(x1 - x0, x2 - x1) / 2.0; n = ValorNormal(new_sigma * S); newx1 = x1 + n; if (newx1 <= x0) { Hijo.Gene[gen + 1] = x0; newx1 = x0; } else { if (newx1 >= x2) { Hijo.Gene[gen + 1] = x2; newx1 = x2; } else { Hijo.Gene[gen + 1] = newx1; } } /* Adaptation of S and mutation of the left point */ S = Adap.Minimo(x0 - base_datos.intervalos[variable][etiqueta].min, newx1 - x0) / 2.0; n = ValorNormal(new_sigma * S); newx = x0 + n; if (newx <= base_datos.intervalos[variable][etiqueta].min) { Hijo.Gene[gen] = base_datos.intervalos[variable][etiqueta].min; } else { if (newx >= newx1) { Hijo.Gene[gen] = newx1; } else { Hijo.Gene[gen] = newx; } } /* Adaptation of S and mutation of the center right */ S = Adap.Minimo(x2 - newx1, base_datos.intervalos[variable][etiqueta].max - x2) / 2.0; n = ValorNormal(new_sigma * S); newx = x2 + n; if (newx <= newx1) { Hijo.Gene[gen + 2] = newx1; } else { if (newx >= base_datos.intervalos[variable][etiqueta].max) { Hijo.Gene[gen + 2] = base_datos.intervalos[variable][etiqueta].max; } else { Hijo.Gene[gen + 2] = newx; } } } /* we evaluate the son */ Hijo.Perf = fun_adap.eval(Hijo.Gene); /* we count the mutation */ n_mutaciones += 1; /* if the son is better than the father this relieve his father, we accept sigma and we count another hit */ if (Hijo.Perf > Padre.Perf) { n_exitos += 1; it_sin_exito = 0; sigma = new_sigma; for (j = 0; j < base_reglas.n_genes; j++) { Padre.Gene[j] = Hijo.Gene[j]; } Padre.Perf = Hijo.Perf; } else { it_sin_exito++; } /* we adapt sigma */ new_sigma = AdaptacionSigma(sigma, n_exitos / (double) n_mutaciones, (double) base_reglas.n_genes - base_datos.tabla.n_variables); if (it_sin_exito >= n_gen_ee) { fin = 1; } } while (fin == 0); } }