/*********************************************************************** 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_Methods.TSK_IRL; import java.io.*; import org.core.*; import java.util.*; class BaseR { public Regla[] BaseReglas; public int max_reglas; public int n_reglas, n_etiq_distintas; public double[] GradoEmp; public double[] cromosoma; public double[][] ListaTabu; public int[] Regla_act; public int [][] b_reglas; public int[][] Pob_reglas; public MiDataset tabla; public BaseD base_datos; public BaseR(BaseD base_d, MiDataset t) { int i; this.tabla = t; this.base_datos = base_d; this.n_reglas = 0; this.max_reglas = 1; for (i = 0; i < tabla.n_var_estado; i++) { max_reglas *= base_datos.n_etiquetas[i]; } Regla_act = new int[tabla.n_var_estado]; cromosoma = new double[tabla.n_var_estado * 5 + 1]; GradoEmp = new double[max_reglas]; ListaTabu = new double[max_reglas][tabla.n_var_estado]; Pob_reglas = new int[max_reglas][tabla.n_var_estado]; BaseReglas = new Regla[this.max_reglas]; for (i = 0; i < this.max_reglas; i++) { BaseReglas[i] = new Regla(tabla.n_var_estado, tabla.n_variables); } } public BaseR(String fichero, MiDataset datos) { int i; tabla = datos; leer_BR(fichero); max_reglas = n_reglas; b_reglas = new int[n_reglas][tabla.n_variables]; GradoEmp = new double[n_reglas]; } /** Reads the RB of a input file */ public void leer_BR(String fichero) { int i, j, k, repetida; String cadena; System.out.println("\n\nEntrando en LeerBR"); 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()); System.out.println("\n\nEntrando en LeerBR"); BaseReglas = new Regla[n_reglas]; for (i = 0; i < n_reglas; i++) { BaseReglas[i] = new Regla(tabla.n_var_estado, tabla.n_variables); } this.n_etiq_distintas = 0; for (i = 0; i < n_reglas; i++) { for (j = 0; j < tabla.n_var_estado; j++) { BaseReglas[i].Ant[j].x0 = Double.parseDouble(sT.nextToken()); BaseReglas[i].Ant[j].x1 = Double.parseDouble(sT.nextToken()); BaseReglas[i].Ant[j].x2 = BaseReglas[i].Ant[j].x1; BaseReglas[i].Ant[j].x3 = Double.parseDouble(sT.nextToken()); BaseReglas[i].Ant[j].y = 1.0; k = repetida = 0; while (k < i && repetida == 0) { if (BaseReglas[i].Ant[j].x0==BaseReglas[k].Ant[j].x0 && BaseReglas[i].Ant[j].x1==BaseReglas[k].Ant[j].x1 && BaseReglas[i].Ant[j].x3==BaseReglas[k].Ant[j].x3) { repetida = 1; } else { k++; } } if (repetida == 0) this.n_etiq_distintas++; } for (j = 0; j < tabla.n_variables; j++) { BaseReglas[i].Cons[j] = Double.parseDouble(sT.nextToken()); } } } /* ------------------------------------------------------------------------- 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].Ant[0]); for (b2 = 1; (minimo != 0.0) && (b2 < tabla.n_var_estado); b2++) { y = Fuzzifica(entradas[b2], BaseReglas[b].Ant[b2]); if (y < minimo) { minimo = y; } } GradoEmp[b] = minimo; } } /* ------------------------------------------------------------------------- Inference of a TSK Fuzzy System ------------------------------------------------------------------------- */ public double Inferencia_TSK(double[] Entrada) { double num, den, salida_regla; int i, j; num = 0; den = 0; for (i = 0; i < n_reglas; i++) { if (GradoEmp[i] != 0.0) { /* we initialize the output to the 'b' value */ salida_regla = BaseReglas[i].Cons[tabla.n_var_estado]; for (j = 0; j < tabla.n_var_estado; j++) { salida_regla += BaseReglas[i].Cons[j] * Entrada[j]; } num += GradoEmp[i] * salida_regla; den += 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 ------------------------------------------------------------------------- */ public double FLC_TSK(double[] Entrada) { Min(Entrada); return (Inferencia_TSK(Entrada)); } /* ------------------------------------------------------------------------- Generic Function ------------------------------------------------------------------------- */ /** If "Antecedente" has positive examples it's stored in the structure "Pob_reglas" */ void CompruebaEjemplos(int[] Antecedente, Adap fun_adap) { int i, hay_ejemplos, etiqueta, pos_individuo; for (i = 0; i < tabla.n_var_estado; i++) { etiqueta = Antecedente[i]; pos_individuo = tabla.n_var_estado + 3 * i; cromosoma[i] = (double) etiqueta; cromosoma[pos_individuo] = base_datos.BaseDatos[i][etiqueta].x0; cromosoma[pos_individuo + 1] = base_datos.BaseDatos[i][etiqueta].x1; cromosoma[pos_individuo + 2] = base_datos.BaseDatos[i][etiqueta].x3; } i = hay_ejemplos = 0; /* we look for a positive example */ while (i < tabla.long_tabla && hay_ejemplos == 0) { if (fun_adap.AntecedenteCubreEjemplo(cromosoma, tabla.datos[i].ejemplo) > 0) { hay_ejemplos = 1; } else { i++; } } /* if there are positive examples the antecedent is stored in "Pob_reglas" */ if (hay_ejemplos > 0) { for (i = 0; i < tabla.n_var_estado; i++) { Pob_reglas[n_reglas][i] = Antecedente[i]; } n_reglas++; } } /** Returns all possible antecedents with positive examples*/ void RecorreAntecedentes(int[] Regla_act, int pos, Adap fun_adap) { int i; if (pos == tabla.n_var_estado) { CompruebaEjemplos(Regla_act, fun_adap); } else { for (Regla_act[pos] = 0; Regla_act[pos] < base_datos.n_etiquetas[pos]; Regla_act[pos]++) { RecorreAntecedentes(Regla_act, pos + 1, fun_adap); } } } /** Generates all possible antecedents */ void Generate(Adap fun_adap) { int i, j, k, etiqueta; double grado_pertenencia, max_pert; n_reglas = 0; RecorreAntecedentes(Regla_act, 0, fun_adap); } /** Inserts a rule in the RB */ public void inserta_regla(int regla, double[] datos) { int i, pos_individuo; for (i = 0; i < tabla.n_var_estado; i++) { pos_individuo = tabla.n_var_estado + 3 * i; ListaTabu[regla][i] = datos[pos_individuo + 1]; BaseReglas[regla].Ant[i].x0 = datos[pos_individuo]; BaseReglas[regla].Ant[i].x1 = datos[pos_individuo + 1]; BaseReglas[regla].Ant[i].x2 = datos[pos_individuo + 1]; BaseReglas[regla].Ant[i].x3 = datos[pos_individuo + 2]; BaseReglas[regla].Ant[i].y = 1.0; /* 'a' values of the consequent */ BaseReglas[regla].Cons[i] = Math.tan(datos[tabla.n_var_estado + tabla.n_var_estado * 3 + i]); } /* 'b' value of the consequent */ BaseReglas[regla].Cons[i] = Math.tan(datos[tabla.n_var_estado + tabla.n_var_estado * 4]); } /** 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_var_estado; j++) { cadena += "" + BaseReglas[i].Ant[j].x0 + " " + BaseReglas[i].Ant[j].x1 + " " + BaseReglas[i].Ant[j].x3 + "\n"; } for (j = 0; j < tabla.n_variables; j++) { cadena += BaseReglas[i].Cons[j] + " "; } cadena += "\n\n"; } return (cadena); } }