/*********************************************************************** 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 Albert Orriols (La Salle, Ram�n Llull University - Barcelona) 28/03/2004 * @author Modified by Xavi Sol� (La Salle, Ram�n Llull University - Barcelona) 03/12/2008 * @version 1.1 * @since JDK1.2 * </p> */ package keel.Algorithms.Genetic_Rule_Learning.XCS; import keel.Algorithms.Genetic_Rule_Learning.XCS.KeelParser.Config; import java.util.*; import java.lang.*; import java.io.*; public class IntegerRep implements Attribute{ /** * <p> * This class represents the integer representation of a gene. It works as described * in the XCSI article (see Wilson 2000) * </p> */ /** * <p> * Represents the lower bound of the representation. * </p> */ private int lowerBound; /** * <p> * Represents the upper bound of the representation. * </p> */ private int upperBound; /** * <p> * It is a constant that contains the lower limit of the integer * representation (minimum value of the attribute). * </p> */ private int minimumValue = 0; /** * <p> * It is a constant that contains the upper limit of the integer * representation (maximum value of the attribute). * </p> */ private int maximumValue = 9; /////////////////////////////////////// // associations /** */ private IntegerMutation integerMutation; /////////////////////////////////////// // operations /** * <p> * Does create a Integer representation for de environmental value given as a parameter * </p> * @param env is the environmental attribute state */ public IntegerRep (double env, int i){ minimumValue = (int)Config.attBounds[i][0]; maximumValue = (int)Config.attBounds[i][1]; double scale = maximumValue - minimumValue + 1; if (env == -1.){ double interval = Config.attBounds[i][0] + (Config.attBounds[i][1] - Config.attBounds[i][0])/2; lowerBound = (int) Math.round ((float) (interval - Config.rand() * Config.r_0) * scale); upperBound = (int) Math.round ((float) (interval + Config.rand() * Config.r_0) * scale); } else{ lowerBound = (int) Math.round ((float) (env - Config.rand() * Config.r_0 * scale)); upperBound = ((int) Math.round ((float) (env + Config.rand() * Config.r_0 * scale))); } if (lowerBound < minimumValue) lowerBound = minimumValue; if (upperBound > maximumValue) upperBound = maximumValue; // A new mutation operator is declared if (Config.typeOfMutation.toLowerCase().equals("niched")){ integerMutation = new INichedMutation(); } else{ integerMutation = new IFreeMutation(); } }//end IntegerRep /** * <p> * It is the default constructor of the class. * </p> * @param lValue is the under value to be set. * @param rValue is the upper value to be set. * @param i is the position of the attribute. */ public IntegerRep(int lValue, int rValue, int i) { minimumValue = (int)Config.attBounds[i][0]; maximumValue = (int)Config.attBounds[i][1]; if (lValue >= minimumValue) lowerBound = lValue; else lowerBound = minimumValue; if (rValue <= maximumValue) upperBound = rValue; else upperBound = maximumValue; if (Config.typeOfMutation.toLowerCase().equals("niched")){ integerMutation = new INichedMutation(); } else{ integerMutation = new IFreeMutation(); } } // end IntegerRep /** * <p> * It is the constructor of the class. It initializes the lower and upper bound values. * </p> * @param lValue is the lower bound value. * @param rValue is the upper bound value. */ public IntegerRep(int lValue, int rValue,int udLimit, int upLimit){ minimumValue = udLimit; maximumValue = upLimit; if (lValue >= minimumValue) lowerBound = lValue; else lowerBound = minimumValue; if (rValue <= maximumValue) upperBound = rValue; else upperBound = maximumValue; if (Config.typeOfMutation.toLowerCase().equals("niched")){ integerMutation = new INichedMutation(); } else{ integerMutation = new IFreeMutation(); } } // end IntegerRep /** * <p> * It is a constructor for the class. It clones the realRep * object passed as a parameter. * @param r is the real representation that has to be copied in the constructor. */ public IntegerRep(Attribute r) { lowerBound = ((IntegerRep)r).lowerBound; upperBound = ((IntegerRep)r).upperBound; minimumValue = ((IntegerRep)r).minimumValue; maximumValue = ((IntegerRep)r).maximumValue; if (Config.typeOfMutation.toLowerCase().equals("niched")){ integerMutation = new INichedMutation(); } else{ integerMutation = new IFreeMutation(); } } // end IntegerRep /** * <p> * Sets the lower and upper values. * </p> * @param lValue is the lower bound value. * @param rValue is the upper bound value. */ public void setAllele(double lValue, double rValue) { if ((int)lValue >= minimumValue) lowerBound = (int)lValue; else lowerBound = minimumValue; if ((int)rValue <= maximumValue) upperBound = (int)rValue; else upperBound = maximumValue; } // end setAllele /** * <p> * Sets the lower and upper values. * </p> * @param r is the realRep of the classifier that has to be copied. */ public void setAllele(Attribute r) { lowerBound = ((IntegerRep)r).lowerBound; upperBound = ((IntegerRep)r).upperBound; minimumValue = ((IntegerRep)r).minimumValue; maximumValue = ((IntegerRep)r).maximumValue; } // end setAllele /** * <p> * Returns the value of the alelle * </p> * @return a 2RealRep with the two reals numbers of the representation. */ public Attribute getAttributeAllele() { return this; } // end getAllele /** * <p> * Returns the lower real value of the representation * </p> * @return a int with the lower value. */ public double getLowerAllele() { return (double)lowerBound; } // end getLowerAllele /** * <p> * Returns the upper real value of the representation * </p> * @return a int with the upper value. */ public double getUpperAllele() { return (double)upperBound; } // end getUpperAllele /** * <p> * It returns the generality of the allele. * </p> * @return a double with the generality of this allele. */ public double getGenerality() { return ((double)(upperBound - lowerBound + 1)) / ((double)(maximumValue - minimumValue + 1)); } // end getGenerality /** * <p> * Verifies if the interval is correct (if the upper value * is greather or equal than the lower value). If it isn't, it * interchanges its values. * </p> */ public void verifyInterval(){ if (lowerBound > upperBound){ int aux = upperBound; upperBound = lowerBound; lowerBound = aux; } }//end verifyInterval /** * <p> * If the random number that is generated is less than the specify probability * (parameter in the Config), the interval is specified with * an uniform distribution [0..l_0] * </p> * @param env is the environment. */ public void makeSpecify (double env){ double scale = maximumValue - minimumValue + 1; if (Config.rand() <= Config.Pspecify ){ lowerBound += (int)((double)Config.rand() * Config.l_0 * scale); if (lowerBound > (int)env && env != -1.) lowerBound = (int)env; } if (Config.rand() <= Config.Pspecify ){ upperBound -= (int)((double)Config.rand() * Config.l_0 * scale); if (upperBound < (int)env && env != -1.) upperBound = (int)env; } }//end makeSpecify /** * <p> * Muates the 2 reals contained in the representation. * </p> */ public void mutate(double currentState) { lowerBound = integerMutation.mutateLower(lowerBound,upperBound, (int)currentState, (maximumValue-minimumValue+1)); upperBound = integerMutation.mutateUpper(lowerBound,upperBound,(int)currentState, (maximumValue-minimumValue+1)); if (lowerBound < minimumValue) lowerBound = minimumValue; else if (lowerBound > maximumValue) lowerBound = maximumValue; if (upperBound > maximumValue) upperBound = maximumValue; else if (upperBound < minimumValue) upperBound = minimumValue; if (lowerBound > upperBound) swapAlleles(); } // end mutate /** * <p> * Swaps the allele values. * </p> */ private void swapAlleles(){ int tmp = upperBound; upperBound = lowerBound; lowerBound = tmp; }//end swapAlleles /** * <p> * Returns true if the allele matches with the environment * </p> * @param env is the value of the environment. * @return a boolean indicating if the allele matches with the environmental value. */ public boolean match (double env){ if (env == -1.) return true; if (lowerBound > (int)env || upperBound < (int)env) return false; return true; } // end match /** * <p> * Returns true if the current representation allele subsumes the representation allele passed as a parameter * </p> * @param r is the integer representation of the subsumer classifier. * @return a boolean indicating if the allele is subsumed. */ public boolean subsumes (Attribute r){ if (lowerBound <= ((IntegerRep)r).lowerBound && upperBound >= ((IntegerRep)r).upperBound) return true; return false; } // end subsumes /** * <p> * Return true if the allele matches with the environment * </p> * @param r is the integer representation of the other classifier. * @return a boolean indicating if the allele matches with the environmental value. */ public boolean equals (Attribute r){ if (lowerBound == ((IntegerRep)r).lowerBound && upperBound == ((IntegerRep)r).upperBound) return true; return false; } // end equals /** * <p> * Return if the integer of the representation. It's not necessary in integer representation, but it has to * be codified because is defined in the interface. So, it will return the generality of the interval. * is a don't care symbol * </p> * @return an integer that indicates if the character of the representation is a don't care symbol. */ public double isDontCareSymbol(){ return (double)(upperBound - lowerBound); } // end isDontCareSymbol /** * <p> * Returns if the current interval is more general than the interval given as a parameter * </p> * @param r is the real representation of the classifier. * @return a boolean indicating if the current interval is more general. */ public boolean isMoreGeneral(Attribute r){ if (lowerBound <= ((IntegerRep)r).lowerBound && upperBound >= ((IntegerRep)r).upperBound) return true; return false; }//end isMoreGeneral /** * <p> * This methods prints the attribute bounds * </p> */ public void print(){ System.out.print ("; "+lowerBound+", "+ upperBound); }//end print /** * <p> * This method prints to the attribute bounds to the specified PrintWriter * </p> * @param out is the PrintWriter where to print the bounds */ public void print (PrintWriter out){ out.print (" "+lowerBound+" "+upperBound+" "); }//end out public double getAllele(){ return 0.0; } public void printNotNorm(PrintWriter fout, Vector conv){ fout.println(" "+((String)conv.elementAt(lowerBound))+" "+((String)conv.elementAt(lowerBound))+" "); } public void printNotNorm(PrintWriter fout, int lo){ fout.print (" "+(lowerBound+lo)+" "+(upperBound+lo)+" "); } public void printNotNorm(PrintWriter fout, double lo, double up){} } // end IntegerRep