package jhpro.sregression;
import java.util.HashMap;
import org.jgap.gp.CommandGene;
import org.jgap.gp.GPFitnessFunction;
import org.jgap.gp.IGPProgram;
import org.jgap.gp.impl.ProgramChromosome;
/**
* Fitness function for evaluating the produced fomulas, represented as GP
* programs. The fitness is computed by calculating the result (Y) of the
* function/formula for integer inputs (X's). The sum of the differences
* between expected Y and actual Y is the fitness, the lower the better (as
* it is a defect rate here).
*/
public class FormulaFitnessFunction
extends GPFitnessFunction {
/**
*
*/
private static final long serialVersionUID = 1L;
protected double evaluate(final IGPProgram a_subject) {
return computeRawFitness(a_subject);
}
public double computeRawFitness(final IGPProgram ind) {
double error = 0.0d;
Object[] noargs = new Object[0];
// 2010-03-01: Allow "penalty"
// If we have requirements of size etc we will
// penalty programs with smaller size.
// normally we don't penalty anything
double penalty = 0.0;
ProgramChromosome chrom = ind.getChromosome(0);
int numTerms = chrom.numFunctions() + chrom.numTerminals();
// penalty if the terms are less than minNodes
if (SymRegression.minNodes >= 0) {
if (numTerms < SymRegression.minNodes) {
penalty += Math.abs(numTerms - SymRegression.minNodes)*SymRegression.minNodesPenalty;
}
}
// added 2010-03-20
// for alldifferent type of constraints
// (Note: This could surely be done more efficient.)
if (SymRegression.alldifferentVariables) {
CommandGene[] functions = chrom.getFunctions();
HashMap countVariables = new HashMap();
for (int i = 0; i < functions.length; i++) {
CommandGene func = functions[i];
if (func != null) {
int arity = func.getArity(ind);
String funcStr = func.toString();
if (arity == 0) {
Class returnType = func.getReturnType();
int subReturnType = func.getSubReturnType();
// It is a terminal
if (!countVariables.containsKey(funcStr)) {
countVariables.put(funcStr, 1);
} else {
// this variable is already seen so we
// punish this program
penalty += SymRegression.alldifferentVariablesPenalty;
countVariables.put(funcStr, countVariables.get(funcStr)+1);
}
}
}
}
}
// Evaluate function for the input numbers
// ---------------------------------------
int thisNumHits = 0;
double[] results = new double[SymRegression.numRows];
double[] errors = new double[SymRegression.numRows];
for (int j = 0; j < SymRegression.numRows; j++) {
// Provide the variable X with the input number.
// See method create(), declaration of "nodeSets" for where X is
// defined.
// -------------------------------------------------------------
// set all the input variables
int variableIndex = 0;
for(int i = 0; i < SymRegression.numInputVariables+1; i++) {
if (i != SymRegression.outputVariable) {
SymRegression.variables[variableIndex].set(SymRegression.data[i][j]);
variableIndex++;
}
}
try {
double result = ind.execute_double(0, noargs);
results[j] = result;
// Sum up the error between actual and expected result
// to get a defect rate.
// ---------------------------------------------------
// original:
double res = SymRegression.data[SymRegression.outputVariable][j];
double diff = Math.abs(result - res) + penalty;
// diff = Math.sqrt(Math.abs(result*result - res*res));
errors[j] = diff;
// double r = data[outputVariable][j];
if (SymRegression.hitsCriteria >= 0.0) {
// count the number of non hits
if (Double.isInfinite(result) || Double.isNaN(result) || Double.isInfinite(diff) || Double.isNaN(diff) || diff > SymRegression.hitsCriteria) {
error += 1.0 + penalty;
}
} else {
error += diff;
}
if (diff <= SymRegression.hitsCriteria) {
thisNumHits++;
}
// If the error is too high, stop evaluation and return
// worst error possible.
// ----------------------------------------------------
if (Double.isInfinite(error) || Double.isNaN(error)) {
return Double.MAX_VALUE;
}
} catch (ArithmeticException ex) {
// This should not happen, some illegal operation was
// executed.
// ----------------------------------------------------
System.out.println(ind);
throw ex;
}
}
// 2010-02-22: Calculate different types of errors
double[] errs = SymRegression.calcAllErrors(error, errors);
if (SymRegression.hitsCriteria < 0) {
error = errs[0];
}
double totalError = errs[1];
double minError = errs[2];
double maxError = errs[3];
double meanError = errs[4];
double medianError = errs[5];
double correlation = SymRegression.correlation(SymRegression.data[SymRegression.outputVariable], results, results.length);
ApplicationData appData;
if (SymRegression.showResults) {
appData = new ApplicationData(error, correlation, thisNumHits, minError, maxError, meanError, medianError, totalError, results);
} else {
appData = new ApplicationData(error, correlation, thisNumHits, minError, maxError, meanError, medianError, totalError);
}
ind.setApplicationData(appData);
if (SymRegression.scaleError > 0.0d) {
return error*SymRegression.scaleError;
} else {
return error;
}
}
}
Ads help maintain this website.