/*
 * FunctionFitnessGray.java
 *
 * Created on March 7, 2006, 10:56 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package cz.pcland.ga.fitness;
import cz.pcland.ga.BaseIndividual;
import cz.pcland.ga.BinaryIndividual;
import java.util.*;
import cz.pcland.functions.lexan.*;
import cz.pcland.functions.nodes.*;
import cz.pcland.functions.syntax.*;
import cz.pcland.functions.*;
/**
 *
 * @author petr
 */
public class FunctionFitnessGray extends BaseFunctionFitness implements Evaluator{
    

    public void postEvaluate(BaseIndividual[] population, double min, double max) {
        
        for(int ii=0;ii<population.length;++ii){
            if(population[ii].getEvaluation() == Double.NaN || population[ii].getEvaluation() == Double.NEGATIVE_INFINITY) {
                population[ii].setFitness(0);
                population[ii].setEvaluation(0);
            }
            
            population[ii].setFitness( population[ii].getFitness()+Math.abs(min) );
        }
      
 
    }
    
    public void init(BaseIndividual[] population) {
        
    }
    
    public void onStart(BaseIndividual[] population){
        
    }
    
    public double decode(BaseIndividual str) {        
        boolean[] bits = ((BinaryIndividual)str).getString();

        long order = 0;
        boolean ok = true;
        for(int ii=0;ii<bits.length;ii++){ //rozk?dov?n? Grayova k?du
            if ( (ok && bits[ii]) ||  (!ok && !bits[ii]) ) {
                order++;
                ok = false;
            } else {
                ok = true;
            }
            order*=2;
        }
        order /= 2;

        return order;
    }
    
 
    
    public double getFunctionValue(double xValue){    
        double value = instance.node.evaluate(xValue, "x");
        return value;
    }
    
    public double getEvaluation(BaseIndividual str){
        boolean[] bits = ((BinaryIndividual)str).getString();
     
        
        double value = decode(str);
        value = convertValueToInterval(value);
        value = getFunctionValue(value);
        if(value != Double.NEGATIVE_INFINITY && value != Double.POSITIVE_INFINITY && value != Double.NaN){
            return value;
        }else {
            return Double.NaN;
        }

    }
    
    
    public String toString(){
        return "Gray code";
    }
    
    
    public boolean isEnd(BaseIndividual bi){
        return false;
    }
    
    /** Creates a new instance of FunctionFitness */
    public FunctionFitnessGray() {
    }
    
}
