001 package net.sf.cpsolver.exam.neighbours;
002
003 import java.util.Set;
004
005 import net.sf.cpsolver.exam.model.Exam;
006 import net.sf.cpsolver.exam.model.ExamModel;
007 import net.sf.cpsolver.exam.model.ExamPeriodPlacement;
008 import net.sf.cpsolver.exam.model.ExamPlacement;
009 import net.sf.cpsolver.ifs.heuristics.NeighbourSelection;
010 import net.sf.cpsolver.ifs.model.Neighbour;
011 import net.sf.cpsolver.ifs.solution.Solution;
012 import net.sf.cpsolver.ifs.solver.Solver;
013 import net.sf.cpsolver.ifs.util.DataProperties;
014 import net.sf.cpsolver.ifs.util.ToolBox;
015
016 /**
017 * A period is selected randomly for a randomly selected exam. Rooms
018 * are computed using {@link Exam#findBestAvailableRooms(ExamPeriodPlacement)}.
019 * <br><br>
020 *
021 * @version
022 * ExamTT 1.1 (Examination Timetabling)<br>
023 * Copyright (C) 2008 Tomáš Müller<br>
024 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
025 * Lazenska 391, 76314 Zlin, Czech Republic<br>
026 * <br>
027 * This library is free software; you can redistribute it and/or
028 * modify it under the terms of the GNU Lesser General Public
029 * License as published by the Free Software Foundation; either
030 * version 2.1 of the License, or (at your option) any later version.
031 * <br><br>
032 * This library is distributed in the hope that it will be useful,
033 * but WITHOUT ANY WARRANTY; without even the implied warranty of
034 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
035 * Lesser General Public License for more details.
036 * <br><br>
037 * You should have received a copy of the GNU Lesser General Public
038 * License along with this library; if not, write to the Free Software
039 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
040 */
041 public class ExamRandomMove implements NeighbourSelection {
042 private boolean iCheckStudentConflicts = false;
043 private boolean iCheckDistributionConstraints = true;
044
045 /**
046 * Constructor
047 * @param properties problem properties
048 */
049 public ExamRandomMove(DataProperties properties) {
050 iCheckStudentConflicts = properties.getPropertyBoolean("ExamRandomMove.CheckStudentConflicts", iCheckStudentConflicts);
051 iCheckDistributionConstraints = properties.getPropertyBoolean("ExamRandomMove.CheckDistributionConstraints", iCheckDistributionConstraints);
052 }
053
054 /**
055 * Initialization
056 */
057 public void init(Solver solver) {}
058
059 /**
060 * Select an exam randomly,
061 * select an available period randomly (from {@link Exam#getPeriodPlacements()}),
062 * select rooms using {@link Exam#findBestAvailableRooms(ExamPeriodPlacement)}.
063 */
064 public Neighbour selectNeighbour(Solution solution) {
065 ExamModel model = (ExamModel)solution.getModel();
066 Exam exam = (Exam)ToolBox.random(model.variables());
067 int px = ToolBox.random(exam.getPeriodPlacements().size());
068 for (int p=0;p<exam.getPeriodPlacements().size();p++) {
069 ExamPeriodPlacement period = (ExamPeriodPlacement)exam.getPeriodPlacements().elementAt((p+px)%exam.getPeriodPlacements().size());
070 if (iCheckStudentConflicts && exam.countStudentConflicts(period)>0) continue;
071 if (iCheckDistributionConstraints && !exam.checkDistributionConstraints(period)) continue;
072 Set rooms = exam.findBestAvailableRooms(period);
073 if (rooms==null) continue;
074 return new ExamSimpleNeighbour(new ExamPlacement(exam, period, rooms));
075 }
076 return null;
077 }
078 }