/*
 * @(#) Selector.java 2003/03/22
 * 
 */

import java.util.Properties;



/**
 * How do you choose individuals for reproduction
 * 
 * @author Sushil J. Louis
 */
public class Selector implements java.io.Serializable {

    private double scalingFactor = 1.0;

    private GARandom random;

    /**
     * Constructor extracts the scaling factor from a GA Properties object
     * (key is "scaleFactor") and stashes a reference to the GA's random
     * number generator.
     *
     * @param props The GA's paramters object.
     * @param r A reference to the GA's random number generator.
     *
     */
    public Selector(Properties props, GARandom r) {
	scalingFactor = Double.parseDouble(props.getProperty("ScaleFactor", 
							     "0.0"));
	random = r;
    }


    /**
     * Implements fitness proportional selection and assumes that
     * statistics has been invoked to calculate the sum of the scaled
     * fitnesses in the population. A scaling factor of 1.0 means no scaling
     * was used in calculating scaled fitness. Probability of selection
     * is proportional to fitness relative to rest of population. This returns
     * the selected individual's index into the population array.
     *
     * @param pop The current population and population statistics.
     *
     * @return The index (between 0 and popsize-1 inclusive) of the selected
     * individual.
     */
    public int select(Population pop) {
	double sumFitness = pop.sumFitness;
	double partSum = 0.0;
	double sum = random.fRandom() * sumFitness;
	int i = -1;
	do {
	    i++;
	    partSum += pop.currentPop[i].fitness;
	} while (i < pop.currentPop.length - 1 && partSum < sum);
	return i;
    }

}
