/***********************************************************************
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.PSO_Learning.REPSO;
/**
* <p>Title: Particle</p>
*
* <p>Company: KEEL</p>
*
* @author Jose A. Saez Munoz
* @version 1.0
*/
import org.core.*;
public class Particle {
public double[] X; //position
public double[] V; //velocity
public double[] B; //particle best position
public int dim; //number of dimensions
public double bestEvaluation; //particle's best evaluation
public double lastEvaluation; //particle's last evaluation
public int TP, TN, FP, FN; //particle evaluation parameters
public int clase; //particle class
//static fields
static double constrictionCoefficient;
static double WeightsUpperLimit;
static double vmax;
static double vmin;
static double w1;
static double w2;
static double w3;
static double Interesting;
static int numAttributes; //number of atttributes in the dataset
static public void InitializeParameters(double c, double w, double _pvmax, double _pvmin, double _pw1, double _pw2, double _pw3, double _pInteresting, int na){
constrictionCoefficient=c;
WeightsUpperLimit=w;
vmax = _pvmax;
vmin = _pvmin;
w1 = _pw1;
w2 = _pw2;
w3 = _pw3;
Interesting = _pInteresting;
numAttributes=na;
}
//*********************************************************************
//***************** Particle constructor ******************************
//*********************************************************************
public Particle(int cl){
dim=numAttributes*3;
X=new double[dim];
V=new double [dim];
B=new double [dim];
TP=0;TN=0;FP=0;FN=0;
bestEvaluation=-1;
lastEvaluation=-1;
clase=cl;
}
//*********************************************************************
//***************** Random initialization ****************************
//*********************************************************************
public void randomInitialization(){
for(int i=0 ; i<dim ; ++i){
X[i]=Randomize.RanddoubleClosed(0, 1);
B[i]=X[i];
V[i]=Randomize.RanddoubleClosed(vmin,vmax);
}
}
//*********************************************************************
//***************** Fitness function **********************************
//*********************************************************************
public double evaluation(){
if(computeNumConditions()==0)
return -1;
ParametrosPreEvaluacion();
double Accuracy = ((double)TP/(double)(TP+FP));
double Coverage = ((double)TP/(double)(TP+FN));
double Succinctness = 1-(computeNumConditions()-1)/numAttributes;
double fitness = w1*(Accuracy*Coverage)+w2*Succinctness+w3*Interesting;
return fitness;
}
public int computeNumConditions(){
int res=0;
for(int i=0 ; i<numAttributes ; ++i)
if(GetAttributePresence(i))
res++;
return res;
}
public boolean GetAttributePresence(int i){
if(X[i]>0.5)
return true;
else
return false;
}
//*********************************************************************
//***************** Pre-evaluation parameters *************************
//*********************************************************************
public void ParametrosPreEvaluacion(){
TP=0;TN=0;FP=0;FN=0;
for(int i=0 ; i<REPSO.train.getnData() ; ++i){
if(!REPSO.train.getRemoved(i)){
//veo si coincide el antecedente
if(CoverInstance(REPSO.train.getExample(i))){
if(REPSO.train.getOutputAsInteger(i)==clase)
TP++;
else
FP++;
}
else{
if(REPSO.train.getOutputAsInteger(i)==clase)
FN++;
else
TN++;
}
}
}
}
//*********************************************************************
//***************** Instance coverage ********************************
//*********************************************************************
public Boolean CoverInstance(double[] instance){
//veo si coincide el antecedente
for(int d=0 ; d<numAttributes ; ++d){
if(GetAttributePresence(d)){
if(REPSO.train.getTipo(d)==myDataset.NOMINAL){
if(!CoverNominalAttribute(instance[d],d))
return false;
}
if(REPSO.train.getTipo(d)==myDataset.INTEGER){
if(!CoverIntegerAttribute(instance[d],d))
return false;
}
if(REPSO.train.getTipo(d)==myDataset.REAL){
if(!CoverRealAttribute(instance[d],d))
return false;
}
}
}
return true;
}
private Boolean CoverIntegerAttribute(double vi, int d){
double vr = X[numAttributes*2+d];
double max[]=REPSO.train.getemax();
double min[]=REPSO.train.getemin();
double rango=max[d]-min[d];
double x1=Math.ceil(vr*rango)+min[d];
//obenter operador
if(X[numAttributes+d]>0.5)
return vi==x1;
else
return vi!=x1;
}
private Boolean CoverRealAttribute(double vi, int d){
double vr = X[numAttributes*2+d];
//obtener valor de la instancia
double max[]=REPSO.train.getemax();
double min[]=REPSO.train.getemin();
double rango=max[d]-min[d];
double x1=vr*rango+min[d];
//obenter operador
if(X[numAttributes+d]>0.5)
return vi>=x1;
else
return vi<x1;
}
private Boolean CoverNominalAttribute(double vi, int d){
double vr = X[numAttributes*2+d];
int rango=(int)REPSO.train.devuelveRangos()[d][1];
double x1=Math.ceil(vr*rango);
//obenter operador
if(X[numAttributes+d]>0.5)
return vi==x1;
else
return vi!=x1;
}
//*********************************************************************
//***************** Set best position and set actual position ********
//*********************************************************************
public void setB(double[] x, double be){
for(int i=0 ; i<dim ; ++i)
B[i]=x[i];
bestEvaluation=be;
}
public void setX(double[] x){
for(int i=0 ; i<dim ; ++i)
X[i]=x[i];
}
//*********************************************************************
//***************** Update velocity and position **********************
//*********************************************************************
public void updateV(Particle G, double wv){
for(int i=0 ; i<dim ; ++i){
double c1=Randomize.RanddoubleClosed(0,WeightsUpperLimit);
double c2=Randomize.RanddoubleClosed(0,WeightsUpperLimit);
V[i]=constrictionCoefficient*( wv*V[i] + (c1*(B[i]-X[i])) + (c2*(G.B[i]-X[i])) );
if(V[i]>vmax) V[i]=vmax;
if(V[i]<vmin) V[i]=vmin;
}
}
public void updateX(){
for(int i=0 ; i<dim ; ++i){
X[i]=X[i]+V[i];
if(X[i]>1)X[i]=1;
if(X[i]<0)X[i]=0;
}
}
//*********************************************************************
//***************** Clone the particle ********************************
//*********************************************************************
public Particle cloneParticle(){
Particle newParticle=new Particle(clase);
for(int i=0 ; i<dim ; ++i){
newParticle.X[i]=X[i];
newParticle.V[i]=V[i];
newParticle.B[i]=B[i];
}
newParticle.dim=dim;
newParticle.bestEvaluation=bestEvaluation;
newParticle.lastEvaluation=lastEvaluation;
newParticle.TP=TP;
newParticle.TN=TN;
newParticle.FP=FP;
newParticle.FN=FN;
newParticle.clase=clase;
return newParticle;
}
//*********************************************************************
//***************** Compare two particles *****************************
//*********************************************************************
public boolean isBetter(Particle p2){
if(bestEvaluation>p2.bestEvaluation)
return true;
if(bestEvaluation==p2.bestEvaluation && presentAttsBest()<p2.presentAttsBest())
return true;
return false;
}
public int presentAttsBest(){
int cont=0;
for(int i=0 ; i<numAttributes ; ++i)
if(B[i]>0.5)
cont++;
return cont;
}
//*********************************************************************
//***************** Default rule **************************************
//*********************************************************************
public void setAsDefaultRule(){
for(int i=0 ; i<numAttributes ;++i)
X[i]=0;
}
//*********************************************************************
//***************** Return operator of an attribute *******************
//*********************************************************************
public String getOperator(int i){
if(REPSO.train.getTipo(i)==myDataset.INTEGER){
if(B[numAttributes+i]>0.5)
return " = ";
else
return " != ";
}
if(REPSO.train.getTipo(i)==myDataset.NOMINAL){
if(B[numAttributes+i]>0.5)
return " = ";
else
return " != ";
}
if(REPSO.train.getTipo(i)==myDataset.REAL){
if(B[numAttributes+i]>0.5)
return " >= ";
else
return " < ";
}
return "";
}
//*********************************************************************
//***************** Return operator of an attribute *******************
//*********************************************************************
public String getDomainValue(int i){
if(REPSO.train.getTipo(i)==myDataset.INTEGER){
double vr = X[numAttributes*2+i];
double max[]=REPSO.train.getemax();
double min[]=REPSO.train.getemin();
double rango=max[i]-min[i];
Double x1=Math.ceil(vr*rango)+min[i];
return x1.toString();
}
if(REPSO.train.getTipo(i)==myDataset.NOMINAL){
double vr = X[numAttributes*2+i];
int rango=(int)REPSO.train.devuelveRangos()[i][1];
double x1=Math.ceil(vr*rango);
int res;
if(x1==0)
res=0;
else
res=(int)x1;
Integer sol=new Integer(res);
return sol.toString();
}
if(REPSO.train.getTipo(i)==myDataset.REAL){
double vr = X[numAttributes*2+i];
//obtener valor de la instancia
double max[]=REPSO.train.getemax();
double min[]=REPSO.train.getemin();
double rango=max[i]-min[i];
Double x1=vr*rango+min[i];
return x1.toString();
}
return "";
}
}