/*
 * TournamentSelection.java
 *
 * Created on 16. listopad 2005, 13:33
 *
 * 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.selection;
import cz.pcland.ga.BaseIndividual;
import cz.pcland.ga.MyRand;
/**
 *
 * @author petr
 */
public class TournamentSelection implements SelectionOperator {
    protected int tournamentSize = 2;
    
    /** Creates a new instance of TournamentSelection */
    public TournamentSelection() {
        super();
    }
    
    public String toString() {
        return "Tournament selection" ;
    }
    
    public void onStart(BaseIndividual[] population) {
        
    }
    
    public void init(BaseIndividual[] population, double sumOfFitness) {
        
    }
    
    public void setTournamentSize(int i){
        if(i < 2) {
            this.tournamentSize = 2;
        }else {
            this.tournamentSize = i;
        }
    }
    
    /**
     * Randomly selects two individuals from generation and returns the one with better fitness.
     */
    public BaseIndividual select(BaseIndividual[] population, int popSize, double sumOfFitness) throws SelectionException{
        
        if(this.tournamentSize >= population.length || this.tournamentSize < 2) throw new SelectionException("Bad tournament size");
                
        int[] tournament = new int[tournamentSize];
        
        for(int i=0;i<tournamentSize;i++){
            tournament[i] = Math.abs(MyRand.getInt()%(popSize));
        }
        
        int maxIndex = tournament[0];
        for(int i=1;i<tournamentSize;i++){
            if(population[tournament[i]].getFitness() > population[maxIndex].getFitness()){
                maxIndex = tournament[i];
            }
        }
        
        return population[maxIndex];
        
    }
}
