/*********************************************************************** 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 Rosa Venzala (University of Granada) 02/06/2008 * @author Modified by Xavi Sol� (La Salle, Ram�n Llull University - Barcelona) 16/12/2008 * @version 1.1 * @since JDK1.2 * </p> */ package keel.Algorithms.Hyperrectangles.EACH; import java.util.LinkedList; import keel.Dataset.*; public class Complex implements Comparable { /** * <p> * This class storages conj. of Selectors * </p> */ private LinkedList compl; private int classAttribute; private int numClasses; private int distrib[]; private double heuristic; private String [] attributeNames; private double weight; private double volume; private int numDimensions; public Complex() { } /** * <p> * Constructor for the complex * </p> * @param nClass int Number of classes */ public Complex(int nClass) { compl = new LinkedList(); //Inicializo la lista numClasses = nClass; //Almaceno el n de clases distrib = new int[nClass]; //Distribucion para las clases for (int i = 0; i < numClasses; i++) { distrib[i] = 0; //Inicializo a 0 } } /** * <p> * Compare two objects of the Complex class * </p> * @param o Object Complex to compare * @return int 0 if are equals (same heuristic and size, -1 if is better (same heuristic less size || * high heuristic) * 1 if is worst (same heuristic, high size || less heuristic). */ public int compareTo(Object o) { Complex c2 = (Complex) o; int out = 0; if (heuristic == c2.getHeuristic() && compl.size() == c2.size()) { out = 0; } else if (heuristic == c2.getHeuristic() && compl.size() < c2.size()) { out = -1; } else if (heuristic == c2.getHeuristic() && compl.size() > c2.size()) { out = 1; } else if (heuristic > c2.getHeuristic()) { out = -1; } else if (heuristic < c2.getHeuristic()) { out = 1; } return (out); } /** * <p> * Check is two complex are equals * </p> * @param c complex to compare * @return boolean True if are equals. False otherwise */ public boolean isEqual(Complex c){ boolean bEquals = false; if (c.size() == compl.size()){ bEquals = true; for (int i = 0; (i < c.size())&&(bEquals); i++){ bEquals = (this.getSelector(i).compareTo(c.getSelector(i)) == 0); } } return bEquals; } /** * <p> * Add the selector to the list * </p> * @param s Selector the selector */ public void addSelector(Selector s) { compl.add(s); } /** * <p> * Remove the selector from the list * </p> * @param s Selector The selector */ public void removeSelector(Selector s) { compl.remove(s); } /** * <p> * Remove the selectors from the list of the selectors that have the parameter attribute * </p>o * @param attribute the attribute */ public void removeSelectorAttribute(int attribute) { Selector s; int atrib; for(int i=0;i<compl.size();i++){ s=(Selector)compl.get(i); atrib=s.getAttribute(); if(atrib==attribute){ compl.remove(s); /*CUIDADO!!!hay q volver al indice anterior pq se ha eliminado un elemento!!*/ i=i-1; } } } /** * <p> * Leaves the list empty * </p> */ public void clear() { compl.clear(); } /** * <p> * Returns the selector in a position given the complex * </p> * @param indice int Podition inside the complex * @return Selector The selector */ public Selector getSelector(int indice) { return (Selector) compl.get(indice); } /** * <p> * Returns the size of the complex * </p> * @return int The number of the selectors that has the complex */ public int size() { return compl.size(); } /** * <p> * Returns the number of classes of the problem * </p> * @return int idem. */ public int getNClases() { return this.numClasses; } /** * Devuelve la clase que define el complejo * @return int la clase */ public int getClassAttribute() { return this.classAttribute; } /** * <p> * Returns the class that defines the comples * </p> */ public void setClassAttribute(int clase) { this.classAttribute = clase; } public void setWeight(double w){ this.weight=w; } public double getWeight(){ return weight; } public void setVolume(double v){ this.volume=v; } public double getVolume(){ return volume; } public void setDimensions(int d){ this.numDimensions=d; } public int getDimensions(){ return numDimensions; } /** * <p> * Calculate the LaPlaces's value for a complex * </p> */ public void computeLaplace() { double nc; double ntot; int i; nc = distrib[classAttribute]; for (i = 0, ntot = 0; i < numClasses; i++) { ntot += distrib[i]; } //heuristica = (ntot - nc + nClases - 1) / (ntot + nClases); heuristic = (nc + 1) / (ntot + numClasses); } /** * <p> * Checks if the rule gets the parameter instance * </p> * @param instance the instance * @return boolean True if the rule gets the instance */ public boolean instanceCoveredByRule(Instance instance){ boolean bCovered=true; double cadena; for (int i = 0; i < this.size()&&bCovered; i++) { Selector s = this.getSelector(i); switch (s.getOperator()) { case 0: // se trata del igual double []valor=s.getValues(); bCovered=false; for (int j = 0; (j < valor.length)&&(!bCovered); j++){ cadena=instance.getInputRealValues(s.getAttribute()); if(cadena==valor[j]) bCovered=true; else bCovered=false; /*int numInputAttributes = Attributes.getInputNumAttributes(); int numOutputAttributes = Attributes.getOutputNumAttributes(); int numUndefinedAttributes = Attributes.getNumAttributes();*/ } break; } } return bCovered; } /** * <p> * Check if the complex gets the given data * </p> * @param m Muestra The example * @return boolean True if gets the example */ public boolean isCovered(Sample m) { boolean cubierto = true; double[] sample = m.getSample(); for (int i = 0; i < this.size() && cubierto; i++) { // recorremos los selectores del complejo Selector s = this.getSelector(i); switch (s.getOperator()) { case 0: // se trata del igual double [] valor = s.getValues(); cubierto = false; //ahora cada selector solo guarda el minimo y maximo //para cuando se trata de una excepcion if(valor.length==1){ if(sample[s.getAttribute()]==valor[0])cubierto=true; } //ahora ya sabemos que valor solo va a tener 2 componentes else{ if( (sample[s.getAttribute()] >= valor[0]) && (sample[s.getAttribute()] <= valor[1])) cubierto=true; } break; case 1: // se trata del distinto cubierto = sample[s.getAttribute()] != s.getZeroValue(); break; case 2: //menor o igual cubierto = sample[s.getAttribute()] <= s.getZeroValue(); break; case 3: //mayor cubierto = sample[s.getAttribute()] > s.getZeroValue(); break; } } return cubierto; } /** * <p> * Returns the heuristic value if the complex * </p> * @return double idem */ public double getHeuristic() { return heuristic; } /** * <p> * Assign a heuristic value(Wracc) to the complex * </p> * @param heu double the heuristic value */ public void setHeuristic(double heu) { heuristic = heu; } /** * Resetea el valor de la distribucion para el complejo */ public void removeDistribution() { for (int i = 0; i < numClasses; i++) { distrib[i] = 0; } } /** * Incrementa en 1 el n de ejemplo para la clase 'clase' cubiertas por el complejo * @param clase int El valor de la clase */ public void incrementDistribution(int clase) { distrib[clase]++; } /** * Devuelve el valor de la distribuci� para una clase dada * @param clase int El indice de la clase * @return double El valor de la distribucion */ public int getDistributionClass(int clase) { return distrib[clase]; } /** * Devuelve el valor de la distribuci� * @return double [] El valor de cada distribucion */ public int[] getDistribution() { return distrib; } /** * Imprime por pantalla el contenido del complejo (Lista -> Atributo operador valor) */ public void print(int nominal) { for (int x = 0; x < compl.size(); x++) { Selector s = (Selector) compl.get(x); double [] values = s.getValues(); String []nValues=s.getNValues(); //System.out.print("(Atr" + s.getAtributo() + " "); System.out.print("(" + attributeNames[s.getAttribute()] + " "); switch (s.getOperator()) { case 0: if(values.length>1 /*|| valoresN.length>1*/)System.out.print("in"); else System.out.print("="); break; case 1: System.out.print("<>"); break; case 2: System.out.print("<="); break; default: System.out.print(">"); } if(nominal==0){ //el atributo es nominal if (nValues.length > 1){ System.out.print(" " + nValues[0]); for (int i = 1; i < nValues.length - 1; i++) { System.out.print(" " + nValues[i]); } System.out.print(" " + nValues[nValues.length - 1] + ")"); } else{ System.out.print(" " + nValues[0]+")"); } } else{ if (values.length > 1){ System.out.print(" [" + values[0]); for (int i = 1; i < values.length - 1; i++) { System.out.print(" " + values[i]); } System.out.print(" " + values[values.length - 1] + "])"); } else{ System.out.print(" " + values[0]+")"); } } if (x < compl.size() - 1) { System.out.print(" AND "); } //System.out.print(" -- "+heuristica+" -- "); System.out.println(); } } /** * <p> * Prints on a String the complex content (List->Attribute) * </p> */ public String printString(int []numValues) { String cad = ""; for (int x = 0; x < compl.size(); x++) { Selector s = (Selector) compl.get(x); //cad += "Atr" + s.getAtributo() + " "; double [] values = s.getValues(); String [] nValues=s.getNValues(); //si para un atributo aparecen todos sus valores, la condicion es true //no imprimimos condicion if(values.length<numValues[s.getAttribute()]){ if ((x < (compl.size())) &&(x>0)) { cad += " AND "; } cad += attributeNames[s.getAttribute()] + " "; switch (s.getOperator()) { case 0: if(values.length>1)cad += "in"; else cad += "="; break; case 1: cad += "<>"; break; case 2: cad += "<="; break; case 3: cad += ">"; break; } if (Attributes.getInputAttribute(s.getAttribute()).getType() == Attribute.NOMINAL){ if (nValues.length > 1){ cad += " [" + nValues[0]; for (int i = 1; i < nValues.length - 1; i++) { cad += " �" + nValues[i]; } cad += " ,�" + nValues[nValues.length - 1] + "] "; } else{ cad += " " + nValues[0] + ""; } } else{ if (values.length > 1){ cad += " [" + values[0]; for (int i = 1; i < values.length - 1; i++) { cad += " �" + values[i]; } cad += " , " + values[values.length - 1] + "]"; } else{ cad += " " + values[0] + ""; } } } } return cad; } /** * <p> * Prints on the screen the class distribution of the complex * </p> */ public void printDistribution() { System.out.print(" ["); for (int i = 0; i < numClasses; i++) { System.out.print(" " + distrib[i]); } System.out.print("]"); } /** * <p> * Prints on the screen the class distribution for the complex * </p> * @return String idem */ public String printDistributionString() { String str = new String(" ["); for (int i = 0; i < numClasses; i++) { str += " " + distrib[i]; } str += "]"; return str; } /** * <p> * Do a local copy of the name of the input variables * </p> * @param atributos String[] an aray that stores the variable's name */ public void addNameAttributes(String [] atributos){ attributeNames = new String[atributos.length -1]; for (int i = 0; i < atributos.length -1; i++){ attributeNames[i] = atributos[i]; } } }