/*********************************************************************** 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.RE_SL_Postprocess.MamWSelect; import java.io.*; import org.core.*; import java.util.*; class BaseR { public Difuso [][] BaseReglas; public int max_reglas; public int n_reglas, cpeso; public double [] GradoEmp; public Difuso [] Consecuentes; public double [] BaseP; MiDataset tabla; public BaseR (int Max_reglas, int peso, MiDataset t) { int i, j; tabla = t; cpeso = peso; n_reglas = 0; max_reglas = Max_reglas; BaseP = new double[max_reglas]; BaseReglas = new Difuso [max_reglas][tabla.n_variables]; /* Vector en el que se almacenan los consecuentes */ Consecuentes = new Difuso[max_reglas]; for (i=0; i<max_reglas; i++) { BaseReglas[i] = new Difuso [tabla.n_variables]; Consecuentes[i] = new Difuso(); for (j=0; j<tabla.n_variables; j++) BaseReglas[i][j] = new Difuso(); } GradoEmp = new double[max_reglas]; } public BaseR (String fichero, int peso, MiDataset t) { int i; tabla = t;; cpeso = peso; leer_BR(fichero); max_reglas = n_reglas; /* Vector en el que se almacenan los consecuentes */ Consecuentes = new Difuso[n_reglas] ; GradoEmp = new double[n_reglas]; for (i=0; i<n_reglas; i++) Consecuentes[i] = new Difuso(); } /** Reads the RB of a input file */ public void leer_BR (String fichero){ int i, j; String cadena; cadena = Fichero.leeFichero(fichero); StringTokenizer sT = new StringTokenizer(cadena, "\n\r\t ", false); sT.nextToken(); sT.nextToken(); sT.nextToken(); n_reglas = Integer.parseInt(sT.nextToken()); BaseReglas = new Difuso [n_reglas][tabla.n_variables]; for (i=0; i<n_reglas; i++) { BaseReglas[i] = new Difuso [tabla.n_variables]; for (j=0; j<tabla.n_variables; j++) BaseReglas[i][j] = new Difuso(); } BaseP = new double[n_reglas]; for (i=0; i<n_reglas; i++) { for (j=0; j<tabla.n_variables; j++) { BaseReglas[i][j].x0 = Double.parseDouble(sT.nextToken()); BaseReglas[i][j].x1 = Double.parseDouble(sT.nextToken()); BaseReglas[i][j].x2 = BaseReglas[i][j].x1; BaseReglas[i][j].x3 = Double.parseDouble(sT.nextToken()); BaseReglas[i][j].y = 1.0; } if (cpeso==1) BaseP[i] = 1.0; } } /* ------------------------------------------------------------------------- Fuzzification Interface ------------------------------------------------------------------------- */ public double Fuzzifica (double X, Difuso D) { /* If X are not in the rank D, the degree is 0 */ if ((X<D.x0) || (X>D.x3)) return (0); if (X<D.x1) return ((X-D.x0)*(D.y/(D.x1-D.x0))); if (X>D.x2) return ((D.x3-X)*(D.y/(D.x3-D.x2))); return (D.y); } /* ------------------------------------------------------------------------- Conjunction Operator ------------------------------------------------------------------------- */ /* T-norma Minimal */ public void Min (double [] entradas) { int b, b2; double minimo, y; for (b=0; b<n_reglas; b++) { minimo = Fuzzifica (entradas[0], BaseReglas[b][0]); for (b2=1; minimo>0.0 && b2 < tabla.n_var_estado; b2++) { y = Fuzzifica (entradas[b2], BaseReglas[b][b2]); if (y < minimo) minimo=y; } GradoEmp[b] = minimo; } } /* ------------------------------------------------------------------------- Implication Operator ------------------------------------------------------------------------- */ public void T_Min () { int b; for (b=0; b<n_reglas; b++) { if (GradoEmp[b] != 0) { if (GradoEmp[b] == 1.0) { Consecuentes[b].x0 = BaseReglas[b][tabla.n_var_estado].x0; Consecuentes[b].x1 = BaseReglas[b][tabla.n_var_estado].x1; Consecuentes[b].x2 = BaseReglas[b][tabla.n_var_estado].x2; Consecuentes[b].x3 = BaseReglas[b][tabla.n_var_estado].x3; } else { Consecuentes[b].x0 = BaseReglas[b][tabla.n_var_estado].x0; Consecuentes[b].x1 = BaseReglas[b][tabla.n_var_estado].x0 + (BaseReglas[b][tabla.n_var_estado].x1 - BaseReglas[b][tabla.n_var_estado].x0)*GradoEmp[b]; Consecuentes[b].x2 = BaseReglas[b][tabla.n_var_estado].x3 + (BaseReglas[b][tabla.n_var_estado].x2 - BaseReglas[b][tabla.n_var_estado].x3)*GradoEmp[b]; Consecuentes[b].x3 = BaseReglas[b][tabla.n_var_estado].x3; } if (BaseReglas[b][tabla.n_var_estado].x0 == BaseReglas[b][tabla.n_var_estado].x1){ Consecuentes[b].x1 = Consecuentes[b].x0-(Consecuentes[b].x2-Consecuentes[b].x0); Consecuentes[b].x0 = Consecuentes[b].x0-(Consecuentes[b].x3-Consecuentes[b].x0); } if (BaseReglas[b][tabla.n_var_estado].x2 == BaseReglas[b][tabla.n_var_estado].x3){ Consecuentes[b].x2=Consecuentes[b].x3+(Consecuentes[b].x3-Consecuentes[b].x1); Consecuentes[b].x3=Consecuentes[b].x3+(Consecuentes[b].x3-Consecuentes[b].x0); } } else { Consecuentes[b].x0=0; Consecuentes[b].x1=0; Consecuentes[b].x2=0; Consecuentes[b].x3=0; } Consecuentes[b].y = GradoEmp[b]; } } /* ------------------------------------------------------------------------- Defuzzification Interface ------------------------------------------------------------------------- */ /** Functions to calculate the centre of gravity */ public double AreaTrapecioX (double x0, double x1, double x2, double x3, double y) { double izq, centro, der; if (x1!=x0) izq = (2*x1*x1*x1-3*x0*x1*x1+x0*x0*x0)/(6*(x1-x0)); else izq = 0; centro = (x2*x2-x1*x1) / 2.0; if (x3 != x2) der = (2*x2*x2*x2-3*x3*x2*x2+x3*x3*x3) / (6*(x3-x2)); else der = 0; return (y * (izq + centro + der)); } public double AreaTrapecio (double x0, double x1, double x2, double x3, double y) { double izq, centro, der; if (x1 != x0) izq = (x1*x1-2*x0*x1+x0*x0)/(2*(x1-x0)); else izq = 0; centro = x2 - x1; if (x3 != x2) der = (x3 * x3 - 2 * x3 * x2 + x2 * x2) / (2 * (x3 - x2)); else der = 0; return (y * (izq + centro + der)); } /** Returns the centre of gravity weight by matching */ public double WECOA () { double num, den; int i; num = 0; den = 0; for (i=0; i < n_reglas; i++) if (Consecuentes[i].y!=0) { num += BaseP[i] * GradoEmp[i] * (AreaTrapecioX (Consecuentes[i].x0,Consecuentes[i].x1, Consecuentes[i].x2,Consecuentes[i].x3,Consecuentes[i].y) / AreaTrapecio (Consecuentes[i].x0,Consecuentes[i].x1, Consecuentes[i].x2,Consecuentes[i].x3,Consecuentes[i].y)); den += BaseP[i] * GradoEmp[i]; } if (den != 0) return (num / den); else return ((tabla.extremos[tabla.n_var_estado].max - tabla.extremos[tabla.n_var_estado].min)/2.0); } /* ------------------------------------------------------------------------- Fuzzy Controller ------------------------------------------------------------------------- */ /** Returns the ouput of the controller */ public double FLC (double [] Entrada) { Min (Entrada); T_Min (); return (WECOA ()); } /** RB to String */ public String BRtoString () { int i, j; String cadena=""; cadena += "Numero de reglas: " + n_reglas + "\n\n"; for (i=0; i < n_reglas; i++) { for (j=0; j < tabla.n_variables; j++) cadena += "" + BaseReglas[i][j].x0 + " " + BaseReglas[i][j].x1 + " " + BaseReglas[i][j].x3 + "\n"; cadena += "" + BaseP[i] + "\n"; cadena += "\n"; } return (cadena); } }