package ac.essex.gp.selection;

import ac.essex.gp.individuals.Individual;
import ac.essex.gp.params.GPParams;
import java.util.Vector;

/**
 * Basic Tournament Selection. Randomly finds x individuals where
 * x is the tournament size. It then chooses the best individual from
 * this tournament. This is defined as the individual with the
 * highest fitness, or (if there is a tie) the fittest individual with
 * the smallest tree size.
 *
 * @author Olly Oechsle, University of Essex, Date: 15-Jan-2007
 * @version 1.0
 */
public class TournamentSelection implements Selector {

    protected int tournamentSize;
    protected Vector<Individual> population;

    public TournamentSelection(GPParams params, Vector<Individual> population) {
        tournamentSize = params.getTournamentSize();
        this.population = population;
    }

    public Individual select() {
        Individual best = null;
        for (int i = 0; i < tournamentSize; i++) {
            Individual ind = getRandomIndividual();
            // if best is null
            // or best is not so good as this individual
            // but ensure that it is only added if not already added.
            // if they have the same fitness, choose the smaller one.
            if (best == null || best.getKozaFitness() > ind.getKozaFitness()) best = ind;
            //if (best == null || best.getKozaFitness() > ind.getKozaFitness() || best.getKozaFitness() == ind.getKozaFitness() && best.getTree().getTreeSize() < ind.getTree().getTreeSize()) best = ind;
        }
        return best;
    }

    private Individual getRandomIndividual() {
        return population.get((int) (Math.random() * population.size()));
    }

}
