/***********************************************************************
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.Fuzzy_Rule_Learning.Genetic.ClassifierSLAVE;
/**
* <p>
* @author Written by Francisco Jos� Berlanga (University of Ja�n) 01/01/2007
* @version 1.0
* @since JDK 1.6
* </p>
*/
import java.util.*;
public class VectorVar {
/**
* <p>
* Defines a list of variables
* </p>
*/
int numero;
variable_t[] lista;
/**
* <p>
* Default Constructor
* </p>
*/
VectorVar() {
numero = 0;
lista = new variable_t[0];
}
/**
* <p>
* Constructor
* </p>
* @param tamano int The number of variables in the list
*/
VectorVar(int tamano) {
numero = tamano;
lista = new variable_t[tamano];
}
/**
* <p>
* Creates a list of variables as a copy of another list
* </p>
* @param x VectorVar The list of variable used to create the new one
*/
VectorVar(VectorVar x) {
numero = x.numero;
lista = new variable_t[numero];
for (int i = 0; i < numero; i++) {
lista[i] = new variable_t(x.lista[i]);
}
}
/**
* <p>
* Creates a list of variables using the information in a set of examples
* </p>
* @param dataset myDataset The set of examples
* @param num_etiquetas int The number of label per each variable in the list
*/
VectorVar(myDataset dataset, int num_etiquetas) {
String nom_var;
int n_var_entradas, n_clases;
boolean antecedente, activa;
activa = true;
numero = dataset.getnVars();
lista = new variable_t[numero];
for (int i = 0; i < numero; i++) {
lista[i] = new variable_t();
}
double[] min = new double[numero];
double[] max = new double[numero];
min = dataset.getemin();
max = dataset.getemax();
n_var_entradas = dataset.getnInputs();
for (int j = 0; j < n_var_entradas; j++) {
nom_var = "X" + j;
lista[j].Set(num_etiquetas, min[j], max[j], false, false,
nom_var);
// lista[j].PrintDefinition();
}
// Now the class
n_clases = dataset.getnClasses();
double[] clases_num = new double[n_clases];
String[] clases_nomb = new String[n_clases];
for (int i = 0; i < n_clases; i++) {
clases_nomb[i] = dataset.getOutputValue(i);
clases_num[i] = (double) i;
}
nom_var = "Class";
lista[n_var_entradas].Set(nom_var, n_clases, clases_nomb, clases_num);
// lista[n_var_entradas].PrintDefinition();
}
/**
* <p>
* Copies the variable "x" in the position "pos" of the list
* </p>
* @param pos int The position in the list
* @param x variable_t The variable
*/
public void Set(int pos, variable_t x) {
if (pos < numero) {
lista[pos] = new variable_t(x);
} else {
System.out.println("The position does not exist");
}
}
/**
* <p>
* It returns the number of antecedents in the list of variables
* </p>
* @return int The number of antecedents in the list of variables
*/
public int N_Antecedents() {
int s = 0;
for (int i = 0; i < numero; i++) {
if (lista[i].IsActive() && lista[i].IsAntecedent()) {
s++;
}
}
return s;
}
/* public void Encode(Integer tb, Integer te) {
System.out.println("Tama[0]: "+tb.intValue()+", Rango[0]:"+te.intValue());
int tb_aux, te_aux;
tb_aux = tb.intValue();
te_aux = te.intValue();
tb_aux = 0;
for (int i = 0; i < numero; i++) {
if (lista[i].IsActive() && lista[i].IsAntecedent()) {
tb_aux += lista[i].N_labels();
} else if (lista[i].IsActive() && !lista[i].IsAntecedent()) {
te_aux = lista[i].N_labels();
}
}
tb = Integer.valueOf(tb_aux);
te = Integer.valueOf(te_aux);
System.out.println("Tama[0]: "+tb.intValue()+", Rango[0]:"+te.intValue());
}
*/
/**
* <p>
* Obtains the number of active antecedent variables and consequent variables in the list
* </p>
* @param milista ArrayList<Integer> It keeps the the number of active antecedent variables and consequent variables in the list
*/
public void Encode(ArrayList<Integer> milista) {
Integer tb, te;
tb = milista.get(0);
te = milista.get(1);
// System.out.println("Tama[0]: "+tb.intValue()+", Rango[0]:"+te.intValue());
int tb_aux, te_aux;
tb_aux = tb.intValue();
te_aux = te.intValue();
tb_aux = 0;
for (int i = 0; i < numero; i++) {
if (lista[i].IsActive() && lista[i].IsAntecedent()) {
tb_aux += lista[i].N_labels();
} else if (lista[i].IsActive() && !lista[i].IsAntecedent()) {
te_aux = lista[i].N_labels();
}
}
tb = Integer.valueOf(tb_aux);
te = Integer.valueOf(te_aux);
// System.out.println("Tama[0]: "+tb.intValue()+", Rango[0]:"+te.intValue());
milista.add(0, tb);
milista.add(1, te);
}
/**
* <p>
* Prints in the standard output the definition of the variable in position "variable" in the list
* </p>
*/
public void PrintDefinition(int variable) {
if (variable >= 0 && variable < numero) {
lista[variable].PrintDefinition();
} else {
System.out.println("That variable does not exist");
}
}
/**
* <p>
* Prints in a String the definition of all the variables in the list
* </p>
* @return String The definition of all the variables in the list
*/
public String PrintDefinitionToString() {
String cadena = "";
for (int i = 0; i < numero; i++) {
cadena += lista[i].PrintDefinitionToString() + "\n";
}
return (cadena);
}
/**
* <p>
* Prints in the standard output the definition of all the variables in the list
* </p>
*/
public void PrintDefinition() {
for (int i = 0; i < numero; i++) {
lista[i].PrintDefinition();
}
}
/**
* <p>
* Prints in the standard output the name of the variable in position "variable" in the list
* </p>
*/
public void PrintVar(int variable) {
lista[variable].PrintVar();
}
/**
* <p>
* Returns a string with the name of the variable in position "variable" in the list
* </p>
* @return String The name of the variable in position "variable" in the list
*/
public String SPrintVar(int variable) {
return lista[variable].SPrintVar();
}
/**
* <p>
* Prints in the standard ouput the name of the label "value" of the variable in position "variable" in the list.
* </p>
* @param variable int The variable in position in the list
* @param value int The label of the variable
*/
public void PrintDomain(int variable, int value) {
lista[variable].PrintDomain(value);
}
/**
* <p>
* Returns a string with the name of the label "value" of the variable in position "variable" in the list.
* </p>
* @param variable int The variable in position in the list
* @param value int The label of the variable
* @return String The name of the label "value" of the variable.
*/
public String SPrintDomain(int variable, int value) {
return lista[variable].SPrintDomain(value);
}
/**
* <p>
* Returns if the variable in position "variable" is considered in the learning process.
* </p>
* @param variable int The variable in position in the list
* @return boolean TRUE is the variable is considered in the learning process. FALSE otherwise
*/
public boolean IsActive(int variable) {
return lista[variable].IsActive();
}
/**
* <p>
* Retuns if the variable in position "variable" is an antecedent of the rule.
* </p>
* @param variable int The variable in position in the list
* @return boolean TRUE is the variable is an antecedent of the rule. FALSE otherwise
*/
public boolean IsAntecedent(int variable) {
return lista[variable].IsAntecedent();
}
/**
* <p>
* Retuns the number of variables in the list
* </p>
* @return int The number of variables in the list
*/
public int TotalVariables() {
return numero;
}
/**
* <p>
* Retuns the number of labels in the variable in position "variable" of the list domain.
* </p>
* @param variable int The variable in position in the list
* @return int The number of labels in the variable's domain.
*/
public int SizeDomain(int variable) {
return lista[variable].SizeDomain();
}
/**
* <p>
* Returns the adaptation degree of a certain value x to the variable in position "variable" of the list.
* </p>
* @param x double The value
* @param variable int The variable in position in the list
* @return double the adaptation degree of a value x to the domain of the variable.
*/
public double Adaptation(double x, int variable) {
if (variable >= 0 && variable < numero) {
return lista[variable].Adaptation(x);
} else {
System.out.println("That variable does not exist");
return ( -1);
//exit(1);
}
}
/**
* <p>
* Returns the adaptation degree of a certain value x to the label "dominio" of the variable in position "variable" of the list.
* </p>
* @param x double The value
* @param variable int The variable in position in the list
* @param dominio int The label in the domain
* @return double the adaptation degree of a value x to the domain of the variable.
*/
public double Adaptation(double x, int variable, int dominio) {
if (variable >= 0 && variable < numero) {
return lista[variable].Adaptation(x, dominio);
} else {
System.out.println("That variable does not exist");
return ( -1);
//exit(1);
}
}
/**
* <p>
* Returns the adaptation degree of a certain value x to a set of label "dominio" of the variable in position "variable" of the list.
* Param "dominio" is given as an ordered vector (String of strings) with zeros and ones
* representing the absence or the presence, respectively.
* </p>
* @param x double The value
* @param variable int The variable in position in the list
* @param dominio String The set of labels in the domain
* @return double the adaptation degree of a value x to the domain.
*/
public double Adaptation(double x, int variable, String dominio) {
if (variable >= 0 && variable < numero) {
return lista[variable].Adaptation(x, dominio);
} else {
System.out.println("That variable does not exist");
return ( -1);
//exit(1);
}
}
/**
* <p>
* Returns the adaptation degree of set of values in "x" to a set rules enconded in a String
* </p>
* @param x vectordouble The vector of values
* @param regla String The set of rules
* @return double the adaptation degree.
*/
public double Adaptation(vectordouble x, String regla) {
double max = 1, aux;
String sub;
int trozo = 0, tam;
for (int i = 0; i < numero && max > 0; i++) {
if (lista[i].IsActive() && lista[i].IsAntecedent()) {
tam = lista[i].N_labels();
sub = regla.substring(trozo, trozo+tam);
aux = lista[i].Adaptation(x.At(i), sub);
if (aux < max) {
max = aux;
}
trozo += tam;
}
}
return max;
}
private int NumActiveLabels(String sub, int tam) {
int n = 0;
char[] array_sub = new char[sub.length()];
array_sub = sub.toCharArray();
for (int i = 0; i < tam; i++) {
if (array_sub[i] == '1') {
n++;
}
}
return n;
}
private void SequenceOfActiveLabels(String sub, int tam, ArrayList<int[]> milista) {
int[] list = new int[3];
list = milista.get(0);
int unos, ceros, n_unos;
char[] array_sub = new char[sub.length()];
array_sub = sub.toCharArray();
int n = 0;
unos = list[0];
ceros = list[1];
n_unos = list[2];
boolean last_uno;
int i = 1;
if (array_sub[0] == '0') {
ceros++;
last_uno = false;
} else {
unos++;
last_uno = true;
n_unos++;
} while (i < tam) {
if (array_sub[i] == '1') {
n_unos++;
}
if (last_uno && array_sub[i] == '0') {
last_uno = false;
ceros++;
} else if (!last_uno && array_sub[i] == '1') {
last_uno = true;
unos++;
}
i++;
}
list[0] = unos;
list[1] = ceros;
list[2] = n_unos;
milista.add(0, list);
}
/**
* <p>
* Returns if the set rules encoded in the String "regla" is valid or not. Its simplicity is also calculated
* </p>
* @param regla String The set of rules
* @param var double[] Contains the information measure for each variable
* @param umbral double Activation threshold (only variable with its information measure equal o greater than this value are considered in the rule).
* @param milista ArrayList<Double> Keeps the simplicity of the rule
* @return boolean TRUE if all the rules in the set of rules are valid. FALSE otherwise
*/
public boolean Is_Valid(String regla, double[] var, double umbral,
ArrayList<Double> milista) {
Double aux1 = milista.get(0);
double simplicidad = aux1.doubleValue();
String sub;
int trozo = 0, tam;
int [] list = new int[3];
for(int i = 0; i < 3; i++){
list[i] = 0;
}
int unos, ceros, n_unos;
int i = 0;
simplicidad = 0.0;
boolean valida = true;
while (i < numero && valida) {
if (lista[i].IsActive() && lista[i].IsAntecedent()) {
tam = lista[i].N_labels();
if (var[i] >= umbral) {
sub = regla.substring(trozo, trozo+tam);
//unos = NumActiveLabels(sub,tam);
ArrayList<int[]> lista1 = new ArrayList<int[]>(1);
lista1.add(list);
SequenceOfActiveLabels(sub, tam, lista1);
list = lista1.get(0);
unos = list[0];
ceros = list[1];
n_unos = list[2];
valida = (unos != 0);
if (valida) {
if (unos == 1 || ceros == 1) {
simplicidad = simplicidad + 1.0;
}
}
}
trozo += tam;
}
i++;
}
aux1 = Double.valueOf(simplicidad);
milista.add(0, aux1);
return valida;
}
/**
* <p>
* Returns the adaptation degree of set of values in "x" to a set rules enconded in a String, taking into account the activation
* threshold for the variables
* </p>
* @param x vectordouble The vector of values
* @param regla String The set of rules
* @param var double[] Contains the information measure for each variable
* @param umbral double Activation threshold (only variable with its information measure equal o greater than this value are considered in the rule).
* @return double the adaptation degree.
*/
public double Adaptation(vectordouble x, String regla, double[] var,
double umbral) {
double max = 1, aux;
String sub;
int trozo = 0, tam, unos;
for (int i = 0; i < numero && max > 0; i++) {
// System.out.println("Trozo es "+trozo+", Tam es "+lista[i].N_labels()+" y Regla mide "+regla.length());
if (lista[i].IsActive() && lista[i].IsAntecedent()) {
tam = lista[i].N_labels();
if (var[i] >= umbral) {
// System.out.println("Regla: " + regla+", ("+trozo+","+tam+")");
sub = regla.substring(trozo, trozo+tam);
// System.out.println("Sub: " + sub);
unos = NumActiveLabels(sub, tam);
if (unos == 0) {
max = 0;
} else if (unos < tam) {
aux = lista[i].Adaptation(x.At(i), sub);
if (aux < max) {
max = aux;
}
}
}
trozo += tam;
}
}
return max;
}
/**
* <p>
* Returns the adaptation degree of set of values in "x" to a set rules enconded in a String, taking into account the activation
* threshold for the variables
* </p>
* @param x vectordouble The vector of values
* @param regla String The set of rules
* @param var double[] Contains the information measure for each variable
* @param umbral double Activation threshold (only variable with its information measure equal o greater than this value are considered in the rule).
* @param umbral2 double Minimum adaptation threshold.
* @return double The adaptation degree if it is greater or equal to the minium adaptation threshold. 0 otherwise.
*/
public double Adaptation(vectordouble x, String regla, double[] var,
double umbral, double umbral2) {
double max = 1, aux;
String sub;
int trozo = 0, tam, unos;
if (umbral2 < 0) {
umbral2 = -umbral2;
}
for (int i = 0; i < numero && max >= umbral2 && max > 0; i++) {
if (lista[i].IsActive() && lista[i].IsAntecedent()) {
tam = lista[i].N_labels();
if (var[i] >= umbral) {
sub = regla.substring(trozo, trozo+tam);
unos = NumActiveLabels(sub, tam);
if (unos == 0) {
max = 0;
} else if (unos < tam) {
aux = lista[i].Adaptation(x.At(i), sub);
if (aux < max) {
max = aux;
}
}
}
trozo += tam;
}
}
if (max >= umbral2) {
return max;
} else {
return 0;
}
}
/**
* <p>
* Calculates the adaptation degree of set of values in "x" to a certain label "etiq". Also calculates the adaptation
* degree to its complementary, that is, the rest of labels in the variable (not including "etiq").
* </p>
* @param x vectordouble The vector of values
* @param etiq int The label in the variable
* @param milista ArrayList <double[]> Keeps the adaptation to the label and its complementary value
*/
public void AdaptationC(vectordouble x, int etiq, ArrayList<double[]> milista){
double[] aux1 = new double[2];
aux1 = milista.get(0);
double pos = aux1[0];
double neg = aux1[1];
double valor, aux;
int i = 0;
while (lista[i].IsAntecedent() && i < numero - 1) {
i++;
}
valor = x.At(i);
pos = lista[i].Adaptation(valor, etiq);
neg = 0.0;
for (int j = 0; j < lista[i].N_labels(); j++) {
if (j != etiq) {
aux = lista[i].Adaptation(valor, j);
if (aux > neg) {
neg = aux;
}
}
}
aux1[0] = pos;
aux1[1] = neg;
milista.add(0, aux1);
}
/**
* <p>
* Returns the area of the label number "lab" in the variable in position "var" of the list.
* </p>
* @param var int The position of the variable
* @param lab int The label number
* @return double The area of the label number "l" in the variable in position "var" of the list.
*/
public double Area(int var, int lab) {
return lista[var].Area(lab);
}
/**
* <p>
* Returns a fuzzy_t object with the definition of the label number "lab" in the variable in position "var" of the list.
* </p>
* @param var int The position of the variable
* @param lab int The label number
* @return fuzzy_t A fuzzy_t object with the definition of the label number "lab" in the variable in position "var" of the list.
*/
public fuzzy_t FuzzyLabel(int var, int lab) {
return lista[var].FuzzyLabel(lab);
}
/**
* <p>
* Returns the central value of the label number "lab" in the variable in position "var" of the list.
* </p>
* @param var int The position of the variable
* @param lab int The label number
* @return double The central value of the label number "lab" in the variable in position "var" of the list.
*/
public double CenterLabel(int var, int lab) {
return lista[var].CenterLabel(lab);
}
/**
* <p>
* Returns if the domain associated to the variable in position "var" of the list is only formed by crisp values.
* </p>
* @param var int The position of the variable
* @return TRUE if the domain associated to the variable in position "var" of the list is only formed by crisp values. FALSE otherwise
*/
public boolean IsDiscrete(int var) {
return lista[var].IsDiscrete();
}
/**
* <p>
* Returns if the domain associated to the variable in position "var" of the list is only formed by intervals.
* </p>
* @param var int The position of the variable
* @return TRUE if the domain associated to the variable in position "var" of the list is only formed by intervals. FALSE otherwise
*/
public boolean IsInterval(int var) {
return lista[var].IsInterval();
}
/**
* <p>
* Returns if the domain associated to the variable in position "var" of the list is only formed by fuzzy sets.
* </p>
* @param var int The position of the variable
* @return TRUE if the domain associated to the variable in position "var" of the list is only formed by fuzzy sets. FALSE otherwise
*/
public boolean IsFuzzy(int var) {
return lista[var].IsFuzzy();
}
/**
* <p>
* Creates a new domain_t object containing the domain of the variable in position "var" of the list
* </p>
* @param var int The position of the variable
* @return domain_t A new domain_t object containing the domain of the variable in position "var" of the list
*/
public domain_t Domain(int var) {
domain_t aux = new domain_t(lista[var].Domain());
return aux;
}
/**
* <p>
* Creates a new variable_t object containing the variable in position "var" of the list
* </p>
* @param var int The position of the variable
* @return domain_t A new varible_t object containing the variable in position "var" of the list
*/
public variable_t Variable(int var) {
variable_t aux = new variable_t(lista[var].Variable());
return aux;
}
/**
* <p>
* Returns the lower value of the definition interval of variable in position "var" of the list
* </p>
* @param var int The position of the variable
* @return double The lower value of the definition interval of variable in position "var" of the list
*/
public double Inf_Range(int var) {
return lista[var].Inf_Range();
}
/**
* <p>
* Returns the upper value of the definition interval of variable in position "var" of the list
* </p>
* @param var int The position of the variable
* @return double The upper value of the definition interval of variable in position "var" of the list
*/
public double Sup_Range(int var) {
return lista[var].Sup_Range();
}
/**
* <p>
* Returns the position of the consequent inside the list of variables
* </p>
* @return int The position of the consequent inside the list of variables
*/
public int Consequent() {
int i = 0;
while ((lista[i].IsAntecedent() || !lista[i].IsActive()) && i < numero) {
i++;
}
if (i != numero) {
return i;
} else {
System.out.println("There is not consequent variable");
return ( -1);
}
}
}