/***********************************************************************
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/
**********************************************************************/
/*
* CromosomaBinario.java
*
* Created on 23 de agosto de 2005, 0:26
*
*/
package keel.Algorithms.Preprocess.Feature_Selection.evolutionary_algorithms;
import org.core.Randomize;
import java.util.Vector;
/**
*
* @author Manuel Chica Serrano
*
* class CromosomaBinario that defines a specificationn of Cromosoma, the internal representation will be a boolean array */
public class CromosomaBinario extends Cromosoma {
/** Creates a new instance of CromosomaBinario
* @param tama is the length of the chromosome */
public CromosomaBinario(int tama) {
super(tama);
}
/** random initialization of a chromosome (two values: 0 or 1)*/
public void initRand(){
for(int i=0; i<tamCromosoma; i++)
rep[i] = Randomize.Randint(0,2);
}
/** this method is used in CHC method.
* initializes a chromosome using a chromosome template and a random initialization
* @param crPlantilla is a chromosome template
* @param ratio is the ratio of random initialization */
public void initPlantilla(Cromosoma crPlantilla, double ratio){
for(int i=0; i<tamCromosoma; i++)
if(Randomize.RandClosed() <= ratio)
rep[i] = crPlantilla.devolverGen(i);
else
rep[i] = Randomize.Randint(0,2);
}
/** return the ith gene of chromosome
@param i is the ith position
@return integer with gene value (0 or 1) */
public int devolverGen(int i){
if(i<0 || i>=tamCromosoma) {
System.err.println("ERROR: Gen i out of chromosome bounds");
System.exit(0);
}
return rep[i];
}
/** modifies the ith value of a gene
@param nuevoValorGen the new value for the gene
@param posGen the position what we want to change (0..tamCromsoma-1) */
public void cambiarGen(int nuevoValorGen, int posGen){
if(posGen<0 || posGen>=rep.length){
System.err.println("ERROR: Gen 'posGen' out of chromosome bounds");
System.exit(0);
}
if(nuevoValorGen!=0 && nuevoValorGen!=1){
System.err.println("ERROR: This is a binary chromosome, therefore it only contains binary values {0,1}");
System.exit(0);
}
rep[posGen] = nuevoValorGen;
}
/** crossover operator. The offsprings must be created before calling method
@param padre2 is a parent
@param hijo1 is the first offspring
@param hijo2 is the second offspring */
public void cruzar(Cromosoma padre2, Cromosoma hijo1, Cromosoma hijo2){
int i, puntoCorte;
if(padre2==null){
System.err.println("ERROR: padre2 doesn't exist");
System.exit(0);
}
/* selects two cut points. it's neccesary to crossover operator */
puntoCorte = Randomize.Randint(0, tamCromosoma);
int vectorAux[] = new int[tamCromosoma];
/* ------------------------------------------ FIRST OFFSPRING -------------------------------------*/
for(i=0; i<puntoCorte; i++) vectorAux[i] = rep[i];
for(i=puntoCorte; i<tamCromosoma; i++) vectorAux[i] = padre2.devolverGen(i);
for(i=0; i<tamCromosoma; i++) hijo1.cambiarGen(vectorAux[i], i);
/* ------------------------------------------ SECOND OFFSPRING -------------------------------------*/
for(i=0; i<puntoCorte; i++) vectorAux[i] = padre2.devolverGen(i);
for(i=puntoCorte; i<tamCromosoma; i++) vectorAux[i] = rep[i];
for(i=0; i<tamCromosoma; i++) hijo2.cambiarGen(vectorAux[i], i);
}
/** uniform crossover operator (HUX)
* If parents are very similar, the crossover operator doesn't apply
@param padre2 is a parent
@param hijo1 is the first offspring
@param hijo2 is the second offspring
@param umbral is the threshold, needed by the operator
@return return true is the crossover operator was succesful, false in other case */
public boolean cruzarHUX(Cromosoma padre2, Cromosoma hijo1, Cromosoma hijo2, int umbral){
Vector v = new Vector();
int i, aux, posACruzar, nGenesACruzar;
if(padre2==null){
System.err.println("ERROR: padre2 doesn't exist");
System.exit(0);
}
/* checks hamming distance */
for(i=0; i<tamCromosoma; i++)
if(rep[i]!=padre2.devolverGen(i))
v.addElement(i);
/* avoiding incest */
if(v.size() < umbral)
return false;
hijo1.copy(this);
hijo2.copy(padre2);
hijo1.setFitness(-1);
hijo2.setFitness(-1);
i = 0;
nGenesACruzar = v.size()/2;
while(i < nGenesACruzar){
/* selects a random value, removing it. Thereby it will not select it again */
posACruzar = ((Integer)v.remove(Randomize.Randint(0,v.size()))).intValue();
/* gene exchange */
aux = hijo1.devolverGen(posACruzar);
hijo1.cambiarGen(hijo2.devolverGen(posACruzar), posACruzar);
hijo2.cambiarGen(aux, posACruzar);
i++;
}
return true;
}
/** binary mutation operator in one point */
public void mutar(){
int puntoAleat = Randomize.Randint(0, tamCromosoma);
if(rep[puntoAleat] == 0) rep[puntoAleat]= 1;
else rep[puntoAleat]= 0;
fitness = -1;
}
/** it prints a chromosome, gene by gene */
public String print(){
String res = new String();
for(int i=0; i<tamCromosoma; i++)
res += String.valueOf(rep[i]);
return res;
}
/** returns a boolean array needed for Leaving One Out, Cross Validation and other methods used in
* Feature Selection Algorithm
@return a boolean array with the selected features */
public boolean[] devolverFeaturesVector(){
boolean featuresVector[];
featuresVector = new boolean[tamCromosoma];
/* converts integer values (0 & 1) to boolean java type (true or false) */
for(int i=0; i<tamCromosoma; i++)
if(rep[i]==1) featuresVector[i]=true;
else featuresVector[i]=false;
return featuresVector;
}
}