/***********************************************************************
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/
**********************************************************************/
/**
* <p>
* @author Written by Juli�n Luengo Mart�n 13/02/2007
* @version 0.1
* @since JDK 1.5
* </p>
*/
package keel.Algorithms.Genetic_Rule_Learning.CORE;
import keel.Dataset.Attribute;
import keel.Dataset.Attributes;
import keel.Dataset.Instance;
import keel.Dataset.InstanceSet;
/**
* <p>
* This class represents the population of chromosomes in the CORE algorithm.
* It is composed by a set of subpopulations (many as number of different classes in the data set)
* </p>
*/
public class Population {
// ArrayList<Chromosome> rules;
Subpopulation rules[];
/**
* <p>
* Constructor which initializes the memory allocations.
* </p>
*/
public Population(){
Attribute a =Attributes.getOutputAttribute(0);
int numClasses;
if(a.getType() == Attribute.NOMINAL)
numClasses = a.getNumNominalValues();
else
numClasses =(int)( a.getMaxAttribute() - a.getMinAttribute());
rules = new Subpopulation[numClasses];
for(int i=0;i<numClasses;i++)
rules[i] = new Subpopulation();
}
/**
* <p>
* Gets the indicated rule
* </p>
* @param _class class of the subpopulation which the rule belongs to
* @param index index of the rule in the proper subpopulation
* @return the rule we want
*/
public Chromosome getRule(int _class,int index){
return rules[_class].getRule(index);
}
/**
* <p>
* Gets one rule using its global index, that is, the index across all subpopulations
* </p>
* @param globalIndex global index of the rule
* @return the indicated rule
*/
public Chromosome getRule(int globalIndex){
int i;
int tmp = globalIndex;
i = 0;
while(tmp >= 0){
tmp -= rules[i].getNumRules();
i++;
}
i--;
tmp += rules[i].getNumRules();
return rules[i].getRule(tmp);
}
/**
* <p>
* Adds a rule to the specified subpopulation
* </p>
* @param _class the class which identifies the subpopulation
* @param rule the rule to be added
*/
public void addRule(int _class,Chromosome rule){
rules[_class].addRule(rule);
}
/**
* <p>
* Gets the number of genes of one subpopulation
* </p>
* @param _class the class which identifies the subpopulation
* @return the number of genes of the specified subpopulation
*/
public int getNumGenes(int _class){
return rules[_class].getNumGenes();
}
/**
* <p>
* Gets the number of rules of the specified subpopulation
* </p>
* @param _class the class which identifies the subpopulation
* @return the number of rules of the specified subpopulation
*/
public int getNumRules(int _class){
return rules[_class].rules.size();
}
/**
* <p>
* Gets the mu value of one subpopulation
* </p>
* @param _class the class which identifies the subpopulation
* @return the mu value of the subpopulation
*/
public int getMu(int _class){
return rules[_class].Mu_next;
}
/**
* <p>
* Sets the new mu value for one subpopulation
* </p>
* @param _class the class which identifies the subpopulation
* @param newMu the new mu value for mutation
*/
public void setMu(int _class, int newMu){
rules[_class].Mu_next = newMu;
}
/**
* <p>
* Mutates a chromosome in a specified subpopulation
* </p>
* @param _class the class which identifies the subpopulation
* @param chrom the index of the chromosome to be mutated
* @param gen the gene of the chromosome to be mutated
*/
public void mutate(int _class,int chrom,int gen){
rules[_class].mutate(chrom,gen);
}
/**
* <p>
* Sets the evaluation status of one rule in a specific subpopulation
* </p>
* @param _class the class which identifies the subpopulation
* @param chrom the chromosome (rule) to be changed
* @param evaluated the new evaluation status of the rule
*/
public void setEvaluated(int _class,int chrom,boolean evaluated){
rules[_class].getRule(chrom).setEvaluated(evaluated);
}
/**
* <p>
* Removes one rule of the specified subpopulation
* </p>
* @param _class the class which identifies the subpopulation
* @param r the rule to be deleted
*/
public void removeRule(int _class,Chromosome r){
rules[_class].removeRule(r);
}
/**
* <p>
* Evaluates all this population with a given data set. Stores the obtained fitness
* in each rule, updating the previous one, and setting the evaluated status of the rules to True.
* </p>
* @param ISet the data set to evaluate with
*/
public void evaluate(InstanceSet ISet){
double input[];
Instance inst;
int obtainedClass;
int tp,fp,tn,fn;
double fitness,penalty;
for(int i=0;i<rules.length;i++){
for(int j=0;j<rules[i].rules.size();j++){
tp = fp = tn = fn = 0;
if(!rules[i].getRule(j).isEvaluated()){
for(int k=0;k<ISet.getNumInstances();k++){
inst = ISet.getInstance(k);
input = inst.getAllInputValues();
obtainedClass = rules[i].getRule(j).evaluate(input);
if(obtainedClass == inst.getAllOutputValues()[0])
tp++;
else if(obtainedClass != -1 &&obtainedClass != inst.getAllOutputValues()[0])
fp++;
else if (obtainedClass == -1 && inst.getAllOutputValues()[0] != rules[i].getRule(j).getClas())
tn++;
else if(obtainedClass == -1 && inst.getAllOutputValues()[0] == rules[i].getRule(j).getClas())
fn++;
}
penalty = (double)ISet.getNumInstances()/(ISet.getNumInstances() + fp);
if((tp+fn) == 0 || (tn+fp)==0)
fitness = 0;
else
fitness = penalty * (tp/(tp+fn))*(1+(tn/(tn+fp)));
rules[i].getRule(j).setFitness(fitness);
rules[i].getRule(j).setEvaluated(true);
}
}
}
}
}