001package net.sf.cpsolver.studentsct.heuristics.selection;
002
003import java.util.List;
004
005import net.sf.cpsolver.ifs.heuristics.NeighbourSelection;
006import net.sf.cpsolver.ifs.model.Neighbour;
007import net.sf.cpsolver.ifs.solution.Solution;
008import net.sf.cpsolver.ifs.solver.Solver;
009import net.sf.cpsolver.ifs.util.DataProperties;
010import net.sf.cpsolver.ifs.util.Progress;
011import net.sf.cpsolver.ifs.util.ToolBox;
012import net.sf.cpsolver.studentsct.StudentSectioningModel;
013import net.sf.cpsolver.studentsct.model.Enrollment;
014import net.sf.cpsolver.studentsct.model.Request;
015import net.sf.cpsolver.studentsct.model.Student;
016
017/**
018 * Random unassignment of some (randomly selected) students.
019 * 
020 * <br>
021 * <br>
022 * In each step a student is randomly selected with the given probabilty. Null
023 * is returned otherwise (controll is passed to the following
024 * {@link NeighbourSelection}).
025 * 
026 * <br>
027 * <br>
028 * Parameters: <br>
029 * <table border='1'>
030 * <tr>
031 * <th>Parameter</th>
032 * <th>Type</th>
033 * <th>Comment</th>
034 * </tr>
035 * <tr>
036 * <td>Neighbour.RandomUnassignmentProb</td>
037 * <td>{@link Double}</td>
038 * <td>Probability of a random selection of a student.</td>
039 * </tr>
040 * </table>
041 * <br>
042 * <br>
043 * 
044 * @version StudentSct 1.2 (Student Sectioning)<br>
045 *          Copyright (C) 2007 - 2010 Tomáš Müller<br>
046 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
047 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
048 * <br>
049 *          This library is free software; you can redistribute it and/or modify
050 *          it under the terms of the GNU Lesser General Public License as
051 *          published by the Free Software Foundation; either version 3 of the
052 *          License, or (at your option) any later version. <br>
053 * <br>
054 *          This library is distributed in the hope that it will be useful, but
055 *          WITHOUT ANY WARRANTY; without even the implied warranty of
056 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
057 *          Lesser General Public License for more details. <br>
058 * <br>
059 *          You should have received a copy of the GNU Lesser General Public
060 *          License along with this library; if not see
061 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
062 */
063public class RandomUnassignmentSelection implements NeighbourSelection<Request, Enrollment> {
064    private List<Student> iStudents = null;
065    protected double iRandom = 0.5;
066
067    /**
068     * Constructor
069     * 
070     * @param properties
071     *            configuration
072     */
073    public RandomUnassignmentSelection(DataProperties properties) {
074        iRandom = properties.getPropertyDouble("Neighbour.RandomUnassignmentProb", iRandom);
075    }
076
077    /**
078     * Initialization
079     */
080    @Override
081    public void init(Solver<Request, Enrollment> solver) {
082        iStudents = ((StudentSectioningModel) solver.currentSolution().getModel()).getStudents();
083        Progress.getInstance(solver.currentSolution().getModel()).setPhase("Random unassignment...", 1);
084    }
085
086    /**
087     * With the given probabilty, a student is randomly selected to be
088     * unassigned. Null is returned otherwise.
089     */
090    @Override
091    public Neighbour<Request, Enrollment> selectNeighbour(Solution<Request, Enrollment> solution) {
092        if (Math.random() < iRandom) {
093            Student student = ToolBox.random(iStudents);
094            return new UnassignStudentNeighbour(student);
095        }
096        Progress.getInstance(solution.getModel()).incProgress();
097        return null;
098    }
099
100    /** Unassignment of all requests of a student */
101    public static class UnassignStudentNeighbour extends Neighbour<Request, Enrollment> {
102        private Student iStudent = null;
103
104        /**
105         * Constructor
106         * 
107         * @param student
108         *            a student to be unassigned
109         */
110        public UnassignStudentNeighbour(Student student) {
111            iStudent = student;
112        }
113
114        @Override
115        public double value() {
116            double val = 0;
117            for (Request request : iStudent.getRequests()) {
118                if (request.getAssignment() != null)
119                    val -= request.getAssignment().toDouble();
120            }
121            return val;
122        }
123
124        /** All requests of the given student are unassigned */
125        @Override
126        public void assign(long iteration) {
127            for (Request request : iStudent.getRequests()) {
128                if (request.getAssignment() != null)
129                    request.unassign(iteration);
130            }
131        }
132
133        @Override
134        public String toString() {
135            StringBuffer sb = new StringBuffer("Un{");
136            sb.append(" " + iStudent);
137            sb.append(" }");
138            return sb.toString();
139        }
140
141    }
142
143}