/*********************************************************************** 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 University Ram�n Lull, Barcelona) 28/03/2004 * @author Modified by Xavi Sol� (La Salle University Ram�n Lull, Barcelona) 03/12/2008 * @version 1.1 * @since JDK1.2 * </p> */ package keel.Algorithms.Genetic_Rule_Learning.UCS; import java.util.*; import java.lang.*; import java.io.*; public class RealRep implements Attribute{ /** * <p> * This class implements the Lower-Upper Bound Representation, i.e., an attribute is represented by * [l_i, u_i]. If some operator modifies the interval limits so that l_i > u_i, then, both bounds are swapped. * </p> */ /** * Represents the lower bound of the representation. */ private double lowerBound; /** * Represents the upper bound of the representation. */ private double upperBound; /** * It is a constant that contains the lower limit of the real * representation. */ private final int minimumValue = 0; /** * It is a constant that contains the upper limit of the real * representation. */ private final int maximumValue = 1; /** * A reference to the mutation operator. */ private RealMutation realMutation; /** * Default constructor of the class. */ public RealRep() { if (Config.typeOfMutation.toLowerCase().equals("niched")){ realMutation = new RNichedMutation(); } else{ realMutation = new RFreeMutation(); } } // end RealRep /** * <p> * Does construct a real representation allele from the environmental state * </p> * @param env is the environmental attribute state */ public RealRep ( double env ) { if (env == -1.){ lowerBound = 0.5 - Config.rand() * Config.r_0; upperBound = 0.5 + Config.rand() * Config.r_0; } else{ lowerBound = env - Config.rand() * Config.r_0; upperBound = env + Config.rand() * Config.r_0; } if ( lowerBound < minimumValue ) lowerBound = minimumValue; if ( upperBound > maximumValue ) upperBound = maximumValue; // A new mutation operator is declared if ( Config.typeOfMutation.toLowerCase().equals("niched") ){ realMutation = new RNichedMutation(); } else{ realMutation = new RFreeMutation(); } } // end RealRep /** * <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 RealRep(double lValue, double rValue) { if ( lValue >= minimumValue ) lowerBound = lValue; else lowerBound = minimumValue; if ( rValue <= maximumValue ) upperBound = rValue; else upperBound = maximumValue; if (Config.typeOfMutation.toLowerCase().equals("niched")){ realMutation = new RNichedMutation(); } else{ realMutation = new RFreeMutation(); } }//end RealRep /** * <p> * It's a constructor for the class. It clones the realRep * object passed as a parameter. * </p> * @param r is the real representation that has to be copied in the constructor. */ public RealRep( Attribute r ) { lowerBound = ((RealRep)r).lowerBound; upperBound = ((RealRep)r).upperBound; if (Config.typeOfMutation.toLowerCase().equals("niched")){ realMutation = new RNichedMutation(); }//end RealRep else{ realMutation = new RFreeMutation(); } } // end RealRep /** * <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 (lValue >= minimumValue) lowerBound = lValue; else lowerBound = minimumValue; if (rValue <= maximumValue) upperBound = 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 = ((RealRep)r).lowerBound; upperBound = ((RealRep)r).upperBound; }//end setAllele /** * <p> * Returns the lower real value of the representation * </p> * @return a double with the lower value. */ public double getLowerAllele() { return lowerBound; } // end getLowerAllele /** * <p> * Returns the upper real value of the representation * </p> * @return a double with the upper value. */ public double getUpperAllele() { return 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 upperBound - lowerBound; } // end getGenerality /** * <p> * Verifies if the interval is correct (if the upper value * is greater or equal than the lower value). If it is not, it * interchanges its values. * </p> */ public void verifyInterval(){ if (lowerBound > upperBound){ double aux = upperBound; upperBound = lowerBound; lowerBound = aux; } } /** * <p> * If the random number 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 environmental value for this attribute */ public void makeSpecify (double env){ /*if (Config.rand() <= Config.Pspecify ){ lowerBound += Config.rand() * Config.l_0; if (lowerBound > env && env != -1.) lowerBound = env; } if (Config.rand() <= Config.Pspecify ){ upperBound -= Config.rand() * Config.l_0; if (upperBound < env && env != -1.) upperBound = env; }*/ }// end makeSpecify /** * <p> * Mutates the 2 reals contained in the representation. * </p> */ public void mutate(double currentState) { double tmp = 0.0; lowerBound = realMutation.mutateLower(lowerBound,upperBound,currentState); if (lowerBound < minimumValue) lowerBound = minimumValue; if (lowerBound > upperBound) swapAlleles(); if (upperBound > maximumValue) upperBound = maximumValue; upperBound = realMutation.mutateUpper(lowerBound,upperBound,currentState); if (upperBound > maximumValue) upperBound = maximumValue; if (upperBound < lowerBound) swapAlleles(); if (lowerBound < minimumValue) lowerBound = minimumValue; } // end mutate /** * <p> * Swaps the allele values. * </p> */ private void swapAlleles(){ double tmp = upperBound; upperBound = lowerBound; lowerBound = tmp; } /** * <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 > env || upperBound <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 real representation of the subsumer classifier. * @return a boolean indicating if the allele is subsumed. */ public boolean subsumes (Attribute r){ if (lowerBound <= ((RealRep)r).lowerBound && upperBound >= ((RealRep)r).upperBound) return true; return false; } // end subumes /** * <p> * Returns true if the allele matches with the environment * </p> * @param r is the real representation of the other classifier. * @return a boolean indicating if the allele matches with the environmental value. */ public boolean equals (Attribute r){ if (lowerBound == ((RealRep)r).lowerBound && upperBound == ((RealRep)r).upperBound) return true; return false; } // end equals /** * <p> * Returns if the real representation is a don't care symbol. It's not necessary in real representation, but it has to * be codified because is defined in the interface. So, it will return the generality of the interval. * </p> * @return a double that indicates if the character of the representation is a don't care symbol. */ public double isDontCareSymbol(){ return (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 it's more general. */ public boolean isMoreGeneral(Attribute r){ if (lowerBound <= ((RealRep)r).lowerBound && upperBound >= ((RealRep)r).upperBound) return true; return false; } public void print(){ String s1 = new Double(lowerBound).toString(); if (s1.length() > 4) s1 = s1.substring(0,4); String s2 = new Double(upperBound).toString(); if (s2.length() > 4) s2 = s2.substring(0,4); System.out.print ("; "+s1+", "+ s2); } public void print ( PrintWriter out ){ out.print (" "+lowerBound+" "+upperBound+" "); } public void printNotNorm(PrintWriter fout, double lo, double up){ double lb = lowerBound * (up-lo) + lo; double ub = upperBound * (up-lo) + lo; fout.print (" "+lb+" "+ub+" "); } public void printNotNorm(PrintWriter fout, double lo){ int a = (int) (lowerBound + lo); int b = (int) (upperBound + lo); fout.print (" "+a+" "+b+" "); } }//end RealRep