/***********************************************************************
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.mogulHC;
import java.lang.Math;
import org.core.*;
class Est_evol {
public int n_gen_ee;
public int long_poblacion, n_genes;
public long n_mutaciones, n_exitos;
public double porc_pob_ee;
public Structure Hijo;
public Structure[] New;
public Structure[] YaExplotados;
public int[] indices;
public static double PI = 3.1415926;
public static double c = 0.9;
public BaseD base_datos;
public Adap fun_adap;
public Est_evol(BaseD base, Adap fun, AG alg_gen, double porc, int n_iter) {
int i;
fun_adap = fun;
base_datos = base;
New = alg_gen.New;
long_poblacion = alg_gen.long_poblacion;
n_genes = alg_gen.n_genes;
porc_pob_ee = porc;
n_gen_ee = n_iter;
indices = new int[long_poblacion];
Hijo = new Structure(n_genes);
YaExplotados = new Structure[long_poblacion];
for (i = 0; i < long_poblacion; i++) {
YaExplotados[i] = new Structure(n_genes);
}
}
/** 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 * Math.log(u1)) * Math.sin(2 * PI * u2));
}
/** Returns 1 if the current index is in the list of selected indexes */
int Pertenece(Structure C, Structure[] L, int n_explotados) {
int crom, gen, esta;
crom = 0;
while ( (crom < n_explotados) && (L[crom].Perf > C.Perf)) {
esta = 1;
gen = 0;
while (gen < n_genes && esta == 1) {
if (C.Gene[gen] != L[crom].Gene[gen]) {
esta = 0;
}
else {
gen++;
}
}
if (esta == 1) {
return (1);
}
crom++;
}
return (0);
}
/** Evolution Strategy */
public void Estrategia_Evolucion() {
int i, j, temp, cromosoma, variable, etiqueta, punto, it_sin_exito,
n_ya_explotados, n_a_explotar, fin;
double n, sigma, newval, new_sigma, old_perf;
/* we order the population by mean of the bubble method */
for (i = 0; i < long_poblacion; i++) {
indices[i] = i;
}
for (i = 0; i < long_poblacion; i++) {
for (j = 0; j < long_poblacion - i - 1; j++) {
if (New[indices[j + 1]].Perf > New[indices[j]].Perf) {
temp = indices[j];
indices[j] = indices[j + 1];
indices[j + 1] = temp;
}
}
}
/* the evolution strategy is applied to each individual of the population with fitness better than 0 */
i = 0;
n_ya_explotados = 0;
n_a_explotar = (int) (porc_pob_ee * long_poblacion);
while ( (i < long_poblacion) && (n_ya_explotados < n_a_explotar)) {
/* we initialize the index of the chromosome */
cromosoma = indices[i];
/* we store this chromosome in the list of the exploited */
for (j = 0; j < n_genes; j++) {
YaExplotados[n_ya_explotados].Gene[j] = New[cromosoma].Gene[j];
}
YaExplotados[n_ya_explotados].Perf = New[cromosoma].Perf;
n_ya_explotados++;
/* Inicialization of the counters */
n_mutaciones = n_exitos = it_sin_exito = fin = 0;
sigma = new_sigma = 1.0;
do {
/* we copy the C1 part of the father in the son */
for (j = 0; j < base_datos.n_variables; j++) {
Hijo.Gene[j] = New[cromosoma].Gene[j];
}
/* we generate the C2 part of the sons by means of the ES */
variable = -1;
etiqueta = (int) New[cromosoma].Gene[0];
for (j = base_datos.n_variables; j < n_genes; j++) {
punto = (j - base_datos.n_variables) % 3;
if (punto == 0) {
variable++;
etiqueta = (int) New[cromosoma].Gene[variable];
}
/* we generate the normal value with the tipical desviation of each variable */
n = ValorNormal(new_sigma * base_datos.S[variable]);
/* We apply the mutation. If a value is outside mutation interval it is revised */
newval = New[cromosoma].Gene[j] + n;
if (newval <= base_datos.intervalos[variable][etiqueta][punto].min) {
Hijo.Gene[j] = base_datos.intervalos[variable][etiqueta][punto].min;
}
else {
if (newval >= base_datos.intervalos[variable][etiqueta][punto].max) {
Hijo.Gene[j] = base_datos.intervalos[variable][etiqueta][punto].
max;
}
else {
Hijo.Gene[j] = newval;
}
}
}
/* 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 > New[cromosoma].Perf) {
n_exitos += 1;
it_sin_exito = 0;
sigma = new_sigma;
for (j = 0; j < n_genes; j++) {
New[cromosoma].Gene[j] = Hijo.Gene[j];
}
New[cromosoma].Perf = Hijo.Perf;
New[cromosoma].n_e = 0;
}
else {
it_sin_exito++;
}
/* we adapt sigma */
new_sigma = AdaptacionSigma(sigma,
(double) n_exitos / (double) n_mutaciones,
(double) n_genes - base_datos.n_variables);
if (it_sin_exito >= n_gen_ee) {
fin = 1;
}
}
while (fin == 0);
/* we look for the next unrecurrent individual */
if (n_ya_explotados < n_a_explotar) {
do {
i++;
}
while (Pertenece(New[indices[i]], YaExplotados, n_ya_explotados) == 1);
}
}
}
}