All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javax.constraints.impl.search.Solver Maven / Gradle / Ivy

//*************************************************
//*  J A V A  C O M M U N I T Y  P R O C E S S    *
//*                                               *
//*              J S R  3 3 1                     *
//*                                               *
//*       CHOCO-BASED IMPLEMENTATION              *
//*                                               *
//* * * * * * * * * * * * * * * * * * * * * * * * *
//*          _       _                            *
//*         |   (..)  |                           *
//*         |_  J||L _|        CHOCO solver       *
//*                                               *
//*    Choco is a java library for constraint     *
//*    satisfaction problems (CSP), constraint    *
//*    programming (CP) and explanation-based     *
//*    constraint solving (e-CP). It is built     *
//*    on a event-based propagation mechanism     *
//*    with backtrackable structures.             *
//*                                               *
//*    Choco is an open-source software,          *
//*    distributed under a BSD licence            *
//*    and hosted by sourceforge.net              *
//*                                               *
//*    + website : http://choco.emn.fr            *
//*    + support : [email protected]                   *
//*                                               *
//*    Copyright (C) F. Laburthe,                 *
//*                  N. Jussien    1999-2009      *
//* * * * * * * * * * * * * * * * * * * * * * * * *
package javax.constraints.impl.search; 

/**
 * An implementation of the interface "Solver" by extending 
 * the common class AbstractSolver
 * @author J.Feldman
 * Modified by: 
 * JF, Oct.3,2010: Added custom SearchStrategies
 */

import choco.cp.solver.CPSolver;
import choco.kernel.common.logging.ChocoLogging;
import choco.kernel.solver.ContradictionException;
import choco.kernel.solver.branch.AbstractIntBranchingStrategy;
import choco.kernel.solver.variables.integer.IntDomainVar;

import javax.constraints.*;
import javax.constraints.SearchStrategy;
import javax.constraints.SearchStrategy.SearchStrategyType;

public class Solver extends AbstractSolver {
	
//	ContradictionException contradictionException;
	final CPSolver chocoSolver;
	boolean modelRead;
	boolean propagated;
	private long _max_occupied_memory;

	public Solver(Problem problem) {
		super(problem);
//		contradictionException = ContradictionException.build();
		chocoSolver = new CPSolver();
		modelRead = false;
		propagated = false;
		readChocoModel();
//		setSearchStrategy(newSearchStrategy());
	}

	public CPSolver getChocoSolver() {
		return chocoSolver;
	}
	
	/**
	 * This methods returns a new default search strategy 
	 * @return a new default search strategy
	 */
	public SearchStrategy newSearchStrategy() {
		readChocoModel();
		SearchStrategy strategy = new javax.constraints.impl.search.SearchStrategy(this);
		strategy.setVars(getProblem().getVars());
		return strategy;
	}
	
	public void readChocoModel() {
		if (! modelRead) {
			javax.constraints.impl.Problem p = (javax.constraints.impl.Problem) getProblem();
			chocoSolver.read(p.getChocoModel());
			modelRead = true;
			//log(chocoSolver.pretty());
		}
	}
	
	public boolean propagate() {
		if (propagated)
			return true;
		try {
			chocoSolver.propagate();
			//problem.log("After chocoSolver.propagate()");
			//problem.log(problem.getVars());
			propagated = true;
			return true;
		} 
		catch (ContradictionException e) {
			//e.printStackTrace();
			log("Constraint propagation failed: "+e);
			return false;
		}
	}

	/**
	 * This method attempts to find a solution of the problem, for which the solver was defined. 
	 * It uses the search strategy defined by the method setSearchStrategy(). 
	 * It returns the found solution (if any) or null. It also saves the solution and makes it 
	 * available through the method getSolution(). 
	 * If a solution is not found, the problem state is restored 
	 * to that of before the invocation of this method.
	 * If a solution is found, the problem state will be restored only if the parameter
	 * "restore" is true. Otherwise all problem variables will be instantiated with the solution
	 * values.
	 *
	 * The search can be limited by time, number of failed attempts, etc.
	 *
	 * @param restoreOrNot defines if the problem state should be restored after a solution is found
	 * @return a Solution if the search is successful or null 
	 */
	public Solution findSolution(ProblemState restoreOrNot) {
		
		readChocoModel();
		
//		log(chocoSolver.pretty());
		
		if (!propagate())
			return null;
		
		int worldIndex = 0;		
		if (restoreOrNot == ProblemState.RESTORE) {
			worldIndex = getChocoSolver().getWorldIndex(); // ??
			getChocoSolver().worldPush();
		}
		
//		SearchStrategy strategy = (SearchStrategy)getSearchStrategy();
//			//(SearchStrategy)getSearchStrategies().elementAt(0);
//		chocoSolver.attachGoal(strategy.getChocoStrategy());
//		for (int i = 1; i < getSearchStrategies().size(); i++) {
//			SearchStrategy addStrategy = (SearchStrategy)getSearchStrategies().elementAt(i);
//			chocoSolver.addGoal(addStrategy.getChocoStrategy());
//		}
		combineSearchStrategies();
        // CPRU: solve() combines calls to generateSearchStrategy() and launch().
        // calling generateSearchStrategy() twice has unexpected side effects.
		chocoSolver.solve();  // recommended by Charles
		ChocoLogging.flushLogs();
		
		Solution solution = null;
		if (chocoSolver.isFeasible().equals(Boolean.TRUE)) {
			solution = new BasicSolution(this,1);
		}

		if (restoreOrNot == ProblemState.RESTORE)
			getChocoSolver().worldPopUntil(worldIndex);
		
		return solution;
	
	}
	
	public AbstractIntBranchingStrategy makeBranching(SearchStrategy strategy) {
		
		AbstractIntBranchingStrategy branching;
		if (strategy.getType().equals(SearchStrategyType.CUSTOM)) {
			branching = new StrategyAsBranching(strategy);
		}
		else {
			javax.constraints.impl.search.SearchStrategy myStrategy =
				(javax.constraints.impl.search.SearchStrategy)strategy;
			branching = myStrategy.getChocoStrategy();
		}
		return branching;
	}
	
	public void combineSearchStrategies() {
		AbstractIntBranchingStrategy branching = makeBranching(getSearchStrategy());
		chocoSolver.addGoal(branching);
		for (int i = 1; i < getSearchStrategies().size(); i++) {
			AbstractIntBranchingStrategy nextBranching = makeBranching(getSearchStrategies().elementAt(i));
			chocoSolver.addGoal(nextBranching);
		}
	}
	
	/**
	 * This method attempts to find the solution that minimizes/maximizes the objective variable.
	 * It uses the search strategy defined by the method setSearchStrategy(strategy). 
	 * The optimization process can be also controlled by:
	 * 
    *
  • OptimizationTolarance that is a difference between optimal solutions - see setOptimizationTolarance() *
  • MaxNumberOfSolutions that is the total number of considered solutions - may be limited by the method * setMaxNumberOfSolutions() *
  • TotalTimeLimit that is the number of seconds allocated for the entire optimization process. *
*
At the same time the time for one iteration inside * optimization loop (a search of one solution) can be also limited by the use of the * special type of search strategy. *
The problem state after the execution of this method is always restored. All variables * that were added to the problems (plus the objectiveVar) will have their assigned values * saved inside the optimal solution. * * @param objective Objective.MINIMIZE or Objective.MAXIMIZE * @param objectiveVar the variable that is being minimized/maximized * @return Solution if a solution is found, * null if there are no solutions. */ public Solution findOptimalSolution(Objective objective, Var objectiveVar) { OptimizationStrategy optimizationStrategy = getOptimizationStrategy(); if (optimizationStrategy.equals(OptimizationStrategy.DICHOTOMIZE)) return findOptimalSolutionDichotomize(objective, objectiveVar); if (optimizationStrategy.equals(OptimizationStrategy.BASIC)) return findOptimalSolutionBasic(objective, objectiveVar); // OptimizationStrategy.NATIVE IntDomainVar chocoObjective = ((javax.constraints.impl.Var)objectiveVar).getChocoDomainVar(); getChocoSolver().setObjective(chocoObjective); addObjective(objectiveVar); combineSearchStrategies(); Solution solution = null; Boolean b = false; if ( objective.equals(Objective.MAXIMIZE) ) { b = getChocoSolver().maximize(true); } else { b = getChocoSolver().minimize(true); } if (b == Boolean.TRUE) solution = new BasicSolution(this,1); return solution; } /** * Creates a solution iterator that allows a user to search and navigate * through multiple solutions. * * @return a solution iterator */ public SolutionIterator solutionIterator() { return new SolutionIterator(this); } // public Solution createSolution() { // Solution solution = new BasicSolution(this); // for (int i = 0; i < chocoSolver.getNbIntVars(); i++) { // final IntVar v = chocoSolver.getIntVar(i); // if (v.isInstantiated()) { // solution.setValue(i,v.getVal()); // } // } // for (int j = 0; j < chocoSolver.getNbRealVars(); j++) { // final RealVar v = chocoSolver.getRealVar(j); // if (v.isInstantiated()) { // solution.setRealValue(j,v.getValue()); // } // } // // for (int k = 0; k < chocoSolver.getNbSetVars(); k++) { // final SetVar v = chocoSolver.getSetVar(k); // if (v.isInstantiated()) { // solution.setSetValue(k,v.getValue()); // } // } // return solution; // } @Override public boolean applySolution(Solution solution) { // TODO Auto-generated method stub return false; } @Override public void trace(Var var) { // TODO Auto-generated method stub } @Override public void trace(Var[] vars) { // TODO Auto-generated method stub } @Override public void trace(VarSet setVar) { // TODO Auto-generated method stub } /** * If flag is true, all failures will be traced (logged) * * @param flag boolean */ public void traceFailures(boolean flag) { javax.constraints.impl.Problem p = (javax.constraints.impl.Problem) getProblem(); if (flag) ChocoLogging.toSearch(); else ChocoLogging.toSilent(); } @Override public void logStats() { log("*** Execution Profile ***"); ChocoLogging.flushLogs(); // ?? // long occupied_memory = Runtime.getRuntime().totalMemory() // - Runtime.getRuntime().freeMemory(); // log("Occupied memory: " + occupied_memory); long executionTime = System.currentTimeMillis() - getSolverStartTime(); log("Execution time: " + executionTime + " msec"); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy