//--------------------------------------------------------------------------------// // 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 PODADO DE REGLAS Y FUNCIONES DE PERTENENCIA // //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// package xfuzzy.xfsl; import xfuzzy.lang.*; public class XfspPruning implements Cloneable { //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// // CONSTANTES PUBLICAS // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// public static final int NONE = 0; public static final int PRUNE_THRESHOLD = 1; public static final int PRUNE_WORST = 2; public static final int PRUNE_EXCEPT = 3; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// // MIEMBROS PRIVADOS // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// private int kind; private double param; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// // CONSTRUCTOR // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //-------------------------------------------------------------// // Constructor por defecto // //-------------------------------------------------------------// public XfspPruning() { this.kind = NONE; this.param = -1; } //-------------------------------------------------------------// // Constructor con datos // //-------------------------------------------------------------// public XfspPruning(int kind, double param) { this.kind = kind; this.param = param; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// // METODOS PUBLICOS // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //-------------------------------------------------------------// // Duplicado del objeto // //-------------------------------------------------------------// public Object clone() { return new XfspPruning(kind, param); } //-------------------------------------------------------------// // Obtiene el tipo de podado // //-------------------------------------------------------------// public int getKind() { return this.kind; } //-------------------------------------------------------------// // Obtiene el parametro del podado / //-------------------------------------------------------------// public double getParam() { return this.param; } //-------------------------------------------------------------// // Verifica que el proceso este configurado // //-------------------------------------------------------------// public boolean isOn() { return (this.kind != NONE); } //-------------------------------------------------------------// // Configura el proceso desde una directiva // //-------------------------------------------------------------// public void set(String name, double[] params) { if(name.equals("prune_threshold")) { kind = PRUNE_THRESHOLD; this.param = params[0]; } if(name.equals("prune_worst")) { kind = PRUNE_WORST; this.param = params[0]; } if(name.equals("prune_except")) { kind = PRUNE_EXCEPT; this.param = params[0]; } } //-------------------------------------------------------------// // Codigo de la directiva de configuracion // //-------------------------------------------------------------// public String toCode() { String eol = System.getProperty("line.separator", "\n"); String src = ""; if(kind == PRUNE_THRESHOLD) src = "(prune_threshold,"+param+")"+eol; if(kind == PRUNE_WORST) src = "(prune_worst,"+(int) param+")"+eol; if(kind == PRUNE_EXCEPT) src = "(prune_except,"+(int) param+")"+eol; return src; } //-------------------------------------------------------------// // Ejecucion del proceso de simplificacion // //-------------------------------------------------------------// public String compute(Specification spec, double[][] pattern) { if(kind == NONE) return null; int rules = 0; setMaxActivation(spec, pattern); if(kind == PRUNE_THRESHOLD) rules = prune_threshold(spec,param); if(kind == PRUNE_WORST) rules = prune_worst(spec, (int) param); if(kind == PRUNE_EXCEPT) rules = prune_best(spec, (int) param); int mfs = prune_mfs(spec); return "Pruning: "+rules+" rules and "+mfs+" membership functions pruned."; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// // METODOS PRIVADOS // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //-------------------------------------------------------------// // Calcula el grado de activacion maxima de cada regla // //-------------------------------------------------------------// private void setMaxActivation(Specification spec, double[][] pattern) { SystemModule system = spec.getSystemModule(); Rulebase[] rulebase = spec.getRulebases(); for(int i=0; i<rulebase.length; i++) rulebase[i].resetMaxActivation(); for(int p=0; p<pattern.length; p++) system.fuzzyInference(pattern[p]); } //-------------------------------------------------------------// // Elimina todos las reglas que no alcanzan un umbral // //-------------------------------------------------------------// private int prune_threshold(Specification spec, double threshold) { Rulebase[] rulebase = spec.getRulebases(); int pruned = 0; for(int i=0; i<rulebase.length; i++) { Rule[] rule = rulebase[i].getRules(); for(int j=0; j<rule.length; j++) if(rule[j].getMaxActivation() < threshold ) { rulebase[i].remove(rule[j]); pruned++; } } return pruned; } //-------------------------------------------------------------// // Elimina todas las reglas salvo las N mejores // //-------------------------------------------------------------// private int prune_best(Specification spec, int best) { Rulebase[] rulebase = spec.getRulebases(); int count=0; for(int i=0; i<rulebase.length; i++) count+=rulebase[i].getRules().length; Rule[] all = new Rule[count]; for(int i=0,k=0; i<rulebase.length; i++) { Rule[] rule = rulebase[i].getRules(); for(int j=0; j<rule.length; j++) { all[k] = rule[j]; k++; } } for(int i=0; i<all.length; i++) for(int j=i+1; j<all.length; j++) if(all[i].getMaxActivation() < all[j].getMaxActivation()) { Rule aux = all[i]; all[i] = all[j]; all[j] = aux; } for(int i=best; i<all.length; i++) for(int j=0; j<rulebase.length; j++) rulebase[j].remove(all[i]); return all.length - best; } //-------------------------------------------------------------// // Elimina las N peores reglas // //-------------------------------------------------------------// private int prune_worst(Specification spec, int worst) { Rulebase[] rulebase = spec.getRulebases(); int count=0; for(int i=0; i<rulebase.length; i++) count+=rulebase[i].getRules().length; Rule[] all = new Rule[count]; for(int i=0,k=0; i<rulebase.length; i++) { Rule[] rule = rulebase[i].getRules(); for(int j=0; j<rule.length; j++) { all[k] = rule[j]; k++; } } for(int i=0; i<all.length; i++) for(int j=i+1; j<all.length; j++) if(all[i].getMaxActivation() < all[j].getMaxActivation()) { Rule aux = all[i]; all[i] = all[j]; all[j] = aux; } for(int i=all.length-worst; i<all.length; i++) for(int j=0; j<rulebase.length; j++) rulebase[j].remove(all[i]); return worst; } //-------------------------------------------------------------// // Elimina las funciones de pertenencia no utilizadas // //-------------------------------------------------------------// private int prune_mfs(Specification spec) { int pruned = 0; Type[] type = spec.getTypes(); for(int i=0; i<type.length; i++) pruned += type[i].prune(); return pruned; } }