/*********************************************************************** 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/ **********************************************************************/ package keel.Algorithms.Rule_Learning.UnoR; import java.util.LinkedList; import keel.Dataset.*; /** * <p>Title: Clase Complejo</p> * * <p>Description: Define un Complex (o regla)</p> * * <p>Copyright: Copyright Rosa (c) 2007</p> * * <p>Company: Mi Casa </p> * * @author Rosa Venzala * @version 1.0 */ public class Complejo implements Comparable { /** * Esta clase almacena conjunciones de Selectores */ private LinkedList compl; private int clase; private int nClases; private int distrib[]; //contiene porcentaje n muestras por clase que satisfacen antecedente private double heuristica; // Coste segun heuristica private String [] nombreAtributos; public Complejo() { } /** * Constructor para el Complejo * @param nClas int Nmero de clases */ public Complejo(int nClas) { compl = new LinkedList(); //Inicializo la lista nClases = nClas; //Almaceno el n de clases distrib = new int[nClas]; //Distribucion para las clases for (int i = 0; i < nClases; i++) { distrib[i] = 0; //Inicializo a 0 } } /** * Compara dos objetos de la clase Complejo * @param o Object Complejo a comparar * @return int 0 si son iguales (misma heuristica y tama�), -1 si es mejor (misma heur, menor tama� || mayor heur) * 1 si es peor (misma heur, mayor tama� || menor heuristica). */ public int compareTo(Object o) { Complejo c2 = (Complejo) o; int sal = 0; if (heuristica == c2.getHeuristica() && compl.size() == c2.size()) { sal = 0; } else if (heuristica == c2.getHeuristica() && compl.size() < c2.size()) { sal = -1; } else if (heuristica == c2.getHeuristica() && compl.size() > c2.size()) { sal = 1; } else if (heuristica > c2.getHeuristica()) { sal = -1; } else if (heuristica < c2.getHeuristica()) { sal = 1; } return (sal); } /** * Comprueba si dos complejos son iguales * @param c Complejo El complejo a comparar * @return boolean True si son iguales. False en caso contrario */ public boolean esIgual(Complejo c){ boolean iguales = false; if (c.size() == compl.size()){ iguales = true; for (int i = 0; (i < c.size())&&(iguales); i++){ iguales = (this.getSelector(i).compareTo(c.getSelector(i)) == 0); } } return iguales; } /** * A�de el selector a la lista de selectores * @param s Selector el selector (conjunto atr. op. valor) */ public void addSelector(Selector s) { compl.add(s); } /** * Borra el selector de la lista de selectores * @param s Selector el selector (conjunto atr. op. valor) */ public void removeSelector(Selector s) { compl.remove(s); } /** * Borra los selectores de la lista de selectores que tengan como atributo el pasado *como argumento * @param atributo el atributo */ public void removeSelectorAtributo(int atributo) { Selector s; int atrib; for(int i=0;i<compl.size();i++){ s=(Selector)compl.get(i); atrib=s.getAtributo(); if(atrib==atributo){compl.remove(s); /*CUIDADO!!!hay q volver al indice anterior pq se ha eliminado un elemento!!*/ i=i-1;} } } /** * Deja vacia la lista */ public void clear() { compl.clear(); } /** * Devuelve un selector en una posicion dada del complejo * @param indice int Posicion dentro del complejo * @return Selector El selector */ public Selector getSelector(int indice) { return (Selector) compl.get(indice); } /** * Devuelve el tama� del complejo * @return int El nmero de selectores que posee el complejo */ public int size() { return compl.size(); } /** * Devuelve el n de clases del problema * @return int idem. */ public int getNClases() { return this.nClases; } /** * Devuelve la clase que define el complejo * @return int la clase */ public int getClase() { return this.clase; } /** * Proporciona el valor de la clase al complejo * @param clase int La clase */ public void setClase(int clase) { this.clase = clase; } /** * Calcula el valor del laplaciano para un complejo */ public void calculaLaplaciano() { double nc; double ntot; int i; nc = distrib[clase]; for (i = 0, ntot = 0; i < nClases; i++) { ntot += distrib[i]; } //heuristica = (ntot - nc + nClases - 1) / (ntot + nClases); heuristica = (nc + 1) / (ntot + nClases); } /** *Comprueba si la regla cubre a la instancia pasada como parametro *@param instancia La instancia *@return boolean True si la regla cubre a la instancia */ public boolean reglaCubreInstancia(Instance instancia){ boolean cubierto=true; double cadena; for (int i = 0; i < this.size()&&cubierto; i++) { Selector s = this.getSelector(i); switch (s.getOperador()) { case 0: // se trata del igual double []valor=s.getValores(); cubierto=false; for (int j = 0; (j < valor.length)&&(!cubierto); j++){ cadena=instancia.getInputRealValues(s.getAtributo()); /*System.out.println("en la instancia es "+cadena); System.out.println("y en el selector "+valor[j]);*/ if(cadena==valor[j]) cubierto=true; else cubierto=false; /*int numInputAttributes = Attributes.getInputNumAttributes(); int numOutputAttributes = Attributes.getOutputNumAttributes(); int numUndefinedAttributes = Attributes.getNumAttributes();*/ } break; } } return cubierto; } /** * Comprueba si el complejo cubre a la muestra dada * @param m Muestra El ejemplo * @return boolean True si cubre al ejemplo. False en otro caso */ public boolean cubre(Muestra m) { boolean cubierto = true; double[] ejemplo = m.getMuest(); for (int i = 0; i < this.size() && cubierto; i++) { // recorremos los selectores del complejo Selector s = this.getSelector(i); switch (s.getOperador()) { case 0: // se trata del igual double [] valor = s.getValores(); cubierto = false; for (int j = 0; (j < valor.length)&&(!cubierto); j++){ cubierto = (ejemplo[s.getAtributo()] == valor[j]); //en cuanto uno sea true me vale (or) } //AÑADIMOS LA SIGUIENTE CONDICION PARA CUANDO EL VALOR EXACTO NO SE ENCUENTRA //EN LA LISTA PERO AL ESTAR ENTRE LOS EXTREMOS TAMBIEN PERTENECE AL INTERVALO if(!cubierto){ if((ejemplo[s.getAtributo()]>=valor[0]) && (ejemplo[s.getAtributo()]<=valor[valor.length-1]))cubierto=true; } /*if (!(ejemplo[s.getAtributo()] == s.getValor())) { cubierto = false; }*/ break; case 1: // se trata del distinto cubierto = ejemplo[s.getAtributo()] != s.getValor(); break; case 2: //menor o igual cubierto = ejemplo[s.getAtributo()] <= s.getValor(); break; case 3: //mayor cubierto = ejemplo[s.getAtributo()] > s.getValor(); break; } } return cubierto; } /** * Devuelve el valor heur�tico del complejo * @return double idem */ public double getHeuristica() { return heuristica; } /** * Asigna un valor heuristico (Wracc) al complejo * @param heu double el valor heuristico */ public void setHeuristica(double heu) { heuristica = heu; } /** * Resetea el valor de la distribucion para el complejo */ public void borraDistrib() { for (int i = 0; i < nClases; 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 incrementaDistrib(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 getDistribucionClase(int clase) { return distrib[clase]; } /** * Devuelve el valor de la distribuci� * @return double [] El valor de cada distribucion */ public int[] getDistribucion() { 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 [] valores = s.getValores(); String []valoresN=s.getValoresN(); //System.out.print("(Atr" + s.getAtributo() + " "); System.out.print("(" + nombreAtributos[s.getAtributo()] + " "); switch (s.getOperador()) { case 0: if(valores.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 (valoresN.length > 1){ System.out.print(" " + valoresN[0]); for (int i = 1; i < valoresN.length - 1; i++) { System.out.print(" " + valoresN[i]); } System.out.print(" " + valoresN[valoresN.length - 1] + ")"); } else{ System.out.print(" " + valoresN[0]+")"); } } else{ if (valores.length > 1){ System.out.print(" [" + valores[0]); for (int i = 1; i < valores.length - 1; i++) { System.out.print(" " + valores[i]); } System.out.print(" " + valores[valores.length - 1] + "])"); } else{ System.out.print(" " + valores[0]+")"); } } if (x < compl.size() - 1) { System.out.print(" AND "); } } //System.out.print(" -- "+heuristica+" -- "); System.out.println(); } /** * Imprime en una cadena de caracteres el contenido del complejo (Lista -> Atributo operador valor) *@param nominal indica si el atributo es nominal(0) o numerico(1) *@param inf el extremo inferior del intervalo *@param sup el extremo superior del intervalo *@param ultima indica si se trata de la ultima regla del conjunto de reglas * @return String La cadena con el contenido del complejo */ public String printString(int nominal,double inf,double sup,boolean ultima) { String cad = ""; for (int x = 0; x < compl.size(); x++) { Selector s = (Selector) compl.get(x); //cad += "Atr" + s.getAtributo() + " "; cad += nombreAtributos[s.getAtributo()] + " "; double [] valores = s.getValores(); String []valoresN=s.getValoresN(); switch (s.getOperador()) { case 0: if(valores.length>1 /*|| valoresN.length>1*/)cad += "in"; else cad += "="; break; case 1: cad += "<>"; break; case 2: cad += "<="; break; case 3: cad += ">"; break; } if(nominal==0){ if (valoresN.length > 1){ cad += " " + valoresN[0]; for (int i = 1; i < valoresN.length - 1; i++) { cad += " �" + valoresN[i]; } cad += " �" + valoresN[valoresN.length - 1] + ""; } else{ cad += " " + valoresN[0] + ""; } } else{ //No imprimimos todo el intervalo, sino solo los extremos inferior y superior //Necesitamos los parametros inf y sup pq estamos agrupando las reglas // consecutivas que tienen la misma clase if (valores.length > 1){ cad += " [" + inf/*valores[0]*/; /*for (int i = 1; i < valores.length - 1; i++) { cad += " �" + valores[i]; }*/ if(ultima) cad += " , �" + sup/*valores[valores.length - 1]*/ + "]"; else cad += " , �" + sup/*valores[valores.length - 1]*/ + ")"; } else{ cad += " " + valores[0] + ""; } } if (x < compl.size() - 1) { cad += " AND "; } } return cad; } /** * Imprime por pantalla la distribuci� de clases para el complejo */ public void printDistribucion() { System.out.print(" ["); for (int i = 0; i < nClases; i++) { System.out.print(" " + distrib[i]); } System.out.print("]"); } /** * Imprime en un String la distribuci� de clases para el complejo * @return String idem */ public String printDistribucionString() { String cad = new String(" ["); for (int i = 0; i < nClases; i++) { cad += " " + distrib[i]; } cad += "]"; return cad; } /** * Realizamos una copia local del nombre de las variables de entrada * @param atributos String[] un Array que guarda el nombre de cada variable */ public void adjuntaNombreAtributos(String [] atributos){ nombreAtributos = new String[atributos.length -1]; for (int i = 0; i < atributos.length -1; i++){ nombreAtributos[i] = atributos[i]; } } }