// Path: src/ch/epfl/bigdata/ts/ga/crossover/CrossoverMethod.java
// public interface CrossoverMethod {
// 	Chromosome cross(Chromosome chr1, Chromosome chr2);
// }
// 
// Path: src/ch/epfl/bigdata/ts/ga/mutation/MutationMethod.java
// public interface MutationMethod {
// 	void mutate(Gene gene, Range range);
// }
// 
// Path: src/ch/epfl/bigdata/ts/ga/selection/SelectionMethod.java
// public abstract class SelectionMethod {
// 	
// 	public abstract List<Chromosome> select(List<Chromosome> population, int n);
// 	
// 	protected List<Chromosome> throwMarble(List<Chromosome> population, int n, double sum) {
// 		for(int i = 1; i < population.size(); i++) {
// 			Chromosome prev = population.get(i - 1), cur = population.get(i);
// 			cur.setFitnessSelection(cur.getFitnessSelection() + prev.getFitnessSelection());
// 		}
// 		
// 		List<Chromosome> result = new ArrayList<Chromosome>();
// 		for(int i = 0; i < n; i++) {
// 			double rVal = Range.R.nextDouble() * sum;
// 			
// 			for(int j = 0; j < population.size(); j++) {
// 				Chromosome cur = population.get(j);
// 				if(cur.getFitnessSelection() > rVal) {
// 					result.add(cur);
// 					break;
// 				}
// 			}
// 			
// 		}
// 		return result;
// 	}
// }
// 
// Path: src/ch/epfl/bigdata/ts/ga/util/Range.java
// public class Range {
// 	public static Random R = new Random(System.currentTimeMillis());
//     private double upper, lower;
// 
//     public Range(double lower, double upper) {
//         this.upper = upper;
//         this.lower = lower;
//     }
// 
//     public double getLower() {
//         return lower;
//     }
// 
//     public double getUpper() {
//         return upper;
//     }
// 
// }


import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import ch.epfl.bigdata.ts.ga.crossover.CrossoverMethod;
import ch.epfl.bigdata.ts.ga.mutation.MutationMethod;
import ch.epfl.bigdata.ts.ga.selection.SelectionMethod;
import ch.epfl.bigdata.ts.ga.util.Range;

package ch.epfl.bigdata.ts.ga;



public class Population {
	
	private SelectionMethod selMethod;
	private CrossoverMethod crossMethod;
	private MutationMethod mutatMethod;

    private int maxPopulationSize;

	private HashMap<String, Range> geneRange;
	
	private List<Chromosome> population;
	private List<Chromosome> elitePopulation;
	
	private int genesPerChr;
	

// Path: src/ch/epfl/bigdata/ts/ga/crossover/CrossoverMethod.java
// public interface CrossoverMethod {
// 	Chromosome cross(Chromosome chr1, Chromosome chr2);
// }
// 
// Path: src/ch/epfl/bigdata/ts/ga/mutation/MutationMethod.java
// public interface MutationMethod {
// 	void mutate(Gene gene, Range range);
// }
// 
// Path: src/ch/epfl/bigdata/ts/ga/selection/SelectionMethod.java
// public abstract class SelectionMethod {
// 	
// 	public abstract List<Chromosome> select(List<Chromosome> population, int n);
// 	
// 	protected List<Chromosome> throwMarble(List<Chromosome> population, int n, double sum) {
// 		for(int i = 1; i < population.size(); i++) {
// 			Chromosome prev = population.get(i - 1), cur = population.get(i);
// 			cur.setFitnessSelection(cur.getFitnessSelection() + prev.getFitnessSelection());
// 		}
// 		
// 		List<Chromosome> result = new ArrayList<Chromosome>();
// 		for(int i = 0; i < n; i++) {
// 			double rVal = Range.R.nextDouble() * sum;
// 			
// 			for(int j = 0; j < population.size(); j++) {
// 				Chromosome cur = population.get(j);
// 				if(cur.getFitnessSelection() > rVal) {
// 					result.add(cur);
// 					break;
// 				}
// 			}
// 			
// 		}
// 		return result;
// 	}
// }
// 
// Path: src/ch/epfl/bigdata/ts/ga/util/Range.java
// public class Range {
// 	public static Random R = new Random(System.currentTimeMillis());
//     private double upper, lower;
// 
//     public Range(double lower, double upper) {
//         this.upper = upper;
//         this.lower = lower;
//     }
// 
//     public double getLower() {
//         return lower;
//     }
// 
//     public double getUpper() {
//         return upper;
//     }
// 
// }


// Path: src/ch/epfl/bigdata/ts/ga/Population.java
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import ch.epfl.bigdata.ts.ga.crossover.CrossoverMethod;
import ch.epfl.bigdata.ts.ga.mutation.MutationMethod;
import ch.epfl.bigdata.ts.ga.selection.SelectionMethod;
import ch.epfl.bigdata.ts.ga.util.Range;

package ch.epfl.bigdata.ts.ga;



public class Population {
	
	private SelectionMethod selMethod;
	private CrossoverMethod crossMethod;
	private MutationMethod mutatMethod;

    private int maxPopulationSize;

	private HashMap<String, Range> geneRange;
	
	private List<Chromosome> population;
	private List<Chromosome> elitePopulation;
	
	private int genesPerChr;
	

	public Population(List<Chromosome> population, SelectionMethod selMethod, CrossoverMethod crossMethod, MutationMethod mutatMethod, HashMap<String, Range> geneRange) {
