Skip to content

Commit 0c417ce

Browse files
committed
Solver: Implement visitor pattern.
Fixes #238
1 parent d02f126 commit 0c417ce

2 files changed

Lines changed: 74 additions & 62 deletions

File tree

src/strategy/ibex_Solver.cpp

Lines changed: 19 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//============================================================================
2-
// I B E X
2+
// I B E X
33
// File : ibex_Solver.cpp
44
// Author : Gilles Chabert
55
// Copyright : Ecole des Mines de Nantes (France)
@@ -17,12 +17,16 @@ using namespace std;
1717
namespace ibex {
1818

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

2222
nb_cells=0;
2323

2424
}
2525

26+
void Solver::setVistor(SolverVisitor *visitor) {
27+
this->visitor = visitor;
28+
}
29+
2630
void Solver::start(const IntervalVector& init_box) {
2731
buffer.flush();
2832

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

3640
// add data required by the bisector
3741
bsc.add_backtrackable(*root);
38-
3942
buffer.push(root);
4043

41-
int nb_var=init_box.size();
42-
43-
IntervalVector tmpbox(ctc.nb_var);
44-
4544
Timer::start();
46-
4745
}
4846

49-
bool Solver::next(std::vector<IntervalVector>& sols) {
47+
void Solver::iterate(std::vector<IntervalVector>& sols) {
5048
try {
5149
while (!buffer.empty()) {
5250

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

62+
if(visitor != NULL)
63+
visitor->visit(c->box,EMPTY_BOOL);
64+
6465
ctc.contract(c->box,impact);
6566

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

8990
catch (NoBisectableVariableException&) {
90-
new_sol(sols, c->box);
91-
delete buffer.pop();
92-
return !buffer.empty();
93-
// note that we skip time_limit_check() here.
94-
// In the case where "next" is called by "solve",
95-
// and if time has exceeded, the exception will be raised by the
96-
// very next call to "next" anyway. This holds, unless "next" finds
97-
// new solutions again and again endlessly. So there is a little risk
98-
// of uncaught timeout in this case (but this case is probably already
99-
// an error case).
91+
if(visitor != NULL)
92+
visitor->visit(c->box,MAYBE);
93+
94+
sols.push_back(c->box);
95+
delete buffer.pop();
10096
}
10197
time_limit_check();
10298
}
10399
}
104100
catch (TimeOutException&) {
105-
cout << "time limit " << time_limit << "s. reached " << endl; return false;
101+
cout << "time limit " << time_limit << "s. reached " << endl;
106102
}
107103
catch (CellLimitException&) {
108104
cout << "cell limit " << cell_limit << " reached " << endl;
109105
}
110106

111107
Timer::stop();
112108
time+= Timer::VIRTUAL_TIMELAPSE();
113-
114-
return false;
115-
116109
}
117110

118111
vector<IntervalVector> Solver::solve(const IntervalVector& init_box) {
119112
vector<IntervalVector> sols;
113+
120114
start(init_box);
121-
while (next(sols)) { }
115+
iterate(sols);
116+
122117
return sols;
123118
}
124119

@@ -129,12 +124,4 @@ void Solver::time_limit_check () {
129124
Timer::start();
130125
}
131126

132-
133-
void Solver::new_sol (vector<IntervalVector> & sols, IntervalVector & box) {
134-
sols.push_back(box);
135-
cout.precision(12);
136-
if (trace >=1)
137-
cout << " sol " << sols.size() << " nb_cells " << nb_cells << " " << sols[sols.size()-1] << endl;
138-
}
139-
140127
} // end namespace ibex

src/strategy/ibex_Solver.h

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//============================================================================
2-
// I B E X
2+
// I B E X
33
// File : ibex_Solver.h
44
// Author : Gilles Chabert
55
// Copyright : Ecole des Mines de Nantes (France)
@@ -34,49 +34,60 @@ namespace ibex {
3434

3535
class CellLimitException : public Exception {} ;
3636

37+
/**
38+
* \ingroup set
39+
* \brief Sivia visitor
40+
*/
41+
class SolverVisitor {
42+
public:
43+
/**
44+
* \brief Delete this.
45+
*/
46+
virtual ~SolverVisitor() { }
47+
48+
/**
49+
* \brief Visit
50+
*/
51+
virtual void visit(const IntervalVector& box, BoolInterval status)=0;
52+
53+
};
54+
3755
class Solver {
3856
public:
3957
/**
4058
* \brief Build a solver.
4159
*
42-
* \param ctc - the contractor (for contracting each node of the search tree)
60+
* \param ctc - the contractor (for contracting each node of the search tree)
4361
* \param bsc - the bisector (for branching). Contains the stop criterion.
4462
* \param buffer - the cell buffer (a CellStack in a depth first search strategy)
4563
*/
4664
Solver(Ctc& ctc, Bsc& bsc, CellBuffer& buffer);
4765

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

57-
/**
58-
* \brief Start solving (interactive mode).
59-
*
60-
* Can also be used to restart a new search.
61-
*/
62-
void start(const IntervalVector& init_box);
67+
/**
68+
* \brief Solve the system.
69+
*
70+
* \param init_box - the initial box (the search space)
71+
*
72+
* Return :the vector of solutions (small boxes with the required precision) found by the solver.
73+
*/
74+
std::vector<IntervalVector> solve(const IntervalVector& init_box);
6375

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

77+
/**
78+
* \brief Set a visitor to provide visibility to Solver process.
79+
*
80+
* \param visitor - The visitor to be reported.
81+
*/
82+
void setVistor(SolverVisitor *visitor);
7283

7384
/**
74-
* \brief The contractor
85+
* \brief The contractor
7586
*
76-
* contractor used by the solver for contracting the current box at each node :
87+
* contractor used by the solver for contracting the current box at each node :
7788
* generally, a sequence (with or without fixpoint) of different contractors (hc4 , acid, Newton , a linear relaxation )
7889
*
79-
*/
90+
*/
8091
Ctc& ctc;
8192

8293
/** Bisector (tests also precision of boxes). */
@@ -100,10 +111,10 @@ class Solver {
100111
/**
101112
* \brief Trace level
102113
*
103-
* the trace level.
114+
* the trace level.
104115
* 0 : no trace (default value)
105116
* 1 the solutions are printed each time a new solution is found
106-
* 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
117+
* 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
107118
*/
108119
int trace;
109120

@@ -116,11 +127,25 @@ class Solver {
116127

117128
protected :
118129

119-
void time_limit_check();
130+
/**
131+
* \brief Start solving.
132+
*
133+
* Can also be used to restart a new search.
134+
*/
135+
void start(const IntervalVector& init_box);
136+
137+
/**
138+
* \brief Continue solving.
139+
*
140+
* Look for the next solution and push it into the vector.
141+
* \return false if the search is over (true otherwise).
142+
*/
143+
void iterate(std::vector<IntervalVector>& sols);
120144

121-
void new_sol(std::vector<IntervalVector> & sols, IntervalVector & box);
145+
void time_limit_check();
122146

123147
BitSet impact;
148+
SolverVisitor *visitor;
124149

125150
};
126151

0 commit comments

Comments
 (0)