Skip to content

Commit

Permalink
Solver: Implement visitor pattern.
Browse files Browse the repository at this point in the history
Fixes #238
  • Loading branch information
schvarcz committed Nov 28, 2016
1 parent d02f126 commit 0c417ce
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 62 deletions.
51 changes: 19 additions & 32 deletions src/strategy/ibex_Solver.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//============================================================================
// I B E X
// I B E X
// File : ibex_Solver.cpp
// Author : Gilles Chabert
// Copyright : Ecole des Mines de Nantes (France)
Expand All @@ -17,12 +17,16 @@ using namespace std;
namespace ibex {

Solver::Solver(Ctc& ctc, Bsc& bsc, CellBuffer& buffer) :
ctc(ctc), bsc(bsc), buffer(buffer), time_limit(-1), cell_limit(-1), trace(0), time(0), impact(BitSet::all(ctc.nb_var)) {
ctc(ctc), visitor(NULL), bsc(bsc), buffer(buffer), time_limit(-1), cell_limit(-1), trace(0), time(0), impact(BitSet::all(ctc.nb_var)) {

nb_cells=0;

}

void Solver::setVistor(SolverVisitor *visitor) {
this->visitor = visitor;
}

void Solver::start(const IntervalVector& init_box) {
buffer.flush();

Expand All @@ -35,18 +39,12 @@ void Solver::start(const IntervalVector& init_box) {

// add data required by the bisector
bsc.add_backtrackable(*root);

buffer.push(root);

int nb_var=init_box.size();

IntervalVector tmpbox(ctc.nb_var);

Timer::start();

}

bool Solver::next(std::vector<IntervalVector>& sols) {
void Solver::iterate(std::vector<IntervalVector>& sols) {
try {
while (!buffer.empty()) {

Expand All @@ -61,6 +59,9 @@ bool Solver::next(std::vector<IntervalVector>& sols) {
else // root node : impact set to 1 for all variables
impact.fill(0,ctc.nb_var-1);

if(visitor != NULL)
visitor->visit(c->box,EMPTY_BOOL);

ctc.contract(c->box,impact);

if (c->box.is_empty()) {
Expand All @@ -87,38 +88,32 @@ bool Solver::next(std::vector<IntervalVector>& sols) {
if (cell_limit >=0 && nb_cells>=cell_limit) throw CellLimitException();}

catch (NoBisectableVariableException&) {
new_sol(sols, c->box);
delete buffer.pop();
return !buffer.empty();
// note that we skip time_limit_check() here.
// In the case where "next" is called by "solve",
// and if time has exceeded, the exception will be raised by the
// very next call to "next" anyway. This holds, unless "next" finds
// new solutions again and again endlessly. So there is a little risk
// of uncaught timeout in this case (but this case is probably already
// an error case).
if(visitor != NULL)
visitor->visit(c->box,MAYBE);

sols.push_back(c->box);
delete buffer.pop();
}
time_limit_check();
}
}
catch (TimeOutException&) {
cout << "time limit " << time_limit << "s. reached " << endl; return false;
cout << "time limit " << time_limit << "s. reached " << endl;
}
catch (CellLimitException&) {
cout << "cell limit " << cell_limit << " reached " << endl;
}

Timer::stop();
time+= Timer::VIRTUAL_TIMELAPSE();

return false;

}

vector<IntervalVector> Solver::solve(const IntervalVector& init_box) {
vector<IntervalVector> sols;

start(init_box);
while (next(sols)) { }
iterate(sols);

return sols;
}

Expand All @@ -129,12 +124,4 @@ void Solver::time_limit_check () {
Timer::start();
}


void Solver::new_sol (vector<IntervalVector> & sols, IntervalVector & box) {
sols.push_back(box);
cout.precision(12);
if (trace >=1)
cout << " sol " << sols.size() << " nb_cells " << nb_cells << " " << sols[sols.size()-1] << endl;
}

} // end namespace ibex
85 changes: 55 additions & 30 deletions src/strategy/ibex_Solver.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//============================================================================
// I B E X
// I B E X
// File : ibex_Solver.h
// Author : Gilles Chabert
// Copyright : Ecole des Mines de Nantes (France)
Expand Down Expand Up @@ -34,49 +34,60 @@ namespace ibex {

class CellLimitException : public Exception {} ;

/**
* \ingroup set
* \brief Sivia visitor
*/
class SolverVisitor {
public:
/**
* \brief Delete this.
*/
virtual ~SolverVisitor() { }

/**
* \brief Visit
*/
virtual void visit(const IntervalVector& box, BoolInterval status)=0;

};

class Solver {
public:
/**
* \brief Build a solver.
*
* \param ctc - the contractor (for contracting each node of the search tree)
* \param ctc - the contractor (for contracting each node of the search tree)
* \param bsc - the bisector (for branching). Contains the stop criterion.
* \param buffer - the cell buffer (a CellStack in a depth first search strategy)
*/
Solver(Ctc& ctc, Bsc& bsc, CellBuffer& buffer);

/**
* \brief Solve the system (non-interactive mode).
*
* \param init_box - the initial box (the search space)
*
* Return :the vector of solutions (small boxes with the required precision) found by the solver.
*/
std::vector<IntervalVector> solve(const IntervalVector& init_box);

/**
* \brief Start solving (interactive mode).
*
* Can also be used to restart a new search.
*/
void start(const IntervalVector& init_box);
/**
* \brief Solve the system.
*
* \param init_box - the initial box (the search space)
*
* Return :the vector of solutions (small boxes with the required precision) found by the solver.
*/
std::vector<IntervalVector> solve(const IntervalVector& init_box);

/**
* \brief Continue solving (interactive mode).
*
* Look for the next solution and push it into the vector.
* \return false if the search is over (true otherwise).
*/
bool next(std::vector<IntervalVector>& sols);

/**
* \brief Set a visitor to provide visibility to Solver process.
*
* \param visitor - The visitor to be reported.
*/
void setVistor(SolverVisitor *visitor);

/**
* \brief The contractor
* \brief The contractor
*
* contractor used by the solver for contracting the current box at each node :
* contractor used by the solver for contracting the current box at each node :
* generally, a sequence (with or without fixpoint) of different contractors (hc4 , acid, Newton , a linear relaxation )
*
*/
*/
Ctc& ctc;

/** Bisector (tests also precision of boxes). */
Expand All @@ -100,10 +111,10 @@ class Solver {
/**
* \brief Trace level
*
* the trace level.
* the trace level.
* 0 : no trace (default value)
* 1 the solutions are printed each time a new solution is found
* 2 the solutions are printed each time a new solution is found and the current box is printed at each node of the branch and prune algorithm
* 2 the solutions are printed each time a new solution is found and the current box is printed at each node of the branch and prune algorithm
*/
int trace;

Expand All @@ -116,11 +127,25 @@ class Solver {

protected :

void time_limit_check();
/**
* \brief Start solving.
*
* Can also be used to restart a new search.
*/
void start(const IntervalVector& init_box);

/**
* \brief Continue solving.
*
* Look for the next solution and push it into the vector.
* \return false if the search is over (true otherwise).
*/
void iterate(std::vector<IntervalVector>& sols);

void new_sol(std::vector<IntervalVector> & sols, IntervalVector & box);
void time_limit_check();

BitSet impact;
SolverVisitor *visitor;

};

Expand Down

0 comments on commit 0c417ce

Please sign in to comment.