/***********************************************************************
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 AG {
public double prob_cruce, prob_mutacion, a, b;
public int Mu_next, Trials;
public double Best_current_perf;
public int Best_guy;
public int long_poblacion, n_variables, n_genes;
public int cruces_simples, cruces_mma;
public int[] sample;
public int last;
public Structure[] Old;
public Structure[] New;
public Structure[] C;
public Structure[] temp;
public Adap fun_adap;
public AG(int n_poblacion, int n_var, double cruce, double mutacion,
double valor_a, double valor_b, Adap funcion) {
int i;
fun_adap = funcion;
n_variables = n_var;
long_poblacion = n_poblacion;
prob_cruce = cruce;
a = valor_a;
b = valor_b;
n_genes = 4 * n_variables;
prob_mutacion = mutacion / (double) n_genes;
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);
}
C = new Structure[4];
for (i = 0; i < 4; i++) {
C[i] = new Structure(n_genes);
}
}
private int ceil(double v) {
int valor;
valor = (int) Math.round(v);
if ( (double) valor < v) {
valor++;
}
return (valor);
}
/** Inicialization of the population */
public void Initialize(BaseR base_reglas, BaseD base_datos, MiDataset tabla) {
int i, j, k, tercio_pob, final_grupo1_2, etiqueta, pos_etiq;
double grado_pertenencia, max_pert;
int[] seleccionados = new int[ceil(long_poblacion / 3.0)];
int[] indices_nc = new int[tabla.long_tabla];
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 (i = j = 0; i < tabla.no_cubiertos && j < tabla.long_tabla; j++) {
if (tabla.datos[j].cubierto == 0) {
indices_nc[i] = j;
i++;
}
}
/* Random selection of the examples. If there are under the necessary all examples are selected */
tercio_pob = ceil(long_poblacion / 3.0);
/* if there aren't suficient, all examples are used */
if (tabla.no_cubiertos <= tercio_pob) {
final_grupo1_2 = tabla.no_cubiertos;
for (i = 0; i < tabla.no_cubiertos; i++) {
seleccionados[i] = indices_nc[i];
}
}
/* if there are suficient, the examples are randomly selected */
else {
final_grupo1_2 = tercio_pob;
for (i = 0; i < tercio_pob; i++) {
seleccionados[i] = indices_nc[Randomize.RandintClosed(0,
tabla.no_cubiertos - 1)];
}
}
/* Generation of the chromosomes */
for (i = 0; i < final_grupo1_2; i++) {
for (j = 0; j < n_variables; j++) {
/* Determination of the better label for each variable */
max_pert = 0.0;
etiqueta = 0;
pos_etiq = tabla.n_variables + 3 * j;
for (k = 0; k < base_datos.n_etiquetas[j]; k++) {
grado_pertenencia = base_reglas.Fuzzifica(tabla.datos[seleccionados[i]].
ejemplo[j], base_datos.BaseDatos[j][k]);
if (grado_pertenencia > max_pert) {
max_pert = grado_pertenencia;
etiqueta = k;
}
}
/* Group 1 */
New[i].Gene[j] = (double) etiqueta;
New[i].Gene[pos_etiq] = base_datos.BaseDatos[j][etiqueta].x0;
New[i].Gene[pos_etiq + 1] = base_datos.BaseDatos[j][etiqueta].x1;
New[i].Gene[pos_etiq + 2] = base_datos.BaseDatos[j][etiqueta].x3;
/* Group 2 */
New[final_grupo1_2 + i].Gene[j] = (double) etiqueta;
for (k = 0; k < 3; k++) {
New[final_grupo1_2 + i].Gene[pos_etiq +
k] = Randomize.Randdouble(base_datos.intervalos[j][etiqueta][k].
min,
base_datos.intervalos[j][etiqueta][k].
max);
}
}
New[i].n_e = 1;
New[final_grupo1_2 + i].n_e = 1;
}
/* Group 3 */
for (i = 2 * final_grupo1_2; i < long_poblacion; i++) {
for (j = 0; j < tabla.n_variables; j++) {
etiqueta = Randomize.RandintClosed(0, base_datos.n_etiquetas[j] - 1);
pos_etiq = tabla.n_variables + 3 * j;
New[i].Gene[j] = etiqueta;
for (k = 0; k < 3; k++) {
New[i].Gene[pos_etiq +
k] = Randomize.Randdouble(base_datos.intervalos[j][etiqueta][k].
min,
base_datos.intervalos[j][etiqueta][k].
max);
}
}
New[i].n_e = 1;
}
}
public void Intercambio() {
temp = Old;
Old = New;
New = temp;
}
/* 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].Perf = Old[k].Perf;
New[i].n_e = 0;
}
}
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 */
void Cruce_MMA_Simple(int n_variables) {
int mom, dad, misma_regla, variable, etiqueta, xpoint1, i, j, intercambio;
int[] indice = new int[4];
double temp1, temp2, temp;
cruces_simples = cruces_mma = 0;
for (mom = 0; mom < last; mom += 2) {
dad = mom + 1;
/* we prove if dad and mom are the same rule */
misma_regla = 1;
i = 0;
while (i < n_variables && misma_regla == 1) {
if (New[dad].Gene[i] != New[mom].Gene[i]) {
misma_regla = 0;
}
else {
i++;
}
}
/* Max-Min-Aritmetical */
if (misma_regla == 1) {
/* we increment the number of the Max-Min-Aritmetical crossover */
cruces_mma++;
/* we calculate the variable and the label */
variable = -1;
for (i = n_variables; i < n_genes; i++) {
temp1 = New[mom].Gene[i];
temp2 = New[dad].Gene[i];
/* we obtain 4 offsprings: appling the t-norma, the
t-conorma and 2 the average function */
C[0].Gene[i] = T_producto_logico(temp1, temp2);
C[1].Gene[i] = S_suma_logica(temp1, temp2);
C[2].Gene[i] = Promedio1(temp1, temp2, a);
C[3].Gene[i] = Promedio1(temp1, temp2, 1.0 - a);
}
/* Evaluation of the 4 offsprings */
C[0].Perf = fun_adap.eval(C[0].Gene);
C[1].Perf = fun_adap.eval(C[1].Gene);
C[2].Perf = fun_adap.eval(C[2].Gene);
C[3].Perf = fun_adap.eval(C[3].Gene);
/* we order the offsprings by means of the bubble method */
for (i = 0; i < 4; i++) {
indice[i] = i;
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 3 - i; j++) {
if (C[indice[j + 1]].Perf > C[indice[j]].Perf) {
intercambio = indice[j];
indice[j] = indice[j + 1];
indice[j + 1] = intercambio;
}
}
}
for (i = 0; i < n_genes; i++) {
New[mom].Gene[i] = C[indice[0]].Gene[i];
New[dad].Gene[i] = C[indice[1]].Gene[i];
}
/* we update the fitness of the offsprings */
New[mom].Perf = C[indice[0]].Perf;
New[dad].Perf = C[indice[1]].Perf;
New[mom].n_e = 0;
New[dad].n_e = 0;
Trials += 4;
}
/* Simple Crossover */
else {
/* we increment the number of simple crossover */
cruces_simples++;
/* we calculate the crossing point in the first part of the chromosome */
xpoint1 = Randomize.RandintClosed(1, n_variables - 1);
/* we cross both part out of a this point */
for (i = xpoint1; i < n_variables; i++) {
temp = New[mom].Gene[i];
New[mom].Gene[i] = New[dad].Gene[i];
New[dad].Gene[i] = temp;
for (j = 0; j < 3; j++) {
temp = New[mom].Gene[n_variables + 3 * i + j];
New[mom].Gene[n_variables + 3 * i + j] = New[dad].Gene[n_variables +
3 * i + j];
New[dad].Gene[n_variables + 3 * i + j] = temp;
}
}
New[mom].n_e = 1;
New[dad].n_e = 1;
}
}
}
private double delta(long t, double y, long n_generaciones) {
double r, potencia, subtotal, sub;
r = Randomize.Rand();
sub = 1.0 - (double) t / (double) n_generaciones;
potencia = Math.pow(sub, (double) b);
subtotal = Math.pow(r, potencia);
return (y * (1.0 - subtotal));
}
/** Uniform Non Mutation */
public void Mutacion_Thrift_No_Uniforme(long Gen, long n_generaciones,
BaseD base_datos) {
int posiciones, i, j, variable, etiqueta, punto;
double nval, 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;
m = Randomize.Rand();
/* the gene is of C1 */
if (j < base_datos.n_variables) {
/* if I'm in the fisrt label */
if ( (m < 0.5 &&
(New[i].Gene[j] != (double) base_datos.n_etiquetas[j] - 1)) ||
New[i].Gene[j] == 0.0) {
nval = New[i].Gene[j] + 1.0;
}
else {
nval = New[i].Gene[j] - 1.0;
}
/* we update the membership function */
variable = j;
etiqueta = (int) nval;
New[i].Gene[base_datos.n_variables +
3 * variable] = base_datos.BaseDatos[variable][etiqueta].x0;
New[i].Gene[base_datos.n_variables + 3 * variable +
1] = base_datos.BaseDatos[variable][etiqueta].x1;
New[i].Gene[base_datos.n_variables + 3 * variable +
2] = base_datos.BaseDatos[variable][etiqueta].x3;
}
/* else the gene is of C2 */
else {
/* we calculate the variable and label of the gene */
variable = (int) (j - base_datos.n_variables) / 3;
etiqueta = (int) New[i].Gene[variable];
punto = (j - base_datos.n_variables) % 3;
/* we mutate the gene */
if (m < 0.5) {
nval = New[i].Gene[j] +
delta(Gen,
base_datos.intervalos[variable][etiqueta][punto].max -
New[i].Gene[j], n_generaciones);
}
else {
nval = New[i].Gene[j] -
delta(Gen,
New[i].Gene[j] -
base_datos.intervalos[variable][etiqueta][punto].min,
n_generaciones);
}
}
New[i].Gene[j] = nval;
New[i].n_e = 1;
/* we calculate the next position */
if (prob_mutacion < 1) {
m = Randomize.Rand();
Mu_next += (int) (Math.log(m) / Math.log(1.0 - prob_mutacion));
Mu_next++;
}
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);
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]) {
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].Perf = Old[Best_guy].Perf;
New[long_poblacion - 1].n_e = 0;
}
}
/** Returns the best solution*/
public double[] solucion() {
return (New[Best_guy].Gene);
}
/** Returns the fitness of the best solution */
public double solucion_ec() {
return (New[Best_guy].Perf);
}
/** Solution to String */
public String SoluciontoString() {
int i, pos_etiq;
String cadena;
cadena = "";
for (i = 0; i < n_variables; i++) {
pos_etiq = n_variables + 3 * i;
cadena += " " + New[Best_guy].Gene[pos_etiq] + " " +
New[Best_guy].Gene[pos_etiq + 1] + " " + New[Best_guy].Gene[pos_etiq +
2] + "\n";
}
return (cadena);
}
}