Skip to content

Commit

Permalink
Add RestartStop
Browse files Browse the repository at this point in the history
This commit adds the RestartStop class that checks whether a given
cutoff for the number of restarts is reached. The RestartStop also made
part of CombinedStop.
  • Loading branch information
Dekker1 authored and zayenz committed Oct 5, 2021
1 parent bbefcea commit 0749349
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 13 deletions.
10 changes: 10 additions & 0 deletions changelog.in
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ Date: 2020-??-??
[DESCRIPTION]
Let's see.

[ENTRY]
Module: search
What: new
Rank: minor
Thanks: Jip J. Dekker
[DESCRIPTION]
Add RestartStop class to enforce a limit on the amount of restarts conducted
in a search. RestartStop is included in CombinedStop and accessible from the
FlatZinc interface through the --restart-limit flag.

[RELEASE]
Version: 6.3.0
Date: 2020-??-??
Expand Down
7 changes: 7 additions & 0 deletions gecode/driver.hh
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,8 @@ namespace Gecode {
Driver::StringOption _restart; ///< Restart method option
Driver::DoubleOption _r_base; ///< Restart base
Driver::UnsignedIntOption _r_scale; ///< Restart scale factor
Driver::UnsignedLongLongIntOption
_r_limit; ///< Cutoff for number of restarts
Driver::BoolOption _nogoods; ///< Whether to use no-goods
Driver::UnsignedIntOption _nogoods_limit; ///< Limit for no-good extraction
Driver::DoubleOption _relax; ///< Probability to relax variable
Expand Down Expand Up @@ -591,6 +593,11 @@ namespace Gecode {
/// Return restart scale factor
unsigned int restart_scale(void) const;

/// Set default restart cutoff
void restart_limit(unsigned long long int n);
/// Return restart cutoff
unsigned long long int restart_limit(void) const;

/// Set default nogoods posting behavior
void nogoods(bool b);
/// Return whether nogoods are used
Expand Down
3 changes: 2 additions & 1 deletion gecode/driver/options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ namespace Gecode {
Search::Config::base),
_r_scale("restart-scale","scale factor for restart sequence",
Search::Config::slice),
_r_limit("restart-limit","restart cutoff (0 = none, solution mode)"),
_nogoods("nogoods","whether to use no-goods from restarts",false),
_nogoods_limit("nogoods-limit","depth limit for no-good extraction",
Search::Config::nogoods_limit),
Expand Down Expand Up @@ -679,7 +680,7 @@ namespace Gecode {
add(_d_l);
add(_node); add(_fail); add(_time); add(_interrupt);
add(_assets); add(_slice);
add(_restart); add(_r_base); add(_r_scale);
add(_restart); add(_r_base); add(_r_scale); add(_r_limit);
add(_nogoods); add(_nogoods_limit);
add(_relax);
add(_mode); add(_iterations); add(_samples); add(_print_last);
Expand Down
9 changes: 9 additions & 0 deletions gecode/driver/options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,15 @@ namespace Gecode {
return _r_scale.value();
}

inline void
Options::restart_limit(unsigned long long int n) {
_r_limit.value(n);
}
inline unsigned long long int
Options::restart_limit(void) const {
return _r_limit.value();
}

inline void
Options::nogoods(bool b) {
_nogoods.value(b);
Expand Down
29 changes: 19 additions & 10 deletions gecode/driver/script.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,18 @@ namespace Gecode { namespace Driver {
Search::NodeStop* ns; ///< Used node stop object
Search::FailStop* fs; ///< Used fail stop object
Search::TimeStop* ts; ///< Used time stop object
Search::RestartStop* rs; ///< Used restart stop object
GECODE_DRIVER_EXPORT
static bool sigint; ///< Whether search was interrupted using Ctrl-C
/// Initialize stop object
CombinedStop(unsigned long long int node,
unsigned long long int fail,
double time)
double time,
unsigned long long int restart)
: ns((node > 0ULL) ? new Search::NodeStop(node) : nullptr),
fs((fail > 0ULL) ? new Search::FailStop(fail) : nullptr),
ts((time > 0.0) ? new Search::TimeStop(time) : nullptr) {
ts((time > 0.0) ? new Search::TimeStop(time) : nullptr),
rs((restart > 0.0) ? new Search::RestartStop(restart) : nullptr) {
sigint = false;
}
public:
Expand All @@ -69,34 +72,38 @@ namespace Gecode { namespace Driver {
SR_NODE = 1 << 0, ///< Node limit reached
SR_FAIL = 1 << 1, ///< Fail limit reached
SR_TIME = 1 << 2, ///< Time limit reached
SR_INT = 1 << 3 ///< Interrupted by user
SR_RESTART = 1 << 3, ///< Time limit reached
SR_INT = 1 << 4 ///< Interrupted by user
};
/// Test whether search must be stopped
virtual bool stop(const Search::Statistics& s, const Search::Options& o) {
return
sigint ||
((ns != nullptr) && ns->stop(s,o)) ||
((fs != nullptr) && fs->stop(s,o)) ||
((ts != nullptr) && ts->stop(s,o));
((ts != nullptr) && ts->stop(s,o)) ||
((rs != nullptr) && rs->stop(s,o));
}
/// Report reason why search has been stopped
int reason(const Search::Statistics& s, const Search::Options& o) {
return
(((ns != nullptr) && ns->stop(s,o)) ? SR_NODE : 0) |
(((fs != nullptr) && fs->stop(s,o)) ? SR_FAIL : 0) |
(((ts != nullptr) && ts->stop(s,o)) ? SR_TIME : 0) |
(((rs != nullptr) && rs->stop(s,o)) ? SR_RESTART : 0) |
(sigint ? SR_INT : 0);
}
/// Create appropriate stop-object
static Search::Stop*
create(unsigned long long int node,
unsigned long long int fail,
double time,
unsigned long long int restart,
bool intr) {
if (!intr && (node == 0ULL) && (fail == 0ULL) && (time == 0.0))
if (!intr && (node == 0ULL) && (fail == 0ULL) && (time == 0.0) && (restart == 0ULL))
return nullptr;
else
return new CombinedStop(node,fail,time);
return new CombinedStop(node,fail,time,restart);
}
#ifdef GECODE_THREADS_WINDOWS
/// Handler for catching Ctrl-C
Expand Down Expand Up @@ -128,7 +135,7 @@ namespace Gecode { namespace Driver {
}
/// Destructor
~CombinedStop(void) {
delete ns; delete fs; delete ts;
delete ns; delete fs; delete ts; delete rs;
}
};

Expand Down Expand Up @@ -379,7 +386,7 @@ namespace Gecode { namespace Driver {
so.d_l = o.d_l();
so.assets = o.assets();
so.slice = o.slice();
so.stop = CombinedStop::create(o.node(),o.fail(), o.time(),
so.stop = CombinedStop::create(o.node(),o.fail(), o.time(), o.restart_limit(),
o.interrupt());
so.cutoff = createCutoff(o);
so.clone = false;
Expand Down Expand Up @@ -431,6 +438,8 @@ namespace Gecode { namespace Driver {
l_out << "fail ";
if (r & CombinedStop::SR_TIME)
l_out << "time ";
if (r & CombinedStop::SR_RESTART)
l_out << "restart ";
l_out << "limit reached" << endl << endl;
}
}
Expand Down Expand Up @@ -480,7 +489,7 @@ namespace Gecode { namespace Driver {
so.c_d = o.c_d();
so.a_d = o.a_d();
so.d_l = o.d_l();
so.stop = CombinedStop::create(o.node(),o.fail(), o.time(),
so.stop = CombinedStop::create(o.node(),o.fail(), o.time(), o.restart_limit(),
o.interrupt());
so.cutoff = createCutoff(o);
so.nogoods_limit = o.nogoods() ? o.nogoods_limit() : 0U;
Expand Down Expand Up @@ -542,7 +551,7 @@ namespace Gecode { namespace Driver {
sok.c_d = o.c_d();
sok.a_d = o.a_d();
sok.d_l = o.d_l();
sok.stop = CombinedStop::create(o.node(),o.fail(), o.time(),
sok.stop = CombinedStop::create(o.node(),o.fail(), o.time(), o.restart_limit(),
false);
sok.cutoff = createCutoff(o);
sok.nogoods_limit = o.nogoods() ? o.nogoods_limit() : 0U;
Expand Down
5 changes: 4 additions & 1 deletion gecode/flatzinc.hh
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ namespace Gecode { namespace FlatZinc {
Gecode::Driver::StringOption _restart; ///< Restart method option
Gecode::Driver::DoubleOption _r_base; ///< Restart base
Gecode::Driver::UnsignedIntOption _r_scale; ///< Restart scale factor
Gecode::Driver::UnsignedLongLongIntOption _r_limit; ///< Cutoff for number of restarts
Gecode::Driver::BoolOption _nogoods; ///< Whether to use no-goods
Gecode::Driver::UnsignedIntOption _nogoods_limit; ///< Depth limit for extracting no-goods
Gecode::Driver::BoolOption _interrupt; ///< Whether to catch SIGINT
Expand Down Expand Up @@ -279,6 +280,7 @@ namespace Gecode { namespace FlatZinc {
_restart("restart","restart sequence type",RM_NONE),
_r_base("restart-base","base for geometric restart sequence",1.5),
_r_scale("restart-scale","scale factor for restart sequence",250),
_r_limit("restart-limit","restart cutoff (0 = none, solution mode)"),
_nogoods("nogoods","whether to use no-goods from restarts",false),
_nogoods_limit("nogoods-limit","depth limit for no-good extraction",
Search::Config::nogoods_limit),
Expand Down Expand Up @@ -310,7 +312,7 @@ namespace Gecode { namespace FlatZinc {
add(_node); add(_fail); add(_time); add(_time_limit); add(_interrupt);
add(_seed);
add(_step);
add(_restart); add(_r_base); add(_r_scale);
add(_restart); add(_r_base); add(_r_scale); add(_r_limit);
add(_nogoods); add(_nogoods_limit);
add(_mode); add(_stat);
add(_output);
Expand Down Expand Up @@ -366,6 +368,7 @@ namespace Gecode { namespace FlatZinc {
void restart_base(double d) { _r_base.value(d); }
unsigned int restart_scale(void) const { return _r_scale.value(); }
void restart_scale(int i) { _r_scale.value(i); }
unsigned long long int restart_limit(void) const { return _r_limit.value(); }
bool nogoods(void) const { return _nogoods.value(); }
unsigned int nogoods_limit(void) const { return _nogoods_limit.value(); }
bool interrupt(void) const { return _interrupt.value(); }
Expand Down
2 changes: 1 addition & 1 deletion gecode/flatzinc/flatzinc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1836,7 +1836,7 @@ namespace Gecode { namespace FlatZinc {
n_p = PropagatorGroup::all.size(*this);
}
Search::Options o;
o.stop = Driver::CombinedStop::create(opt.node(), opt.fail(), opt.time(),
o.stop = Driver::CombinedStop::create(opt.node(), opt.fail(), opt.time(), opt.restart_limit(),
true);
o.c_d = opt.c_d();
o.a_d = opt.a_d();
Expand Down
21 changes: 21 additions & 0 deletions gecode/search.hh
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,8 @@ namespace Gecode { namespace Search {
static Stop* fail(unsigned long long int l);
/// Stop if time limit \a l (in milliseconds) has been exceeded
static Stop* time(double l);
/// Stop if restart limit \a l has been exceeded
static Stop* restart(unsigned long long int l);
//@}
};

Expand Down Expand Up @@ -888,6 +890,25 @@ namespace Gecode { namespace Search {
virtual bool stop(const Statistics& s, const Options& o);
};

/**
* \brief %Stop-object based on number of restarts
* \ingroup TaskModelSearchStop
*/
class GECODE_SEARCH_EXPORT RestartStop : public Stop {
protected:
/// Restart limit
unsigned long long int l;
public:
/// Stop if restart limit \a l is exceeded
RestartStop(unsigned long long int l);
/// Return current limit
unsigned long long int limit(void) const;
/// Set current limit to \a l restarts
void limit(unsigned long long int l);
/// Return true if failure limit is exceeded
virtual bool stop(const Statistics& s, const Options& o);
};

}}

#include <gecode/search/stop.hpp>
Expand Down
12 changes: 12 additions & 0 deletions gecode/search/stop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ namespace Gecode { namespace Search {
Stop::time(double l) {
return new TimeStop(l);
}
Stop*
Stop::restart(unsigned long long int l) {
return new RestartStop(l);
}


/*
Expand Down Expand Up @@ -82,6 +86,14 @@ namespace Gecode { namespace Search {
return t.stop() > l;
}

/*
* Stopping for restart limit
*
*/
bool
RestartStop::stop(const Statistics& s, const Options&) {
return s.restart > l;
}

}}

Expand Down
18 changes: 18 additions & 0 deletions gecode/search/stop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,24 @@ namespace Gecode { namespace Search {
t.start();
}

/*
* Stopping for restart limit
*
*/

forceinline
RestartStop::RestartStop(unsigned long long int l0) : l(l0) {}

forceinline unsigned long long int
RestartStop::limit(void) const {
return l;
}

forceinline void
RestartStop::limit(unsigned long long int l0) {
l=l0;
}

}}

// STATISTICS: search-other
1 change: 1 addition & 0 deletions tools/flatzinc/gecode.msc.in
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
],
["--restart-base", "Base for geometric restart sequence", "float", "1.5"],
["--restart-scale", "Scale factor for restart sequence", "int", "250"],
["--restart-limit", "Restart cutoff", "int", "0"],
["--nogoods", "Use no-goods from restarts", "bool", "false"],
["--nogoods-limit", "Depth limit for no-good extraction", "int", "128"]
],
Expand Down

0 comments on commit 0749349

Please sign in to comment.