001 package net.sf.cpsolver.studentsct.heuristics.selection;
002
003 import net.sf.cpsolver.ifs.heuristics.NeighbourSelection;
004 import net.sf.cpsolver.ifs.heuristics.ValueSelection;
005 import net.sf.cpsolver.ifs.heuristics.VariableSelection;
006 import net.sf.cpsolver.ifs.model.Neighbour;
007 import net.sf.cpsolver.ifs.model.SimpleNeighbour;
008 import net.sf.cpsolver.ifs.solution.Solution;
009 import net.sf.cpsolver.ifs.solver.Solver;
010 import net.sf.cpsolver.ifs.util.DataProperties;
011 import net.sf.cpsolver.ifs.util.Progress;
012 import net.sf.cpsolver.studentsct.model.Enrollment;
013 import net.sf.cpsolver.studentsct.model.Request;
014
015 /**
016 * Use the provided variable and value selection for some time. The provided
017 * variable and value selection is used for the number of iterations equal to
018 * the number of all variables in the problem. If a complete solution is found,
019 * the neighbour selection is stopped (it returns null).
020 *
021 * <br>
022 * <br>
023 * Parameters: <br>
024 * <table border='1'>
025 * <tr>
026 * <th>Parameter</th>
027 * <th>Type</th>
028 * <th>Comment</th>
029 * </tr>
030 * <tr>
031 * <td>Neighbour.StandardIterations</td>
032 * <td>{@link Long}</td>
033 * <td>Number of iterations to perform. If -1, number of iterations is set to
034 * the number of unassigned variables.</td>
035 * </tr>
036 * </table>
037 * <br>
038 * <br>
039 *
040 * @version StudentSct 1.2 (Student Sectioning)<br>
041 * Copyright (C) 2007 - 2010 Tomas Muller<br>
042 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
043 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
044 * <br>
045 * This library is free software; you can redistribute it and/or modify
046 * it under the terms of the GNU Lesser General Public License as
047 * published by the Free Software Foundation; either version 3 of the
048 * License, or (at your option) any later version. <br>
049 * <br>
050 * This library is distributed in the hope that it will be useful, but
051 * WITHOUT ANY WARRANTY; without even the implied warranty of
052 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
053 * Lesser General Public License for more details. <br>
054 * <br>
055 * You should have received a copy of the GNU Lesser General Public
056 * License along with this library; if not see
057 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
058 */
059 public class StandardSelection implements NeighbourSelection<Request, Enrollment> {
060 private long iIteration = 0;
061 private ValueSelection<Request, Enrollment> iValueSelection = null;
062 private VariableSelection<Request, Enrollment> iVariableSelection = null;
063 protected long iNrIterations = -1;
064
065 /**
066 * Constructor (variable and value selection are expected to be already
067 * initialized).
068 *
069 * @param properties
070 * configuration
071 * @param variableSelection
072 * variable selection
073 * @param valueSelection
074 * value selection
075 */
076 public StandardSelection(DataProperties properties, VariableSelection<Request, Enrollment> variableSelection,
077 ValueSelection<Request, Enrollment> valueSelection) {
078 iVariableSelection = variableSelection;
079 iValueSelection = valueSelection;
080 }
081
082 /** Initialization */
083 @Override
084 public void init(Solver<Request, Enrollment> solver) {
085 iIteration = solver.currentSolution().getIteration();
086 iNrIterations = solver.getProperties().getPropertyLong("Neighbour.StandardIterations", -1);
087 if (iNrIterations > 0)
088 Progress.getInstance(solver.currentSolution().getModel()).setPhase("Ifs...", iNrIterations);
089 }
090
091 /**
092 * Employ the provided {@link VariableSelection} and {@link ValueSelection}
093 * and return the selected value as {@link SimpleNeighbour}. The selection
094 * is stopped (null is returned) after the number of iterations equal to the
095 * number of variables in the problem or when a complete solution is found.
096 */
097 @Override
098 public Neighbour<Request, Enrollment> selectNeighbour(Solution<Request, Enrollment> solution) {
099 if (iNrIterations < 0) {
100 iNrIterations = solution.getModel().unassignedVariables().size();
101 Progress.getInstance(solution.getModel()).setPhase("Ifs...", iNrIterations);
102 }
103 if (solution.getModel().unassignedVariables().isEmpty()
104 || solution.getIteration() >= iIteration + iNrIterations)
105 return null;
106 Progress.getInstance(solution.getModel()).incProgress();
107 for (int i = 0; i < 10; i++) {
108 Request request = iVariableSelection.selectVariable(solution);
109 Enrollment enrollment = (request == null ? null : (Enrollment) iValueSelection.selectValue(solution,
110 request));
111 if (enrollment != null && !enrollment.variable().getModel().conflictValues(enrollment).contains(enrollment))
112 return new SimpleNeighbour<Request, Enrollment>(request, enrollment);
113 }
114 return null;
115 }
116
117 }