/*********************************************************************** This file is part of KEEL-software, the Data Mining tool for regression, classification, clustering, pattern mining and so on. Copyright (C) 2004-2010 J. Alcal�-Fdez (jalcala@decsai.ugr.es) A. Fern�ndez (alberto.fernandez@ujaen.es) S. Garc�a (sglopez@ujaen.es) F. Herrera (herrera@decsai.ugr.es) L. S�nchez (luciano@uniovi.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/ **********************************************************************/ /** * * File: BinaryCHC.java * * A binary implementation of the CHC algorithm, for the IS population * * @author Written by Joaqu�n Derrac (University of Granada) 13/1/2010 * @version 1.0 * @since JDK1.5 * */ package keel.Algorithms.Coevolution.CIW_NN; import java.util.Arrays; import org.core.Randomize; class BinaryCHC { private static int evals; private static int sizePop; private static int threshold; private static int initialThreshold; private static double alpha; private static double prob0to1R; /** * Set threshold for the CHC restart * * @param value Threshold */ public static void setThreshold(int value){ initialThreshold=value; threshold=value; } /** * Sets alpha value * * @param value Alpha value */ public static void setAlpha(double value){ alpha=value; } /** * Sets prob0to1 probability on restart * * @param value Probability to set */ public static void setprob0to1R(double value){ prob0to1R=value; } /** * Performs a generation of the CHC algorithm * * @param population IS population * * @return Evaluations spent */ public static int generation(ChromosomeIS [] population){ ChromosomeIS newPopulation []; boolean nuevos=false; double value; evals=0; sizePop=population.length; //baraje de la poblacion newPopulation=shuffle(population); //Cruce for(int i=0;i<sizePop;i+=2){ if(hamming(newPopulation[i].getAll(),newPopulation[i+1].getAll())/2>threshold){ //cruce HUXCross(newPopulation,i,i+1); //evaluacion value=evaluateFitness(newPopulation[i]); newPopulation[i].setFitness(value); value=evaluateFitness(newPopulation[i+1]); newPopulation[i+1].setFitness(value); nuevos=true; } } //Seleccion selectiva if(nuevos){ nuevos=mergePop(population,newPopulation); } //reinicicializacion if(nuevos==false){ threshold--; if(threshold==0){ //generar for(int i=1; i<sizePop;i++){ population[i]=population[0].clone(); } //mutar for(int i=1; i<sizePop;i++){ for(int j=0;j<ChromosomeIS.getSize();j++){ if(Randomize.Rand()<0.35){ if(Randomize.Rand()<prob0to1R){ population[i].set(j,1); } else{ population[i].set(j,0); } } } population[i].setFitness(-1.0); } //evaluar for(int i=1; i<sizePop;i++){ value=evaluateFitness(population[i]); population[i].setFitness(value); } //ordenar Arrays.sort(population); threshold=initialThreshold; } } return evals; } /** * Merges two population * * @param population Old population * @param newPopulation New population * * @return True if any new chromosome has been acepted. False, if not */ private static boolean mergePop(ChromosomeIS [] population,ChromosomeIS [] newPopulation){ int index=0; int taken=0; boolean used=false; double bestFitness; int bestPosition; ChromosomeIS [] finalPop=new ChromosomeIS [sizePop]; bestFitness=-1; bestPosition=-1; for(int i=0;i<newPopulation.length;i++){ if(newPopulation[i].getFitness()>bestFitness){ bestFitness=newPopulation[i].getFitness(); bestPosition=i; } } while(taken<sizePop){ if(population[index].getFitness()>bestFitness){ finalPop[taken]=population[index].clone(); index++; } else{ finalPop[taken]=newPopulation[bestPosition].clone(); newPopulation[bestPosition].setFitness(-1.0); bestFitness=-1; bestPosition=-1; for(int i=0;i<newPopulation.length;i++){ if(newPopulation[i].getFitness()>bestFitness){ bestFitness=newPopulation[i].getFitness(); bestPosition=i; } } used=true; } taken++; } System.arraycopy(finalPop, 0, population, 0, sizePop); return used; } /** * Computes hamming distance * * @param a First array * @param b Second array * * @return Hamming distance */ private static int hamming (int a[],int b[]){ int dist=0; for(int i=0;i<a.length;i++){ if(a[i]!=b[i]){ dist++; } } return dist; } /** * Shuffles the population * * @param population IS population * * @return Shuffled population */ private static ChromosomeIS [] shuffle(ChromosomeIS [] population){ int index[]=new int [sizePop]; int pos,tmp; ChromosomeIS clon []= new ChromosomeIS [sizePop]; for (int i=0; i<sizePop; i++){ index[i] = i; } for (int i=0; i<sizePop; i++) { pos = Randomize.Randint (0, sizePop); tmp = index[i]; index[i] = index[pos]; index[pos] = tmp; } for (int i=0; i<sizePop; i++) { clon[i]=population[index[i]].clone(); } return clon; } /** * Fitnes function * * @param a Chromosome to evaluate * * @return Fitness value */ private static double evaluateFitness(ChromosomeIS a){ double value,acc,red; WKNN.setInstances(a.getAll()); acc=WKNN.accuracy(); evals++; red=a.computeRed(); value=(alpha*acc)+((1.0-alpha)*red); return value; } /** * HUX crossing operator * * @param population Is population * @param a First chromosome * @param b Second chromosome */ private static void HUXCross(ChromosomeIS population [],int a,int b){ population[b]=population[a].HUX(population[b]); } } //end-class