/***********************************************************************
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/
**********************************************************************/
/**
* <p>
* @author Written by Salvador Garcia (University of Jaén) 12/09/2009
* @version 0.1
* @since JDK1.5
* </p>
*/
package keel.Algorithms.Hyperrectangles.EHS_CHC;
import org.core.*;
import java.util.Arrays;
import java.util.Vector;
public class Cromosoma implements Comparable {
/*Cromosome data structure*/
boolean cuerpo[];
/*Useless data for cromosomes*/
double calidad;
boolean cruzado;
boolean valido;
double errorRate;
public double cover;
/*Construct a random cromosome of specified size(OK)*/
public Cromosoma (int size) {
double u;
int i;
cuerpo = new boolean[size];
for (i=0; i<size; i++) {
u = Randomize.Rand();
if (u < 0.5) {
cuerpo[i] = false;
} else {
cuerpo[i] = true;
}
}
cruzado = true;
valido = true;
cover=0.0;
}
/*Create a copied cromosome (OK)*/
public Cromosoma (int size, Cromosoma a) {
int i;
cuerpo = new boolean[size];
for (i=0; i<cuerpo.length; i++)
cuerpo[i] = a.getGen(i);
calidad = a.getCalidad();
cruzado = false;
valido = true;
cover=a.cover;
}
/*Cronstruct a cromosome from a bit array (OK)*/
public Cromosoma (boolean datos[]) {
int i;
cuerpo = new boolean[datos.length];
for (i=0; i<datos.length; i++)
cuerpo[i] = datos[i];
cruzado = true;
valido = true;
}
/*OK*/
public boolean getGen (int indice) {
return cuerpo[indice];
}
/*OK*/
public boolean [] getBody () {
return cuerpo;
}
/*OK*/
public double getCalidad () {
return calidad;
}
/*OK*/
public void setGen (int indice, boolean valor) {
cuerpo[indice] = valor;
}
/*Function that evaluates a cromosome (OK)*/
public void evalua (double datos[][], int nominal[][], boolean missing[][], int clases[], Hyper database[], double distans[][],double alfa, int nClases, double beta) {
int i, j;
int aciertos = 0;
double M, T, s;
int vecinoCercano;
double dist, minDist;
double minVolume, volume;
int dimensions, pos;
int cover = 0;
Vector <Integer> cand_rules = new Vector <Integer> ();
M = (double)datos.length;
T = (double)database.length;
s = (double)genesActivos();
for (i=0; i<datos.length; i++) {
vecinoCercano = -1;
minDist = Double.POSITIVE_INFINITY;
cand_rules.removeAllElements();
for (j=0; j<database.length; j++) {
if (cuerpo[j]) { //It is in S
if(distans[j][i]>0)
dist=distans[j][i];
else{
dist = EHS_CHC.distancia(database[j],datos[i], nominal[i], missing[i]);
distans[j][i]=dist;
}
if (dist > 0) {
if (dist < minDist) {
minDist = dist;
vecinoCercano = j;
}
} else {
dimensions = database[j].dimensions();
if (dimensions > 0) {
minDist = 0;
cand_rules.add(j);
}
}
}
}
if (minDist > 0) {
if (vecinoCercano >= 0) {
if (clases[i] == database[vecinoCercano].clase)
aciertos++;
}
} else {
minVolume = database[cand_rules.elementAt(0)].volume();
pos = 0;
for (j=1; j<cand_rules.size(); j++) {
volume = database[cand_rules.elementAt(j)].volume();
if (volume < minVolume) {
pos = j;
minVolume = volume;
}
}
if (clases[i] == database[cand_rules.elementAt(pos)].clase)
aciertos++;
cover++;
}
}
calidad = ((double)(aciertos)/M)*alfa*100.0;
calidad += ((1.0 - alfa) * 100.0 * (T - s) / T);
calidad = calidad*beta;
calidad += (1.0 - beta) * 100.0 * ((double)(cover)/M);
cruzado = false;
}
/*Function that does the mutation (OK)*/
public void mutacion (double pMutacion1to0, double pMutacion0to1) {
int i;
for (i=0; i<cuerpo.length; i++) {
if (cuerpo[i]) {
if (Randomize.Rand() < pMutacion1to0) {
cuerpo[i] = false;
cruzado = true;
}
} else {
if (Randomize.Rand() < pMutacion0to1) {
cuerpo[i] = true;
cruzado = true;
}
}
}
}
/*Function that does the CHC diverge*/
public void divergeCHC (double r, Cromosoma mejor, double prob) {
int i;
for (i=0; i<cuerpo.length; i++) {
if (Randomize.Rand() < r) {
if (Randomize.Rand() < prob) {
cuerpo[i] = true;
} else {
cuerpo[i] = false;
}
} else {
cuerpo[i] = mejor.getGen(i);
}
}
cruzado = true;
}
/*OK*/
public boolean estaEvaluado () {
return !cruzado;
}
/*OK*/
public int genesActivos () {
int i, suma = 0;
for (i=0; i<cuerpo.length; i++) {
if (cuerpo[i]) suma++;
}
return suma;
}
/*OK*/
public boolean esValido () {
return valido;
}
/*OK*/
public void borrar () {
valido = false;
}
/*Function that lets compare cromosomes to sort easily (OK)*/
public int compareTo (Object o1) {
if (this.calidad > ((Cromosoma)o1).calidad)
return -1;
else if (this.calidad < ((Cromosoma)o1).calidad)
return 1;
else return 0;
}
/*Function that inform about if a cromosome is different only in a bit, obtain the
position of this bit. In case of have more differences, it returns -1 (OK)*/
public int differenceAtOne (Cromosoma a) {
int i;
int cont = 0, pos = -1;
for (i=0; i<cuerpo.length && cont < 2; i++)
if (cuerpo[i] != a.getGen(i)) {
pos = i;
cont++;
}
if (cont >= 2)
return -1;
else return pos;
}
/*OK*/
public String toString() {
int i;
String temp = "[";
for (i=0; i<cuerpo.length; i++)
if (cuerpo[i])
temp += "1";
else
temp += "0";
temp += ", " + String.valueOf(calidad) + "," + String.valueOf(errorRate) + ", " + String.valueOf(genesActivos()) + "]";
return temp;
}
}