001package org.cpsolver.ifs.termination; 002 003import org.cpsolver.ifs.model.Value; 004import org.cpsolver.ifs.model.Variable; 005import org.cpsolver.ifs.solution.Solution; 006import org.cpsolver.ifs.util.DataProperties; 007 008/** 009 * General implementation of termination condition. <br> 010 * <br> 011 * Solver stops when the solution is complete (all varaibles are assigned) or 012 * when a timeout is reached (expressed either by the number of iterations or by 013 * a time). <br> 014 * <br> 015 * Parameters: <br> 016 * <table border='1' summary='Related Solver Parameters'> 017 * <tr> 018 * <th>Parameter</th> 019 * <th>Type</th> 020 * <th>Comment</th> 021 * </tr> 022 * <tr> 023 * <td>Termination.StopWhenComplete</td> 024 * <td>{@link Double}</td> 025 * <td>if true, solver stops when a complete solution is found</td> 026 * </tr> 027 * <tr> 028 * <td>Termination.MaxIters</td> 029 * <td>{@link Integer}</td> 030 * <td>if zero or positive, solver stops when the given number of iteration is 031 * reached</td> 032 * </tr> 033 * <tr> 034 * <td>Termination.TimeOut</td> 035 * <td>{@link Double}</td> 036 * <td>if zero or positive, solver stops when the given timeout (given in 037 * seconds) is reached</td> 038 * </tr> 039 * </table> 040 * 041 * @see org.cpsolver.ifs.solver.Solver 042 * 043 * @version IFS 1.3 (Iterative Forward Search)<br> 044 * Copyright (C) 2006 - 2014 Tomáš Müller<br> 045 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 046 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 047 * <br> 048 * This library is free software; you can redistribute it and/or modify 049 * it under the terms of the GNU Lesser General Public License as 050 * published by the Free Software Foundation; either version 3 of the 051 * License, or (at your option) any later version. <br> 052 * <br> 053 * This library is distributed in the hope that it will be useful, but 054 * WITHOUT ANY WARRANTY; without even the implied warranty of 055 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 056 * Lesser General Public License for more details. <br> 057 * <br> 058 * You should have received a copy of the GNU Lesser General Public 059 * License along with this library; if not see <a href='http://www.gnu.org/licenses'>http://www.gnu.org/licenses</a>. 060 * 061 * @param <V> Variable 062 * @param <T> Value 063 **/ 064public class GeneralTerminationCondition<V extends Variable<V, T>, T extends Value<V, T>> implements 065 TerminationCondition<V, T> { 066 protected static org.apache.logging.log4j.Logger sLogger = org.apache.logging.log4j.LogManager.getLogger(GeneralTerminationCondition.class); 067 private int iMaxIter; 068 private double iTimeOut; 069 private boolean iStopWhenComplete; 070 071 public GeneralTerminationCondition(DataProperties properties) { 072 iMaxIter = properties.getPropertyInt("Termination.MaxIters", -1); 073 iTimeOut = properties.getPropertyDouble("Termination.TimeOut", -1.0); 074 iStopWhenComplete = properties.getPropertyBoolean("Termination.StopWhenComplete", false); 075 } 076 077 @Override 078 public boolean canContinue(Solution<V, T> currentSolution) { 079 if (iMaxIter >= 0 && currentSolution.getIteration() >= iMaxIter) { 080 sLogger.info("Maximum number of iteration reached."); 081 return false; 082 } 083 if (iTimeOut >= 0 && currentSolution.getTime() > iTimeOut) { 084 sLogger.info("Timeout reached."); 085 return false; 086 } 087 if (iStopWhenComplete || (iMaxIter < 0 && iTimeOut < 0)) { 088 boolean ret = (currentSolution.getAssignment().nrUnassignedVariables(currentSolution.getModel()) != 0); 089 if (!ret) 090 sLogger.info("Complete solution found."); 091 return ret; 092 } 093 return true; 094 } 095}