// Path: MetaHeuristics4Java/src/main/java/de/mh4j/solver/Solution.java
// public interface Solution<SolutionImplementationType extends Solution<?>> {
// 
//     /**
//      * Returns a numeric value that represents the costs of this solution. If
//      * the optimization problem is, to maximize the costs of a solution the
//      * return value indicates the absolute quality of the solution (the
//      * fitness).
//      **/
//     int getCosts();
// 
//     /**
//      * Compares this solution to another solution.
//      * 
//      * @return <code>true</code> if this solution instance is better than the
//      *         other solution<br>
//      *         <code>false</code> if this solution is of worse or equal quality.
//      **/
//     boolean isBetterThan(SolutionImplementationType otherSolution);
// 
// }
// 
// Path: MetaHeuristics4Java/src/main/java/de/mh4j/solver/Solver.java
// public interface Solver<GenericSolutionType> extends Runnable {
// 
//     /**
//      * Performs a single step in the algorithm of this solver. The following
//      * actions will be taken:
//      * <ol>
//      * <li>The solver will be {@link #initialize() initialized} if it has not
//      * yet been initialized by a previous call to this method</li>
//      * <li>The actual algorithm step will be performed</li>
//      * <li>The step counter will be advanced by 1</li>
//      * <li>All {@link SolverStateListener SolverStateListeners} will be notified
//      * by a call to {@link SolverStateListener#solverStateHasChanged()}</li>
//      */
//     void step();
// 
//     /**
//      * Runs the whole algorithm until the termination condition is reached.
//      */
//     @Override
//     void run();
// 
//     /**
//      * Resets this solver. The current solution will be discarded and the solver
//      * will be initialized again. All {@link SolverStateListener
//      * SolverStateListeners} will be notified.
//      */
//     void reset();
// 
//     /**
//      * Returns how often a single step in the solvers algorithm has been
//      * executed.
//      */
//     int getNumberOfSteps();
// 
//     /**
//      * Returns the current solution that has been created after the last call to
//      * {@link #step()}.<br>
//      * <br>
//      * <b>Note:</b><br>
//      * This interim solution may not be the best solution ever found and can
//      * even be <code>null</code> if {@link #step()} has never been called.
//      */
//     GenericSolutionType getCurrentSolution();
// 
//     /**
//      * Returns <code>true</code> as soon as the solver has finished optimizing
//      * the problem. Otherwise <code>false</code> is returned.
//      */
//     boolean hasFinished();
// 
//     /**
//      * Adds a {@linkplain SolverStateListener} to this solver. The listener will
//      * be informed about important events that may occur on this solver.
//      */
//     void addStateListener(SolverStateListener<GenericSolutionType> listener);
// 
//     /**
//      * Removes a {@linkplain SolverStateListener} from this solver. The listener
//      * will no longer be informed about important events that may occur on this
//      * solver.
//      */
//     void removeStateListener(SolverStateListener<GenericSolutionType> listener);
// 
// }


import de.mh4j.solver.Solution;
import de.mh4j.solver.Solver;
package de.mh4j.solver.termination;


public class StagnationTermination implements TerminationCondition {

	private final Solver<? extends Solution<?>> solver;
	private final int maxNrOfStagnatingSteps;

	private int nrOfStagnatingSteps;
	private Solution<?> lastSolution;

	public StagnationTermination(Solver<? extends Solution<?>> solver,
			int maxNrOfStagnatingSteps) {
		this.solver = solver;
		this.maxNrOfStagnatingSteps = maxNrOfStagnatingSteps;
		this.nrOfStagnatingSteps = 0;
	}

	@Override
	public boolean shouldTerminate() {
		Solution<?> currentSolution = solver.getCurrentSolution();

		if (lastSolution == null) {
			lastSolution = currentSolution;
			nrOfStagnatingSteps = 0;
		} else if (currentSolution.equals(lastSolution)) {
			nrOfStagnatingSteps++;
		} else {
			nrOfStagnatingSteps = 0;
// Path: MetaHeuristics4Java/src/main/java/de/mh4j/solver/Solution.java
// public interface Solution<SolutionImplementationType extends Solution<?>> {
// 
//     /**
//      * Returns a numeric value that represents the costs of this solution. If
//      * the optimization problem is, to maximize the costs of a solution the
//      * return value indicates the absolute quality of the solution (the
//      * fitness).
//      **/
//     int getCosts();
// 
//     /**
//      * Compares this solution to another solution.
//      * 
//      * @return <code>true</code> if this solution instance is better than the
//      *         other solution<br>
//      *         <code>false</code> if this solution is of worse or equal quality.
//      **/
//     boolean isBetterThan(SolutionImplementationType otherSolution);
// 
// }
// 
// Path: MetaHeuristics4Java/src/main/java/de/mh4j/solver/Solver.java
// public interface Solver<GenericSolutionType> extends Runnable {
// 
//     /**
//      * Performs a single step in the algorithm of this solver. The following
//      * actions will be taken:
//      * <ol>
//      * <li>The solver will be {@link #initialize() initialized} if it has not
//      * yet been initialized by a previous call to this method</li>
//      * <li>The actual algorithm step will be performed</li>
//      * <li>The step counter will be advanced by 1</li>
//      * <li>All {@link SolverStateListener SolverStateListeners} will be notified
//      * by a call to {@link SolverStateListener#solverStateHasChanged()}</li>
//      */
//     void step();
// 
//     /**
//      * Runs the whole algorithm until the termination condition is reached.
//      */
//     @Override
//     void run();
// 
//     /**
//      * Resets this solver. The current solution will be discarded and the solver
//      * will be initialized again. All {@link SolverStateListener
//      * SolverStateListeners} will be notified.
//      */
//     void reset();
// 
//     /**
//      * Returns how often a single step in the solvers algorithm has been
//      * executed.
//      */
//     int getNumberOfSteps();
// 
//     /**
//      * Returns the current solution that has been created after the last call to
//      * {@link #step()}.<br>
//      * <br>
//      * <b>Note:</b><br>
//      * This interim solution may not be the best solution ever found and can
//      * even be <code>null</code> if {@link #step()} has never been called.
//      */
//     GenericSolutionType getCurrentSolution();
// 
//     /**
//      * Returns <code>true</code> as soon as the solver has finished optimizing
//      * the problem. Otherwise <code>false</code> is returned.
//      */
//     boolean hasFinished();
// 
//     /**
//      * Adds a {@linkplain SolverStateListener} to this solver. The listener will
//      * be informed about important events that may occur on this solver.
//      */
//     void addStateListener(SolverStateListener<GenericSolutionType> listener);
// 
//     /**
//      * Removes a {@linkplain SolverStateListener} from this solver. The listener
//      * will no longer be informed about important events that may occur on this
//      * solver.
//      */
//     void removeStateListener(SolverStateListener<GenericSolutionType> listener);
// 
// }


// Path: MetaHeuristics4Java/src/main/java/de/mh4j/solver/termination/StagnationTermination.java
import de.mh4j.solver.Solution;
import de.mh4j.solver.Solver;

package de.mh4j.solver.termination;


public class StagnationTermination implements TerminationCondition {

	private final Solver<? extends Solution<?>> solver;
	private final int maxNrOfStagnatingSteps;

	private int nrOfStagnatingSteps;
	private Solution<?> lastSolution;

	public StagnationTermination(Solver<? extends Solution<?>> solver,
			int maxNrOfStagnatingSteps) {
		this.solver = solver;
		this.maxNrOfStagnatingSteps = maxNrOfStagnatingSteps;
		this.nrOfStagnatingSteps = 0;
	}

	@Override
	public boolean shouldTerminate() {
		Solution<?> currentSolution = solver.getCurrentSolution();

		if (lastSolution == null) {
			lastSolution = currentSolution;
			nrOfStagnatingSteps = 0;
		} else if (currentSolution.equals(lastSolution)) {
			nrOfStagnatingSteps++;
		} else {
			nrOfStagnatingSteps = 0;
			lastSolution = currentSolution;