/*
 * CorrectionAlgorithmFitness.java
 *
 * Created on 20. listopad 2005, 13:50
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

package cz.pcland.ga.fitness;
import cz.pcland.ga.BaseIndividual;
import cz.pcland.ga.BinaryIndividual;
import cz.pcland.knapsack.KnapSack;
import cz.pcland.knapsack.KnapSackItem;
import java.util.*;
//import java.io.*;
/**
 *
 * @author petr
 */
public class CorrectionAlgorithmFitness implements Evaluator {
    private KnapSack ks;
    private double sumOfCapacity;
    
    public void setDataObject(Object instance){
        if(instance instanceof KnapSack) {
            this.ks = (KnapSack)instance;
        }
    }
    
    public void init(BaseIndividual[] population) {
        
    }
    public void onStart(BaseIndividual[] population){
        
    }
    
    public void postEvaluate(BaseIndividual[] population, double min, double max) {
        
    }
    
    public boolean isEnd(BaseIndividual bi){
        return false;
    }
    
    /** Creates a new instance of CorrectionAlgorithmFitness */
    public CorrectionAlgorithmFitness() {
        super();
        sumOfCapacity = 0;
    }
    
    public String toString() {
        return "with correction";
    }
    
   
    
    public double getEvaluation(BaseIndividual str){
        boolean[] bits = ((BinaryIndividual)str).getString();
        int i = 0;
        sumOfCapacity = 0;
        double sumOfprice = 0;
        KnapSackItem temp;
        
        
        for(Enumeration e = ks.getItems().elements();e.hasMoreElements();) {
            temp = (KnapSackItem)e.nextElement();
            if(bits[i]) { //todo: out of bounds ???
                sumOfCapacity += temp.getCapacity();
                sumOfprice += temp.getPrice();
            }
            i++;
        }
        
        
        if(sumOfCapacity <= ks.getCapacity()){
            return sumOfprice;
        } else {
            return sumOfprice-correct(str);
        }
    }
    
    
    /**
     * returns price of removed items
     */
    private double correct(BaseIndividual str){  //returns price of removed items
        boolean[] bits = ((BinaryIndividual)str).getString();
        double retValue = 0;
        
        while(sumOfCapacity > ks.getCapacity()){
            int i = 0;
            KnapSackItem temp,temp2=null;
            double minimum = 100000;
            int minimumIndex = 0;
            
            
            for(Enumeration e = ks.getItems().elements();e.hasMoreElements();) {
                temp = (KnapSackItem)e.nextElement();
                if(bits[i]) {
                    if(minimum > (temp.getPrice()/temp.getCapacity())) {
                        minimum = temp.getPrice()/temp.getCapacity();
                        minimumIndex = i;
                        temp2 = temp;
                    }
                }
                i++;
            }
            sumOfCapacity-=temp2.getCapacity();
            retValue += temp2.getPrice();
            bits[minimumIndex] = false;
        }
        return retValue;
    }
    
    
    
}
