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'><caption>Related Solver Parameters</caption> 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 * @author Tomáš Müller 044 * @version IFS 1.3 (Iterative Forward Search)<br> 045 * Copyright (C) 2006 - 2014 Tomáš Müller<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 <a href='http://www.gnu.org/licenses'>http://www.gnu.org/licenses</a>. 061 * 062 * @param <V> Variable 063 * @param <T> Value 064 **/ 065public class GeneralTerminationCondition<V extends Variable<V, T>, T extends Value<V, T>> implements 066 TerminationCondition<V, T> { 067 protected static org.apache.logging.log4j.Logger sLogger = org.apache.logging.log4j.LogManager.getLogger(GeneralTerminationCondition.class); 068 private int iMaxIter; 069 private double iTimeOut; 070 private boolean iStopWhenComplete; 071 072 public GeneralTerminationCondition(DataProperties properties) { 073 iMaxIter = properties.getPropertyInt("Termination.MaxIters", -1); 074 iTimeOut = properties.getPropertyDouble("Termination.TimeOut", -1.0); 075 iStopWhenComplete = properties.getPropertyBoolean("Termination.StopWhenComplete", false); 076 } 077 078 @Override 079 public boolean canContinue(Solution<V, T> currentSolution) { 080 if (iMaxIter >= 0 && currentSolution.getIteration() >= iMaxIter) { 081 sLogger.info("Maximum number of iteration reached."); 082 return false; 083 } 084 if (iTimeOut >= 0 && currentSolution.getTime() > iTimeOut) { 085 sLogger.info("Timeout reached."); 086 return false; 087 } 088 if (iStopWhenComplete || (iMaxIter < 0 && iTimeOut < 0)) { 089 boolean ret = (currentSolution.getAssignment().nrUnassignedVariables(currentSolution.getModel()) != 0); 090 if (!ret) 091 sLogger.info("Complete solution found."); 092 return ret; 093 } 094 return true; 095 } 096}