/*********************************************************************** 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 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.Rule_Learning.Riona; import java.util.LinkedList; import keel.Dataset.*; public class Complex implements Comparable { /** * <p> * Stores conjunctions of selectors * </p> */ private LinkedList compl; // Class of the rule private int classAttribute; private int nClasses; // Percent private int distribution[]; // Heuristic cost private double heuristic; private String [] nameAttributes; // weight of H private double weight; // volume of H private double volume; // dimension of H hole(0), lina(1), rectangle(2) private int nDimensions; public Complex() { } /** * Constructor for Complejo * @param nClas int number of classes */ public Complex(int nClas) { compl = new LinkedList(); //Inicializo la lista nClasses = nClas; //Almaceno el n de clases distribution = new int[nClas]; //Distribucion para las clases for (int i = 0; i < nClasses; i++) { distribution[i] = 0; //Inicializo a 0 } } /** * <p> * Compare two objects of the class * </p> * @param o complex to compare * @return int 0 Are equals (same heuristic and size, -1 if is major (same heuristic, less size || more heuristic) * 1 is worst (same heuristic, less size || less heuristic). */ public int compareTo(Object o) { Complex c2 = (Complex) o; int sal = 0; if (heuristic == c2.getHeuristic() && compl.size() == c2.size()) { sal = 0; } else if (heuristic == c2.getHeuristic() && compl.size() < c2.size()) { sal = -1; } else if (heuristic == c2.getHeuristic() && compl.size() > c2.size()) { sal = 1; } else if (heuristic > c2.getHeuristic()) { sal = -1; } else if (heuristic < c2.getHeuristic()) { sal = 1; } return (sal); } /** * <p> * Check if two complex are equals (represent the same) * </p> * @param c El 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).equivalents(c.getSelector(i)) == 0); } if(bEquals && (classAttribute!=c.getClassAttribute()))bEquals=false; } if(c.size()>compl.size()){ bEquals = true; for (int i = 0; (i < compl.size())&&(bEquals); i++){ bEquals = (this.getSelector(i).equivalents(c.getSelector(i)) == 0); } if(bEquals && (classAttribute!=c.getClassAttribute()))bEquals=false; } return bEquals; } /** * <p> * Add the selector into the selector list * </p> * @param s the selector (set atr. op. value) */ public void addSelector(Selector s) { compl.add(s); } /** * <p> * Drop the selector of the list selectors * </p> * @param s the selector (set atr. op. value) */ public void removeSelector(Selector s) { compl.remove(s); } /** * <p> * Borra los selectores de la lista de selectores que tengan como atributo el pasado * como argumento * </p> * @param attribute el atributo */ 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); i=i-1;} } } /** * <p> * Cleans the list * </p> */ public void clear() { compl.clear(); } /** * <p> * Return a selector in one position by giving a complex * </p> * @param indice Position inside the complex * @return Selector El selector */ public Selector getSelector(int indice) { return (Selector) compl.get(indice); } /** * <p> * Return the size complex * </p> * @return int El nmero de selectores que posee el complejo */ public int size() { return compl.size(); } /** * <p> * Return the number of classes * </p> * @return int number of classes */ public int getNClases() { return this.nClasses; } /** * <p> * Return the class that define the complex * </p> * @return int the class */ public int getClassAttribute() { return this.classAttribute; } /** * <p> * Gives the value of the class to the complex * </p> * @param clase int The class */ 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.nDimensions=d; } public int getDimensions(){ return nDimensions; } /** * <p> * Calculate the value of laplace for a complex * </p> */ public void computeLaPlace() { double nc; double ntot; int i; nc = distribution[classAttribute]; for (i = 0, ntot = 0; i < nClasses; i++) { ntot += distribution[i]; } heuristic = (nc + 1) / (ntot + nClasses); } /** * <p> * Check if the rule match with the parameter instance * </p> * @param ejemplo The instance * @return boolean True if match */ public boolean ruleCoversInstance(double []ejemplo/*Instance instancia*/){ boolean bCovered=true; for (int i = 0; i < this.size()&&bCovered; i++) { Selector s = this.getSelector(i); switch (s.getOperator()) { case 0: // se trata del igual double []valores=s.getValues(); bCovered=false; if (Attributes.getInputAttribute(s.getAttribute()).getType() == Attribute.NOMINAL){ for (int j = 0; (j < valores.length)&&(!bCovered); j++){ if(ejemplo[s.getAttribute()]==valores[j])bCovered=true; } } else {if( (ejemplo[s.getAttribute()] >= valores[0]) && (ejemplo[s.getAttribute()] <= valores[1])) bCovered=true;} break; } } return bCovered; } /** * <p> * return the heuristic value of the complex * </p> * @return double heuristic value of the complex */ public double getHeuristic() { return heuristic; } /** * <p> * Assign a heuristic value (Wracc) to the complex * </p> * @param heuristic heuristic value */ public void setHeuristic(double heuristic) { this.heuristic = heuristic; } /** * <p> * reset the distribution value for the complex * </p> */ public void removeDistribution() { for (int i = 0; i < nClasses; i++) { distribution[i] = 0; } } /** * <p> * Add one to the n of the complex for the class * </p> * @param classAttribute int value of the class */ public void incrementDistribution(int classAttribute) { distribution[classAttribute]++; } /** * <p> * Return the value of the distribution * </p> * @param classAttribute int index of the class * @return double value of distribution */ public int getDistributionClass(int classAttribute) { return distribution[classAttribute]; } /** * <p> * Return the value of the distribution * </p> * @return double [] the value of each distribution */ public int[] getDistribution() { return distribution; } /** * <p> * Print the content of the complex (List->Attribute operator value) * </p> */ public void print() { for (int x = 0; x < compl.size(); x++) { Selector s = (Selector) compl.get(x); double [] values = s.getValues(); String []valuesN=s.getNValues(); System.out.print("(" + nameAttributes[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 (Attributes.getInputAttribute(s.getAttribute()).getType() == Attribute.NOMINAL){ if (valuesN.length > 1){ System.out.print(" {" + valuesN[0]); for (int i = 1; i < valuesN.length - 1; i++) { System.out.print(", " + valuesN[i]); } System.out.print(", " + valuesN[valuesN.length - 1] + "})"); } else{ System.out.print(" " + valuesN[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.println("-> "+classAttribute); } } /** * <p> * Print the complex content using a string (List->Attribute operator value) * </p> * @return String string with the content of the complex */ public String printString(int []numValues) { String str = ""; for (int x = 0; x < compl.size(); x++) { Selector s = (Selector) compl.get(x); double [] values = s.getValues(); String []valuesN=s.getNValues(); str += nameAttributes[s.getAttribute()] + " "; switch (s.getOperator()) { case 0: if (Attributes.getInputAttribute(s.getAttribute()).getType() == Attribute.NOMINAL) str += "="; else str += "in"; break; case 1: str += "<>"; break; case 2: str += "<="; break; case 3: str += ">"; break; } if (Attributes.getInputAttribute(s.getAttribute()).getType() == Attribute.NOMINAL){ str += " " + valuesN[0] + ""; } else{ if (values.length > 1){ str += " [" + values[0]; for (int i = 1; i < values.length - 1; i++) { str += " �" + values[i]; } str += " , " + values[values.length - 1] + "]"; } else{ str += " " + values[0] + ""; } } if (x < compl.size() - 1) { str += " AND "; } } if(compl.size()==0)str+="true"; return str; } /** * <p> * Print the classes distribution for the complex * </p> */ public void printDistribucion() { System.out.print(" ["); for (int i = 0; i < nClasses; i++) { System.out.print(" " + distribution[i]); } System.out.print("]"); } /** * <p> * Print the classes distribution for the complex * </p> * @return String classes distribution for the complex */ public String printDistribucionString() { String str = new String(" ["); for (int i = 0; i < nClasses; i++) { str += " " + distribution[i]; } str += "]"; return str; } /** * <p> * Local copy of the name of variables * </p> * @param attributes String[] stores the name of the variables */ public void adjuntNameAttributes(String [] attributes){ nameAttributes = new String[attributes.length -1]; for (int i = 0; i < attributes.length -1; i++){ nameAttributes[i] = attributes[i]; } } /** * <p> * Return an array of size numAttributes. * Each content 1 if selector exists, 0 otherwise * </p> */ public int []existingSelectors(){ int []conditions=new int[nameAttributes.length]; for(int i=0;i<nameAttributes.length;i++){ conditions[i]=0; for(int j=0;j<compl.size();j++){ Selector s; s=(Selector) compl.get(j); int at=s.getAttribute(); conditions[at]=1; } } return conditions; } }