//--------------------------------------------------------------------------------//
// COPYRIGHT NOTICE //
//--------------------------------------------------------------------------------//
// Copyright (c) 2012, Instituto de Microelectronica de Sevilla (IMSE-CNM) //
// //
// All rights reserved. //
// //
// Redistribution and use in source and binary forms, with or without //
// modification, are permitted provided that the following conditions are met: //
// //
// * Redistributions of source code must retain the above copyright notice, //
// this list of conditions and the following disclaimer. //
// //
// * Redistributions in binary form must reproduce the above copyright //
// notice, this list of conditions and the following disclaimer in the //
// documentation and/or other materials provided with the distribution. //
// //
// * Neither the name of the IMSE-CNM nor the names of its contributors may //
// be used to endorse or promote products derived from this software //
// without specific prior written permission. //
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" //
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE //
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE //
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE //
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL //
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR //
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER //
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, //
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE //
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. //
//--------------------------------------------------------------------------------//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// ALGORITMO DE NAUCK DE REGLAS MAS CORRECTAS //
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
package xfuzzy.xfdm;
import xfuzzy.lang.*;
import java.util.Vector;
public class XfdmNauck extends XfdmActiveRules {
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// MIEMBROS PRIVADOS //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
private int numclass;
private boolean global;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// CONSTRUCTOR //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//-------------------------------------------------------------//
// Constructor completo //
//-------------------------------------------------------------//
public XfdmNauck(int numclass, boolean global) {
this.numclass = numclass;
this.global = global;
}
//-------------------------------------------------------------//
// Constructor con el numero de clases //
//-------------------------------------------------------------//
public XfdmNauck(int numclass) {
this.numclass = numclass;
this.global = true;
}
//-------------------------------------------------------------//
// Constructor por defecto //
//-------------------------------------------------------------//
public XfdmNauck() {
this.numclass = 5;
this.global = true;
}
//-------------------------------------------------------------//
// Constructor desde el fichero de configuracion //
//-------------------------------------------------------------//
public XfdmNauck(double param[]) {
this.numclass = (int) param[0];
this.global = (((int) param[1]) == 1);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// METODOS PUBLICOS //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//-------------------------------------------------------------//
// Obtiene un duplicado del objeto //
//-------------------------------------------------------------//
public Object clone() {
return new XfdmNauck(numclass,global);
}
//-------------------------------------------------------------//
// Obtiene el nombre del algoritmo //
//-------------------------------------------------------------//
public String toString() {
return "Nauck (Best-performance rule extraction)";
}
//-------------------------------------------------------------//
// Representacion en el fichero de configuracion //
//-------------------------------------------------------------//
public String toCode() {
int gb = (global? 1 : 0);
return "xfdm_algorithm(Nauck,"+numclass+","+gb+")";
}
//-------------------------------------------------------------//
// Obtiene el numero de reglas a seleccionar //
//-------------------------------------------------------------//
public int getNumberOfRules() {
return numclass;
}
//-------------------------------------------------------------//
// Verifica si es el numero de reglas total o por clase //
//-------------------------------------------------------------//
public boolean isGlobal() {
return this.global;
}
//-------------------------------------------------------------//
// Asigna el numero de reglas a seleccionar //
//-------------------------------------------------------------//
public void setNumberOfRules(int number) {
this.numclass = number;
}
//-------------------------------------------------------------//
// Asigna si es el numero de reglas total o por clase //
//-------------------------------------------------------------//
public void setGlobal(boolean global) {
this.global = global;
}
//-------------------------------------------------------------//
// Selecciona las reglas mas correctas //
//-------------------------------------------------------------//
public Vector pruneRules(Vector rules) {
if(global) return pruneRulesGlobal(rules);
else return pruneRulesLocal(rules);
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// METODOS PRIVADOS //
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//-------------------------------------------------------------//
// Selecciona las N mejores reglas //
//-------------------------------------------------------------//
private Vector pruneRulesGlobal(Vector rules) {
int sort[][] = getSortedList(rules);
Vector pruned = new Vector();
for(int i=0;i<numclass;i++) pruned.add(rules.elementAt(sort[i][0]));
return pruned;
}
//-------------------------------------------------------------//
// Selecciona las N mejores reglas para cada clase //
//-------------------------------------------------------------//
private Vector pruneRulesLocal(Vector rules) {
int included[][] = new int[outputtype.length][];
for(int i=0; i<outputtype.length; i++) {
LinguisticLabel lb[] = outputtype[i].getAllMembershipFunctions();
included[i] = new int[lb.length];
}
int sorted[][] = getSortedList(rules);
Vector pruned = new Vector();
for(int i=0; i<sorted.length; i++) {
if(isFull(included)) break;
if(!isFull(included,sorted[i])) {
pruned.add(rules.elementAt(sorted[i][0]));
increase(included,sorted[i]);
}
}
return pruned;
}
//-------------------------------------------------------------//
// Obtiene la lista de reglas ordenada por eficiencia //
//-------------------------------------------------------------//
private int[][] getSortedList(Vector rules) {
double perform[][] = new double[rules.size()][2];
for(int i=0; i<perform.length; i++) {
perform[i][0] = ((XfdmPseudoRule) rules.elementAt(i)).getPerformance();
perform[i][1] = 1.0*i;
}
double aux0, aux1;
for(int i=0; i<perform.length-1; i++) {
for(int j=i+1; j<perform.length; j++) {
if(perform[i][0]<perform[j][0]) {
aux0 = perform[i][0]; aux1 = perform[i][1];
perform[i][0] = perform[j][0]; perform[i][1] = perform[j][1];
perform[j][0] = aux0; perform[j][1] = aux1;
}
}
}
int sorted[][] = new int[rules.size()][config.numoutputs+1];
for(int i=0; i<sorted.length; i++) {
sorted[i][0] = (int) perform[i][1];
XfdmPseudoRule pseudo = (XfdmPseudoRule) rules.elementAt(sorted[i][0]);
int clind[] = pseudo.getClassIndexes();
for(int j=0; j<clind.length; j++) sorted[i][j+1] = clind[j];
}
return sorted;
}
//-------------------------------------------------------------//
// Verifica si la cuenta de reglas por clases esta saturada //
//-------------------------------------------------------------//
private boolean isFull(int counter[][]) {
for(int i=0; i<counter.length; i++)
for(int j=0; j<counter[i].length; j++)
if(counter[i][j] <numclass) return false;
return true;
}
//-------------------------------------------------------------//
// Verifica si las clases indicadas estan saturadas //
//-------------------------------------------------------------//
private boolean isFull(int counter[][], int index[]) {
for(int i=0; i<counter.length; i++)
if(counter[i][index[i+1]] <numclass) return false;
return true;
}
//-------------------------------------------------------------//
// Incrementa el contador de las clases indicadas //
//-------------------------------------------------------------//
private void increase(int counter[][], int index[]) {
for(int i=0; i<counter.length; i++) counter[i][index[i+1]]++;
}
}