import java.util.ArrayList;
import java.util.Random;
/**
 * \brief Trida, ktera obsahuje jednotlive metody pro selekci
 * @author nemec
 *
 */
public class Selection {
	/**
	 * Funkce, ktera reprezentuje turnajovou selekci
	 * @param tournamentSize Velikost turnaje
	 * @param population Populace, ze ktere se vybiraji chromozomy na zaklade jejich fitness
	 * @return Vizet turnaje
	 */
	public static Chromozome tournamentSelection(int tournamentSize, Population population){
		
		ArrayList<Chromozome> tournament = new ArrayList<Chromozome>();
		Random random = new Random();
		
		
		for(int i=0; i<tournamentSize; i++){
			tournament.add(population.getChromozome(random.nextInt(population.getSize())));
		}
		
		double bestFitness = tournament.get(0).getFitness();
		int fittest = 0;
		
		for(int j=0; j<tournamentSize; j++){
			if(tournament.get(j).getFitness() <= bestFitness){
				bestFitness = tournament.get(j).getFitness();
				fittest = j;
			}
		}
		
		return tournament.get(fittest);
	}
	
	public static Chromozome rouletteWheelBasedFitness(Population population){
		
		double min = 0.0;
		double max = 0.0;
		double roulette = 0;
		Chromozome ret = null;
		ArrayList<Interval> intervals = new ArrayList<Interval>();
		double sumFitness = population.getFitnessSum();
		Random random = new Random();
		
		for(int i=0;i<population.getSize();i++){
			//System.out.println(min);
			max = min + (5000.0 - population.getChromozome(i).getFitness())/((double)sumFitness);
			//System.out.println(max);
			intervals.add(new Interval(min, max, population.getChromozome(i)));
			min = max;
			}
		
		roulette = random.nextDouble();
		//System.out.println(roulette);
		
		for(int j=0;j<population.getSize();j++){
			if(roulette >= intervals.get(j).getMin() && roulette <= intervals.get(j).getMax()){
				ret = intervals.get(j).getChromozome();
				//ret.printChromozome();
				//System.out.println();
				//System.out.println("Chromozom c." + (j+1) + " s hodnotou fitness: " + ret.getFitness());
				break;
			}
		}
		
		return ret;
	}
	
	public static Chromozome rouletteWheelBaseRank(Population population, double selectionPressure){
		
		population.sortByFitness();
		double min = 0.0;
		double max = 0.0;
		double a = 0.0;
		double b = (double)population.getSize();
		ArrayList<Interval> intervals = new ArrayList<Interval>();
		
		for(int i=0;i<population.getSize();i++){
			a = (double)i;
			population.getChromozome(i).setSpecialFitness(2d - selectionPressure + 2d * (selectionPressure - 1d) * (a/b));
			System.out.println("Special je: " + population.getChromozome(i).getSpecialFitness());
		}
		
		for(int j=0;j<population.getSize();j++){
			//System.out.println(min);
			max = min + (population.getChromozome(j).getSpecialFitness()/((double)population.getSize()));
			//System.out.println(max);
			intervals.add(new Interval(min, max, population.getChromozome(j)));
			min = max;
		}
		
		return null;
	}
	
}
