/***********************************************************************
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_Postprocess.MamWSelect;
import java.lang.Math;
import org.core.*;
class AG {
public double prob_cruce, prob_mutacion;
public double MMA_a = 0.35;
public int Mu_next, Trials;
public double Best_current_perf;
public int Best_guy;
public int long_poblacion, n_genes;
public int [] sample;
public int last;
public Structure [] Old;
public Structure [] New;
public Structure [] temp;
public Adap fun_adap;
public char [][] regla_son;
public double [][] peso_son;
public Structure [] son;
public AG (int n_poblacion, int genes, double cruce, double mutacion, Adap funcion) {
int i;
long_poblacion = n_poblacion;
n_genes = genes;
prob_cruce = cruce;
prob_mutacion = mutacion / (double) n_genes;
fun_adap = funcion;
sample = new int[long_poblacion];
Old = new Structure[long_poblacion];
New = new Structure[long_poblacion];
for (i=0; i<long_poblacion; i++) {
Old[i] = new Structure(n_genes);
New[i] = new Structure(n_genes);
}
regla_son = new char[2][n_genes];
peso_son = new double[4][n_genes];
son = new Structure[8];
for (i=0; i<8; i++) son[i] = new Structure(n_genes);
}
private int ceil (double v) {
int valor;
valor = (int) Math.round(v);
if ((double)valor < v) valor++;
return (valor);
}
public void Intercambio () {
temp=Old;
Old=New;
New=temp;
}
/** Inicialization of the population */
public void Initialize (BaseR base_total) {
int i, j;
last = (int) ((prob_cruce * long_poblacion) - 0.5);
Trials = 0;
if (prob_mutacion < 1.0)
Mu_next = ceil (Math.log(Randomize.Rand()) / Math.log(1.0 - prob_mutacion));
else Mu_next = 1;
for (j=0; j<n_genes; j++) {
New[0].Gene[j] = '1';
if (base_total.cpeso == 1) New[0].GeneR[j] = base_total.BaseP[j];
else New[0].GeneR[j] = 1.0;
}
New[0].n_e = 1;
for (i=1; i < long_poblacion; i++) {
for (j=0; j<n_genes; j++) {
if (Randomize.RandintClosed(0,1) == 0) New[i].Gene[j] = '0';
else New[i].Gene[j] = '1';
New[i].GeneR[j] = Randomize.Randdouble(0.0, 1.0);
}
New[i].n_e = 1;
}
}
/* Selection based on the Baker's Estocastic Universal Sampling */
void Select() {
double expected, factor, perf, ptr, sum, rank_max, rank_min;
int i, j, k, best, temp;
rank_min = 0.75;
/* we assign the ranking to each element:
The best: ranking = long_poblacion-1
The worse: ranking = 0 */
for (i=0; i<long_poblacion; i++) Old[i].n_e = 0;
/* we look for the best ordered non element */
for (i=0; i<long_poblacion-1; i++) {
best = -1;
perf = 0.0;
for (j=0; j<long_poblacion; j++) {
if ((Old[j].n_e==0) && (best==-1 || Old[j].Perf < perf)) {
perf = Old[j].Perf;
best = j;
}
}
/* we assign the ranking */
Old[best].n_e = long_poblacion - 1 - i;
}
/* we normalize the ranking */
rank_max = 2.0 - rank_min;
factor = (rank_max-rank_min)/(double)(long_poblacion-1);
/* we assign the number of replicas of each chormosome according to the select probability */
k = 0;
ptr = Randomize.Rand ();
for (sum = i = 0; i<long_poblacion; i++) {
expected = rank_min + Old[i].n_e * factor;
for (sum += expected; sum>=ptr; ptr++) sample[k++] = i;
}
/* we complete the population if necessary */
if (k != long_poblacion) {
for (;k<long_poblacion; k++) sample[k] = Randomize.RandintClosed (0, long_poblacion-1);
}
/* we shuffle the selected chromosomes */
for (i=0; i<long_poblacion; i++) {
j = Randomize.RandintClosed (i, long_poblacion-1);
temp = sample[j];
sample[j] = sample[i];
sample[i] = temp;
}
/* we create the new population */
for (i=0; i<long_poblacion; i++) {
k = sample[i];
for (j=0; j<n_genes; j++) {
New[i].Gene[j] = Old[k].Gene[j];
New[i].GeneR[j] = Old[k].GeneR[j];
}
New[i].Perf = Old[k].Perf;
New[i].n_e = 0;
}
}
/* Multipoint Crossover in two points */
void Cruce_Multipunto () {
int mom, dad, xpoint1, xpoint2, i, j;
char temp;
for (mom=0; mom<last; mom+=2) {
dad = mom+1;
/* we select 2 points */
xpoint1 = Randomize.RandintClosed (0,n_genes-1);
if (xpoint1 != n_genes-1)
xpoint2 = Randomize.RandintClosed (xpoint1 + 1, n_genes - 1);
else xpoint2 = n_genes - 1;
/* we cross the individuals between xpoint1 and xpoint2 */
for (i=xpoint1; i<=xpoint2; i++) {
temp = New[mom].Gene[i];
New[mom].Gene[i] = New[dad].Gene[i];
New[dad].Gene[i] = temp;
}
New[mom].n_e = 1;
New[dad].n_e = 1;
}
}
/* Crossover operator in 2 point */
public void Cruce_2P (char [] dad1, char [] dad2) {
int i, j, xpoint1, xpoint2, tmp_int;
/* we select 2 points */
xpoint1 = Randomize.RandintClosed(0,n_genes-1);
do
xpoint2 = Randomize.RandintClosed(0,n_genes-1);
while (xpoint2 == xpoint1);
if (xpoint2 < xpoint1) {
tmp_int = xpoint2;
xpoint2 = xpoint1;
xpoint1 = tmp_int;
}
/* we cross the parts */
for (i=0; i<xpoint1; i++) {
regla_son[0][i] = dad1[i];
regla_son[1][i] = dad2[i];
}
for (i=xpoint1; i<=xpoint2; i++) {
regla_son[0][i] = dad2[i];
regla_son[1][i] = dad1[i];
}
for (i=xpoint2+1; i<n_genes; i++) {
regla_son[0][i] = dad1[i];
regla_son[1][i] = dad2[i];
}
}
private double T_producto_logico (double x ,double y) {
if (x<y) return (x);
else return (y);
}
private double S_suma_logica (double x ,double y) {
if (x>y) return (x);
else return (y);
}
private double Promedio1 (double x, double y, double p) {
return (p*x + (1-p)*y);
}
/* Max-Min-Aritmetical Crossover */
void Cruce_MMA (double [] dad1, double [] dad2) {
int i, j;
/* we obtain 4 offsprings: appling the t-norma, the
t-conorma and 2 the average function */
for (i=0; i<n_genes; i++) {
peso_son[0][i] = T_producto_logico (dad1[i], dad2[i]);
peso_son[1][i] = S_suma_logica (dad1[i], dad2[i]);
peso_son[2][i] = Promedio1 (dad1[i], dad2[i], MMA_a);
peso_son[3][i] = Promedio1 (dad1[i], dad2[i], 1.0 - MMA_a);
}
}
/* Crossover Operator */
void Cruce () {
int dad1, dad2, l, i, j, k, n, tmp;
int [] indice = new int[8];
for (i=0; i<last; i+=2) {
dad1 = i;
dad2 = i+1;
Cruce_2P (New[dad1].Gene, New[dad2].Gene);
Cruce_MMA (New[dad1].GeneR, New[dad2].GeneR);
/* 8 offsprings (2x4) */
for (l=k=0; l<2; l++)
for (j=0; j<4; j++,k++) {
for (n=0; n<n_genes; n++) {
son[k].Gene[n] = regla_son[l][n];
son[k].GeneR[n] = peso_son[j][n];
}
}
/* evaluation of the offsprings */
for (l=0; l<8; l++) {
son[l].Perf = fun_adap.eval(son[l].Gene, son[l].GeneR);
indice[l] = l;
}
/* Selection of the 2 best*/
for (l=0; l<8; l++)
for (j=0; j<7-l; j++)
if (son[indice[j+1]].Perf < son[indice[j]].Perf) {
tmp = indice[j];
indice[j] = indice[j+1];
indice[j+1] = tmp;
}
for (n=0; n<n_genes; n++) {
New[dad1].Gene[n] = son[indice[0]].Gene[n];
New[dad2].Gene[n] = son[indice[1]].Gene[n];
New[dad1].GeneR[n] = son[indice[0]].GeneR[n];
New[dad2].GeneR[n] = son[indice[1]].GeneR[n];
}
New[dad1].Perf = son[indice[0]].Perf;
New[dad1].n_e = 0;
New[dad2].Perf = son[indice[1]].Perf;
New[dad2].n_e = 0;
}
}
/* Uniform Mutation */
void Mutacion_Uniforme () {
int posiciones, i, j;
double m;
posiciones = n_genes * long_poblacion;
if (prob_mutacion>0) {
while (Mu_next<posiciones) {
/* we determinate the chromosome and the gene */
i = Mu_next / n_genes;
j = Mu_next % n_genes;
/* we mutate the gene */
if (New[i].Gene[j]=='0') New[i].Gene[j]='1';
else New[i].Gene[j]='0';
/* we mutate the rule's weight */
New[i].GeneR[j]= Randomize.Randdouble(0.0,1.0);
New[i].n_e=1;
/* we calculate the next position */
if (prob_mutacion<1) {
m = Randomize.Rand();
Mu_next += ceil (Math.log(m) / Math.log(1.0 - prob_mutacion));
}
else Mu_next += 1;
}
}
Mu_next -= posiciones;
}
/** Fitness Function */
void Evaluate() {
double performance;
int i, j;
for (i=0; i<long_poblacion; i++) {
/* if the chromosome aren't evaluated, it's evaluate */
if (New[i].n_e == 1) {
New[i].Perf = fun_adap.eval (New[i].Gene, New[i].GeneR);
performance = New[i].Perf;
New[i].n_e = 0;
Trials++; /* we increment the number of evaluated chromosomes */
}
else performance = New[i].Perf;
/* we calculate the position of the best individual */
if (i == 0) {
Best_current_perf = performance;
Best_guy = 0;
}
else if (performance < Best_current_perf) {
Best_current_perf = performance;
Best_guy = i;
}
}
}
/* Elitist selection */
void Elitist () {
int i, k, found;
/* if the best individual of the old population aren't in the new population, we remplace the last individual for this */
for (i=0, found=0; i<long_poblacion && (found==0); i++)
for (k=0, found=1; (k<n_genes) && (found==1); k++)
if ((New[i].Gene[k] != Old[Best_guy].Gene[k]) || (New[i].GeneR[k] != Old[Best_guy].GeneR[k]))
found = 0;
if (found == 0) {
for (k=0; k<n_genes; k++) {
New[long_poblacion-1].Gene[k] = Old[Best_guy].Gene[k];
New[long_poblacion-1].GeneR[k] = Old[Best_guy].GeneR[k];
}
New[long_poblacion-1].Perf = Old[Best_guy].Perf;
New[long_poblacion-1].n_e = 0;
}
}
/** Returns the best solution*/
public char [] solucion () {
return (New[Best_guy].Gene);
}
/** Returns the weights of the best solution */
public double [] solucionR () {
return (New[Best_guy].GeneR);
}
/** Returns the fitness of the best solution */
public double solucion_ec () {
return (New[Best_guy].Perf);
}
}