001package net.sf.cpsolver.studentsct.heuristics;
002
003import net.sf.cpsolver.ifs.heuristics.RouletteWheelSelection;
004import net.sf.cpsolver.ifs.heuristics.VariableSelection;
005import net.sf.cpsolver.ifs.solution.Solution;
006import net.sf.cpsolver.ifs.solver.Solver;
007import net.sf.cpsolver.ifs.util.DataProperties;
008import net.sf.cpsolver.studentsct.StudentSectioningModel;
009import net.sf.cpsolver.studentsct.model.Enrollment;
010import net.sf.cpsolver.studentsct.model.Request;
011
012/**
013 * Variable ({@link Request}) selection using {@link RouletteWheelSelection}.
014 * Unassigned request has 10 points, an assigned request has 1 point for each
015 * section that exceeds its bound.
016 * 
017 * <br>
018 * <br>
019 * 
020 * @version StudentSct 1.2 (Student Sectioning)<br>
021 *          Copyright (C) 2007 - 2010 Tomáš Müller<br>
022 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
023 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
024 * <br>
025 *          This library is free software; you can redistribute it and/or modify
026 *          it under the terms of the GNU Lesser General Public License as
027 *          published by the Free Software Foundation; either version 3 of the
028 *          License, or (at your option) any later version. <br>
029 * <br>
030 *          This library is distributed in the hope that it will be useful, but
031 *          WITHOUT ANY WARRANTY; without even the implied warranty of
032 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
033 *          Lesser General Public License for more details. <br>
034 * <br>
035 *          You should have received a copy of the GNU Lesser General Public
036 *          License along with this library; if not see
037 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
038 */
039public class RouletteWheelRequestSelection implements VariableSelection<Request, Enrollment> {
040    RouletteWheelSelection<Request> iRoulette = null;
041
042    /**
043     * Constructor
044     * 
045     * @param properties
046     *            configuration
047     */
048    public RouletteWheelRequestSelection(DataProperties properties) {
049        super();
050    }
051
052    /** Initialization */
053    @Override
054    public void init(Solver<Request, Enrollment> solver) {
055
056    }
057
058    /** Populate roulette wheel selection, if null or empty. */
059    protected RouletteWheelSelection<Request> getRoulette(Solution<Request, Enrollment> solution) {
060        if (iRoulette != null && iRoulette.hasMoreElements()) {
061            if (iRoulette.getUsedPoints() < 0.1 * iRoulette.getTotalPoints())
062                return iRoulette;
063        }
064        iRoulette = new RouletteWheelSelection<Request>();
065        for (Request request : ((StudentSectioningModel) solution.getModel()).variables()) {
066            double points = 0;
067            if (request.getAssignment() == null)
068                points += 10;
069            else {
070                Enrollment enrollment = request.getAssignment();
071                if (enrollment.toDouble() > request.getBound())
072                    points += 1;
073            }
074            if (points > 0)
075                iRoulette.add(request, points);
076        }
077        return iRoulette;
078    }
079
080    /**
081     * Variable selection. {@link RouletteWheelSelection} is used. Unassigned
082     * request has 10 points, an assigned request has 1 point for each section
083     * that exceeds its bound.
084     */
085    @Override
086    public Request selectVariable(Solution<Request, Enrollment> solution) {
087        return getRoulette(solution).nextElement();
088    }
089}