001package net.sf.cpsolver.studentsct.heuristics.selection; 002 003import net.sf.cpsolver.ifs.heuristics.NeighbourSelection; 004import net.sf.cpsolver.ifs.heuristics.ValueSelection; 005import net.sf.cpsolver.ifs.heuristics.VariableSelection; 006import net.sf.cpsolver.ifs.model.Neighbour; 007import net.sf.cpsolver.ifs.model.SimpleNeighbour; 008import net.sf.cpsolver.ifs.solution.Solution; 009import net.sf.cpsolver.ifs.solver.Solver; 010import net.sf.cpsolver.ifs.util.DataProperties; 011import net.sf.cpsolver.ifs.util.Progress; 012import net.sf.cpsolver.studentsct.model.Enrollment; 013import 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 Tomáš Müller<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 */ 059public 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}