001    package net.sf.cpsolver.studentsct.heuristics.selection;
002    
003    import java.util.List;
004    
005    import net.sf.cpsolver.ifs.heuristics.NeighbourSelection;
006    import net.sf.cpsolver.ifs.model.Neighbour;
007    import net.sf.cpsolver.ifs.solution.Solution;
008    import net.sf.cpsolver.ifs.solver.Solver;
009    import net.sf.cpsolver.ifs.util.DataProperties;
010    import net.sf.cpsolver.ifs.util.Progress;
011    import net.sf.cpsolver.ifs.util.ToolBox;
012    import net.sf.cpsolver.studentsct.StudentSectioningModel;
013    import net.sf.cpsolver.studentsct.model.Enrollment;
014    import net.sf.cpsolver.studentsct.model.Request;
015    import 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 Tomas Muller<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     */
063    public 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    }