package search.searchtechniques;
import gpinterpreter.Instruction;
import gpinterpreter.vector.VecInstruction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import main.ProgressStatus;
import org.jgap.Gene;
import org.jgap.IChromosome;
import org.jgap.InvalidConfigurationException;
import org.jgap.impl.FixedBinaryGene;
import org.jgap.impl.IntegerGene;
import primitives.cluster.ClusterHead;
import search.fitnessfunctions.TreeFitnessFunction;
import search.genes.BitFieldInstructionGene;
import search.genes.GeneType;
import search.genes.InstructionGene;
import search.genes.IntegerInstructionGene;
import search.genes.StackInstructionGene;
import search.util.SearchResult;
public abstract class Search {
protected GeneType geneType;
protected int chromesize;
protected int iterations;
protected int gens;
protected TreeFitnessFunction ff;
protected ClusterHead in;
protected String name = "";
protected ProgressStatus progressStatus;
protected String interpreter;
protected String experimentName;
protected double bestFitness;
protected ClusterHead solution;
public void setExperimentName(String en) {
experimentName = en;
}
public int getChromosomeSize() {
return chromesize;
}
public void setChromosomeSize(int chromesize) {
this.chromesize = chromesize;
}
public TreeFitnessFunction getFitnessFunction() {
return ff;
}
public void setFitnessFunction(TreeFitnessFunction ff) {
this.ff = ff;
}
public String getGeneType() {
return geneType.toString();
}
public void setGeneType(String geneType) {
try {
this.geneType = GeneType.valueOf(geneType);
} catch (IllegalArgumentException iae) {
HashMap<String, GeneType> mapping = new HashMap<String, GeneType>() {
{
put("StackInstructionGene", GeneType.STACK);
put("IntegerInstructionGene", GeneType.INTEGER);
put("SymbolInstructionGene", GeneType.SYMBOL);
put("BitFieldInstructionGene", GeneType.BITFIELD);
}
};
this.geneType = mapping.get(geneType);
}
if (this.geneType == null) {
throw new RuntimeException("Gene Type of \"geneType\" is not recognised.");
}
}
public int getGenerations() {
return gens;
}
public void setGenerations(int gens) {
this.gens = gens;
}
public ClusterHead getInput() {
return in;
}
public void setInput(ClusterHead in) {
this.in = in;
}
public int getIterations() {
return iterations;
}
public void setIterations(int iterations) {
this.iterations = iterations;
}
public int getPopulationSize() {
return popsize;
}
public void setPopulationSize(int popsize) {
this.popsize = popsize;
}
public void setFitnessBudget(int fb) {
fitnessBudget = fb;
}
public int getFitnessBudget() {
return fitnessBudget;
}
protected int popsize;
public void setInterpreter(String interpreter) {
this.interpreter = interpreter;
}
protected int fitnessBudget = -1;
public Search() {
}
public Search(int population, int chromosomes, int generations,
TreeFitnessFunction fitnessFunction, ClusterHead input) {
popsize = population;
chromesize = chromosomes;
gens = generations;
ff = fitnessFunction;
in = input;
geneType = GeneType.INTEGER;
}
public Search(int population, int chromosomes, int generations,
TreeFitnessFunction fitnessFunction, ClusterHead input,
String geneType) {
this(population, chromosomes, generations, fitnessFunction, input);
this.setGeneType(geneType);
}
public void setProgressStatus(ProgressStatus ps) {
progressStatus = ps;
}
public void setName(String n) {
name = n;
}
public static List<Instruction> getProgram(List<Gene> individual, GeneType geneType, ClusterHead in) {
List<Instruction> program = new ArrayList<Instruction>();
for (int i = 0; i < individual.size(); i++) {
Instruction inst = null;
switch (geneType) {
case INTEGER:
IntegerGene g = (IntegerGene) (individual.get(i));
inst = IntegerInstructionGene.getInstruction(g.intValue(),
in.getSize());
break;
case BITFIELD:
FixedBinaryGene fbg = (FixedBinaryGene) (individual.get(i));
inst = BitFieldInstructionGene.getInstruction(
BitFieldInstructionGene.asInteger(fbg), in.getSize());
break;
case SYMBOL:
inst = (VecInstruction) individual.get(i).getAllele();
break;
case STACK:
inst = ((StackInstructionGene) (individual.get(i).getAllele())).getInstruction();
break;
default:
throw new RuntimeException("Gene type \"" + geneType + "\" isn't an instruction and can't be translated into a program.");
}
program.add(inst);
}
return program;
}
public static List<Instruction> getProgram(IChromosome individual, GeneType geneType, ClusterHead in) {
List<Gene> conv = Arrays.asList(individual.getGenes());
return getProgram(conv, geneType, in);
}
/**
* Initialise the search, if necessary.
*/
protected void setup() throws Exception {
}
/**
* Run one iteration of the search.
*
* @return the best fitness reached so far by the search.
*/
protected abstract double iteration();
protected abstract ClusterHead getClustering();
protected abstract double getFitness();
public final SearchResult start() throws Exception {
ff.setTree(in);
ff.setFitnessBudget(fitnessBudget);
//FIXME: what chromosome size should be used for the stack?
//n isn't enough, 2n? that allows for everything to be pushed and clustered once.
if(geneType == GeneType.HCLUST){
chromesize = in.getSize() + 2*(in.getSize() - 1);
}else if(geneType == GeneType.STACK){
chromesize = in.getSize() * 2;
}else{
chromesize = in.getSize();
}
setup();
int i = 0;
progressStatus.start(experimentName + " " + name);
while ((gens == 0 || i < gens) && !ff.budgetHit()) {
bestFitness = iteration();
i++;
}
String reason = "Iteration limit";
ClusterHead tr;
int totalEvals = 0;
double fitness = 0;
if (ff.budgetHit()) {
reason = "Budget reached";
tr = ff.getFittest();
fitness = ff.getBestFitness();
totalEvals = ff.getEvalsToBest();
} else {
tr = getClustering();
fitness = getFitness();
totalEvals = ff.getFitnessEvaluations();
}
Logger.getLogger(Search.class.getName()).log(Level.INFO, "Clustering of {0} complete, fitness {1} after {2} evals. {3}", new Object[]{name, fitness, totalEvals, reason});
progressStatus.finish(fitness);
SearchResult ret = new SearchResult(tr, fitness);
ret.setFitnessEvaluations(totalEvals);
return ret;
}
}