package multinomad.tools;

import multinomad.config.Configuration;
import multinomad.individuals.DoubleIndividual;
import multinomad.individuals.Population;

public class Selection {
	
	public static DoubleIndividual select(Population pop) {
		if (Configuration.selection.equals(Configuration.TOURNAMENT))
			return tournamentSelect(pop);
		else
			return cooperativeSelect(pop);
	}

	public static DoubleIndividual cooperativeSelect(Population pop) {
		DoubleIndividual tourn[] = new DoubleIndividual[Configuration.tournamentSize];
		
		int pos_best = 0;
		int pos_second = 0;
		int pos_third = 0;

		for (int i=0;i<Configuration.tournamentSize;i++){
			
			//Get a random individual
			tourn[i] = pop.getP().get(CommonState.r.nextInt(pop.size()));
			

			pos_best = (tourn[i].getCoopFitness() > tourn[pos_best].getCoopFitness()) ? i:pos_best; 
			
			if (tourn[pos_best].getCoopFitness() > tourn[i].getCoopFitness() 
				&& 
				tourn[i].getCoopFitness() > tourn[pos_second].getCoopFitness()){
				pos_second = i;
			}
			
			if (tourn[pos_best].getCoopFitness() > tourn[i].getCoopFitness()  
				&& 
				tourn[pos_second].getCoopFitness() > tourn[i].getCoopFitness() 
				&&
				tourn[i].getCoopFitness() > tourn[pos_third].getCoopFitness()){
				pos_third = i;
			}
		}
		
		
		double decrement = (tourn[pos_second].getCoopFitness() +tourn[pos_third].getCoopFitness())/2.0;

		tourn[pos_best].setCoopFitness(decrement);	
		
		return tourn[pos_best];
	}
	
	public static DoubleIndividual tournamentSelect(Population pop) {
		DoubleIndividual tourn[] = new DoubleIndividual[Configuration.tournamentSize];
		
		int pos_best = 0;

		for (int i=0;i<Configuration.tournamentSize;i++){
			//Get a random individual
			tourn[i] = pop.getP().get(CommonState.r.nextInt(pop.size()));
			pos_best = (tourn[i].getFitness() > tourn[pos_best].getFitness()) ? i:pos_best; 
		}
		
		return tourn[pos_best];
	}

}
