001 package net.sf.cpsolver.ifs.extension; 002 003 import java.util.*; 004 005 import net.sf.cpsolver.ifs.model.*; 006 import net.sf.cpsolver.ifs.solution.*; 007 import net.sf.cpsolver.ifs.solver.*; 008 import net.sf.cpsolver.ifs.util.*; 009 010 /** 011 * Go back to the best known solution when no better solution is found within the given amount of iterations. 012 * 013 * @version 014 * IFS 1.1 (Iterative Forward Search)<br> 015 * Copyright (C) 2006 Tomáš Müller<br> 016 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 017 * Lazenska 391, 76314 Zlin, Czech Republic<br> 018 * <br> 019 * This library is free software; you can redistribute it and/or 020 * modify it under the terms of the GNU Lesser General Public 021 * License as published by the Free Software Foundation; either 022 * version 2.1 of the License, or (at your option) any later version. 023 * <br><br> 024 * This library is distributed in the hope that it will be useful, 025 * but WITHOUT ANY WARRANTY; without even the implied warranty of 026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 027 * Lesser General Public License for more details. 028 * <br><br> 029 * You should have received a copy of the GNU Lesser General Public 030 * License along with this library; if not, write to the Free Software 031 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 032 */ 033 public class SearchIntensification extends Extension implements SolutionListener { 034 private static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(SearchIntensification.class); 035 private long iInitialIterationLimit = 100; 036 private long iIterationLimit = 100; 037 private long iLastReturn = 0; 038 private ConflictStatistics iCBS = null; 039 private int iResetInterval = 5; 040 private int iResetCounter = 0; 041 private int iMux = 2; 042 private int iMuxInterval = 2; 043 private int iMuxCounter = 0; 044 045 public SearchIntensification(Solver solver, DataProperties properties) { 046 super(solver, properties); 047 iInitialIterationLimit = properties.getPropertyLong("SearchIntensification.IterationLimit", iInitialIterationLimit); 048 iResetInterval = properties.getPropertyInt("SearchIntensification.ResetInterval", iResetInterval); 049 iMuxInterval = properties.getPropertyInt("SearchIntensification.MultiplyInterval", iMuxInterval); 050 iMux = properties.getPropertyInt("SearchIntensification.Multiply", iMux); 051 } 052 053 public boolean init(Solver solver) { 054 if (iResetInterval>0) { 055 for (Enumeration e=solver.getExtensions().elements();e.hasMoreElements();) { 056 Extension ex = (Extension)e.nextElement(); 057 if (ex instanceof ConflictStatistics) { 058 iCBS = (ConflictStatistics)ex; 059 break; 060 } 061 } 062 } 063 return super.init(solver); 064 } 065 066 public void register(Model model) { 067 super.register(model); 068 getSolver().currentSolution().addSolutionListener(this); 069 } 070 071 public void unregister(Model model) { 072 super.unregister(model); 073 getSolver().currentSolution().removeSolutionListener(this); 074 } 075 076 public void afterAssigned(long iteration, Value value) { 077 if (iIterationLimit>0 && iteration>0) { 078 Solution solution = getSolver().currentSolution(); 079 if (solution.getBestIteration()<0 || !solution.isBestComplete()) return; 080 long bestIt = Math.max(solution.getBestIteration(), iLastReturn); 081 long currIt = solution.getIteration(); 082 if (currIt - bestIt > iIterationLimit) { 083 iLastReturn = currIt; iResetCounter++; iMuxCounter++; 084 sLogger.debug("Going back to the best known solution..."); 085 solution.restoreBest(); 086 sLogger.debug("Reset counter set to "+iResetCounter); 087 if (iMuxInterval>0 && (iMuxCounter%iMuxInterval)==0) { 088 iIterationLimit *= iMux; 089 sLogger.debug("Iteration limit increased to "+iIterationLimit); 090 } 091 if (iCBS!=null && iResetInterval>0 && (iResetCounter%iResetInterval)==0) { 092 sLogger.debug("Reseting CBS..."); 093 iCBS.reset(); 094 } 095 } 096 } 097 } 098 public void bestSaved(Solution solution) { 099 if (iResetCounter>0) 100 sLogger.debug("Reset counter set to zero."); 101 iResetCounter = 0; iMuxCounter = 0; iIterationLimit = iInitialIterationLimit; 102 } 103 public void solutionUpdated(Solution solution) { 104 } 105 public void bestCleared(Solution solution) { 106 } 107 public void bestRestored(Solution solution) { 108 } 109 public void getInfo(Solution solution, Dictionary info) { 110 } 111 public void getInfo(Solution solution, Dictionary info, Vector variables) { 112 } 113 }