/*
* Copyright (c) 2010 Mathew Hall, University of Sheffield.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* Neither the name of the University of Sheffield nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package search.fitnessfunctions;
import gpinterpreter.stack.StackInstruction;
import gpinterpreter.stack.StackInterpreter;
import gpinterpreter.vector.VecInterpreter;
import gpinterpreter.vector.VecInstruction;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jgap.FitnessFunction;
import org.jgap.Gene;
import org.jgap.IChromosome;
import org.jgap.impl.FixedBinaryGene;
import org.jgap.impl.IntegerGene;
import primitives.cluster.ClusterHead;
import primitives.cluster.ClusterNode;
import primitives.cluster.ClusterUtils;
import primitives.cluster.IClusterLevel;
import primitives.graph.Node;
import search.fitnessfunctions.util.TreeTranslator;
import search.genes.*;
public abstract class TreeFitnessFunction extends FitnessFunction {
/**
*
*/
private static final long serialVersionUID = -5219003121816689020L;
private ClusterHead tree;
public void setTree(ClusterHead tree) {
this.tree = tree;
}
private int evaluations = 0;
private int fitnessBudget = -1;
public void setFitnessBudget(int fb) {
fitnessBudget = fb;
}
public boolean budgetHit() {
return evaluations >= fitnessBudget;
}
private ClusterHead best = null;
public ClusterHead getFittest() {
return best;
}
double bestFitness = -1;
public double getBestFitness() {
return bestFitness;
}
private int evalsToBest = -1;
public int getEvalsToBest() {
return evalsToBest;
}
protected boolean punishesWastage() {
return false;
}
/**
* @return true if the fitness function requires clusters to be subsumed
* (with EdgeSubsumptionTransformer)
*
*/
public static Boolean subsumes() {
return false;
}
public int getFitnessEvaluations() {
return evaluations;
}
public double scaleWastage(double fitness, int amount) {
return fitness;
}
public double evaluate(IChromosome a_subject) {
if (a_subject.size() == 0) {
return 0.0;
}
GeneType type = (GeneType) a_subject.getApplicationData();
ClusterHead ch = TreeTranslator.getTree(a_subject, tree);
double fitness;
if (type == GeneType.STACK) {
ArrayList<StackInstructionGene> prog = new ArrayList<StackInstructionGene>();
for (int i = 0; i < a_subject.size(); i++) {
prog.add((StackInstructionGene) a_subject.getGene(i));
}
fitness = evaluateStackGene(prog);
} else {
fitness = evaluate(ch);
}
checkBudget(fitness, ch);
return fitness;
}
public void checkBudget(double fitness, ClusterHead solution) {
evaluations++;
if (!budgetHit()) {
evalsToBest = evaluations;
if (fitness > bestFitness) {
bestFitness = fitness;
best = solution.deepCopy();
evalsToBest = evaluations;
}
}
}
public double evaluateTree(ClusterHead tr){
double fitness = evaluate(tr);
checkBudget(fitness, tr);
return fitness;
}
public double evaluateStackGene(ArrayList<StackInstructionGene> program) {
ArrayList<StackInstruction> p = new ArrayList<StackInstruction>();
for (int i = 0; i < program.size(); i++) {
p.add(program.get(i).getInstruction());
}
StackInterpreter interp = new StackInterpreter(p, tree.deepCopy());
ClusterHead evaluated = interp.run();
double fitness = evaluate(evaluated);
if (punishesWastage()) {
fitness = scaleWastage(fitness, interp.getWastage());
}
checkBudget(fitness, evaluated);
return fitness;
}
public abstract double evaluate(ClusterHead result);
}