/***********************************************************************
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.CPSO;
/**
* <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 Boolean[] AttribPr; //attribute presence
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 indifferenceThreshold;
static double constrictionCoefficient;
static double WeightsUpperLimit;
static public void InitializeParameters(double t, double c, double w){
indifferenceThreshold=t;
constrictionCoefficient=c;
WeightsUpperLimit=w;
}
//*********************************************************************
//***************** Particle constructor ******************************
//*********************************************************************
public Particle(int tam, int cl){
dim=tam;
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;
AttribPr=new Boolean [dim/2];
for(int d=0 ; d<dim/2 ; ++d)
AttribPr[d]=true;
}
//*********************************************************************
//***************** Random initialization ****************************
//*********************************************************************
public void randomInitialization(){
for(int i=0 ; i<dim ; ++i){
if(i<dim/2 && CPSO.train.getTipo(i)==myDataset.NOMINAL )
X[i]=Randomize.RanddoubleClosed(0, 1);
else
X[i]=Randomize.RanddoubleClosed(0, indifferenceThreshold);
B[i]=X[i];
V[i]=Randomize.RanddoubleClosed((-1)*indifferenceThreshold, indifferenceThreshold);
}
}
//*********************************************************************
//***************** Fitness function **********************************
//*********************************************************************
public double evaluation(){
//if particle leaves space search...
// a) see centers
for(int i=0 ; i<dim/2 ; ++i)
if(X[i]>1 || X[i]<0)
return -1;
// b) see radius if attribute is not nominal
for(int i=dim/2 ; i<dim ; ++i)
if(CPSO.train.getTipo(i-(dim/2))!=myDataset.NOMINAL && (X[i]>1 || X[i]<0))
return -1;
// c) see number of presents attributes
int cont=0;
for(int i=0 ; i<dim/2 ; ++i)
if(X[i]<indifferenceThreshold)
cont++;
if(cont==0)
return -1;
//otherwise...
ParametrosPreEvaluacion();
double res=((double)TP/(double)(TP+FN))*((double)TN/(double)(TN+FP));
return res;
}
//*********************************************************************
//***************** Pre-evaluation parameters *************************
//*********************************************************************
public void ParametrosPreEvaluacion(){
TP=0;TN=0;FP=0;FN=0;
for(int i=0 ; i<CPSO.train.getnData() ; ++i){
if(!CPSO.train.getRemoved(i)){
//veo si coincide el antecedente
if(CoverInstance(CPSO.train.getExample(i))){
if(CPSO.train.getOutputAsInteger(i)==clase)
TP++;
else
FP++;
}
else{
if(CPSO.train.getOutputAsInteger(i)==clase)
FN++;
else
TN++;
}
}
}
}
//*********************************************************************
//***************** Instance coverage ********************************
//*********************************************************************
public Boolean CoverInstance(double[] instance){
//veo si coincide el antecedente
for(int d=0 ; d<dim/2 ; ++d){
if(GetAttributePresence(d)){
if(CPSO.train.getTipo(d)==myDataset.INTEGER || CPSO.train.getTipo(d)==myDataset.REAL){
if(!CoverNumericalAttribute(X[d],X[(dim/2)+d],instance[d]))
return false;
}
if(CPSO.train.getTipo(d)==myDataset.NOMINAL){
if(!CoverNominalAttribute(X[d],instance[d],d))
return false;
}
}
}
return true;
}
private Boolean CoverNumericalAttribute(double v1, double v2, double vi){
if( (v1>=indifferenceThreshold) || ((v1-v2)<=vi && (v1+v2)>=vi) )
return true;
else
return false;
}
private Boolean CoverNominalAttribute(double v1, double vi, int d){
int rango=(int)CPSO.train.devuelveRangos()[d][1]+1;
int x1=(int)((v1*rango)/indifferenceThreshold);
int x2=(int)((vi*rango)/indifferenceThreshold);
if( (v1>=indifferenceThreshold) || (x1==x2) )
return true;
else
return false;
}
//*********************************************************************
//***************** 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){
for(int i=0 ; i<dim ; ++i){
double c1=Randomize.RanddoubleClosed(0,WeightsUpperLimit);
double c2=Randomize.RanddoubleClosed(0,WeightsUpperLimit);
V[i]=constrictionCoefficient*( V[i] + (c1*(B[i]-X[i])) + (c2*(G.B[i]-X[i])) );
if(V[i]>indifferenceThreshold/10) V[i]=indifferenceThreshold/10;
if(V[i]<(-1*(indifferenceThreshold/10))) V[i]=(-1*(indifferenceThreshold/10));
}
}
public void updateX(){
for(int i=0 ; i<dim ; ++i)
X[i]=X[i]+V[i];
}
//*********************************************************************
//***************** Clone the particle ********************************
//*********************************************************************
public Particle cloneParticle(){
Particle newParticle=new Particle(dim, 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;
for(int i=0 ; i<dim/2 ; ++i)
newParticle.AttribPr[i]=AttribPr[i];
return newParticle;
}
public void SetAttributePresence(int pos, Boolean presence){
AttribPr[pos]=presence;
}
public Boolean GetAttributePresence(int pos){
return AttribPr[pos];
}
public void fixAttributePresence(){
for(int i=0 ; i<dim/2 ; ++i)
if(B[i]>=indifferenceThreshold && B[i]<=1)
SetAttributePresence(i,false);
else
SetAttributePresence(i,true);
}
//*********************************************************************
//***************** 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<dim/2 ; ++i)
if(GetAttributePresence(i))
cont++;
return cont;
}
//*********************************************************************
//***************** Default rule **************************************
//*********************************************************************
public void setAsDefaultRule(){
for(int i=0 ; i<dim/2 ;++i)
SetAttributePresence(i,false);
}
}