40#ifndef GECODE_THREADS_WINDOWS
59 CombinedStop(
unsigned long long int node,
60 unsigned long long int fail,
82 ((ns !=
nullptr) && ns->stop(s,o)) ||
83 ((fs !=
nullptr) && fs->stop(s,o)) ||
84 ((ts !=
nullptr) && ts->stop(s,o)) ||
85 ((rs !=
nullptr) && rs->stop(s,o));
90 (((ns !=
nullptr) && ns->stop(s,o)) ?
SR_NODE : 0) |
91 (((fs !=
nullptr) && fs->stop(s,o)) ?
SR_FAIL : 0) |
92 (((ts !=
nullptr) && ts->stop(s,o)) ?
SR_TIME : 0) |
93 (((rs !=
nullptr) && rs->stop(s,o)) ?
SR_RESTART : 0) |
99 unsigned long long int fail,
101 unsigned long long int restart,
108#ifdef GECODE_THREADS_WINDOWS
110 static BOOL
interrupt(DWORD t)
noexcept {
111 if (t == CTRL_C_EVENT) {
128 if (force || !sigint) {
129#ifdef GECODE_THREADS_WINDOWS
130 SetConsoleCtrlHandler( (PHANDLER_ROUTINE)
interrupt, install);
132 std::signal(SIGINT, install ?
interrupt : SIG_DFL);
138 delete ns;
delete fs;
delete ts;
delete rs;
153 am(
double t[],
unsigned int n);
159 dev(
double t[],
unsigned int n);
162 template<
class Options>
182#ifdef GECODE_HAS_GIST
187 template<
class Engine>
224#ifdef GECODE_HAS_CPPROFILER
227 template<
class BaseSpace>
238 template<
class BaseSpace>
243 template<
class BaseSpace>
248 template<
class BaseSpace>
252 template<
class BaseSpace>
256 template<
class BaseSpace>
259 if (strcmp(sn,
"stdout") == 0) {
261 }
else if (strcmp(sn,
"stdlog") == 0) {
263 }
else if (strcmp(sn,
"stderr") == 0) {
271#ifdef GECODE_HAS_CPPROFILER
273 template<
class BaseSpace>
276 template<
class BaseSpace>
279 std::stringstream ss;
292 template<
class T,
template<
class>
class E>
298 template<
class BaseSpace>
299 template<
class Script,
template<
class>
class Engine,
class Options>
303 std::cerr <<
"Cannot use restarts and portfolio..." << std::endl;
307 runMeta<Script,Engine,Options,RBS>(o,s);
308 }
else if (o.
assets() > 0) {
309 runMeta<Script,Engine,Options,PBS>(o,s);
311 runMeta<Script,Engine,Options,EngineToMeta>(o,s);
315 template<
class BaseSpace>
316 template<
class Script,
template<
class>
class Engine,
class Options,
317 template<
class,
template<
class>
class>
class Meta>
319 ScriptBase<BaseSpace>::runMeta(const Options& o, Script* s) {
322 ofstream sol_file, log_file;
324 ostream& s_out = select_ostream(o.out_file(), sol_file);
325 ostream& l_out = select_ostream(o.log_file(), log_file);
332#ifdef GECODE_HAS_GIST
337 opt.inspect.click(&
pi);
338 opt.inspect.compare(&vc);
342 for (
unsigned int i=0; o.inspect.click(i) !=
nullptr; i++)
343 opt.inspect.click(o.inspect.click(i));
344 for (
unsigned int i=0; o.inspect.solution(i) !=
nullptr; i++)
345 opt.inspect.solution(o.inspect.solution(i));
346 for (
unsigned int i=0; o.inspect.move(i) !=
nullptr; i++)
347 opt.inspect.move(o.inspect.move(i));
348 for (
unsigned int i=0; o.inspect.compare(i) !=
nullptr; i++)
349 opt.inspect.compare(o.inspect.compare(i));
352 (void)
GistEngine<Engine<Script> >::explore(s, opt);
360#ifndef GECODE_HAS_GIST
364#ifdef GECODE_HAS_CPPROFILER
365 if (o.profiler_port()) {
367 getInfo =
new ScriptGetInfo<BaseSpace>;
369 (o.profiler_id(), o.name(), o.profiler_port(), getInfo);
372 l_out << o.name() << endl;
374 unsigned long long int s_l =
375 (o.solutions() == 0) ? ULLONG_MAX : o.solutions();
376 unsigned long long int s_n = 0;
380 unsigned int n_p = PropagatorGroup::all.size(*s);
381 unsigned int n_b = BrancherGroup::all.size(*s);
387 so.
slice = o.slice();
388 so.
stop = CombinedStop::create(o.node(),o.fail(), o.time(), o.restart_limit(),
390 so.
cutoff = createCutoff(o);
394 CombinedStop::installCtrlHandler(
true);
396 Meta<Script,Engine> e(s,so);
397 if (o.print_last()) {
398 Script* px =
nullptr;
400 Script* ex = e.next();
424 CombinedStop::installCtrlHandler(
false);
425 Search::Statistics stat = e.statistics();
428 l_out <<
"Search engine stopped..." << endl
430 int r =
static_cast<CombinedStop*
>(so.
stop)->reason(stat,so);
431 if (r & CombinedStop::SR_INT)
432 l_out <<
"user interrupt " << endl;
434 if (r & CombinedStop::SR_NODE)
436 if (r & CombinedStop::SR_FAIL)
438 if (r & CombinedStop::SR_TIME)
440 if (r & CombinedStop::SR_RESTART)
442 l_out <<
"limit reached" << endl << endl;
445 l_out <<
"Initial" << endl
446 <<
"\tpropagators: " << n_p << endl
447 <<
"\tbranchers: " << n_b << endl
453 <<
"\tsolutions: " << s_n << endl
454 <<
"\tpropagations: " << stat.propagate << endl
455 <<
"\tnodes: " << stat.node << endl
456 <<
"\tfailures: " << stat.fail << endl
457 <<
"\trestarts: " << stat.restart << endl
458 <<
"\tno-goods: " << stat.nogood << endl
459 <<
"\tpeak depth: " << stat.depth << endl
460#ifdef GECODE_PEAKHEAP
462 <<
static_cast<int>((
heap.peak()+1023) / 1024) <<
" KB"
473 l_out << o.name() << endl;
475 unsigned long long int s_l =
476 (o.solutions() == 0) ? ULLONG_MAX : o.solutions();
477 unsigned long long int s_n = 0;
481 unsigned int n_p = PropagatorGroup::all.size(*s);
482 unsigned int n_b = BrancherGroup::all.size(*s);
487 so.
slice = o.slice();
491 so.
stop = CombinedStop::create(o.node(),o.fail(), o.time(), o.restart_limit(),
496 CombinedStop::installCtrlHandler(
true);
498 Meta<Script,Engine> e(s,so);
507 CombinedStop::installCtrlHandler(
false);
508 Search::Statistics stat = e.statistics();
510 <<
"\tpropagators: " << n_p << endl
511 <<
"\tbranchers: " << n_b << endl
515 <<
"\tsolutions: " << s_n << endl
516 <<
"\tpropagations: " << stat.propagate << endl
517 <<
"\tnodes: " << stat.node << endl
518 <<
"\tfailures: " << stat.fail << endl
519 <<
"\trestarts: " << stat.restart << endl
520 <<
"\tno-goods: " << stat.nogood << endl
521 <<
"\tpeak depth: " << stat.depth << endl
522#ifdef GECODE_PEAKHEAP
524 <<
static_cast<int>((
heap.peak()+1023) / 1024) <<
" KB"
534 l_out << o.name() << endl;
536 double* ts =
new double[o.samples()];
537 bool stopped =
false;
538 for (
unsigned int ns = o.samples(); !stopped && ns--; ) {
539 unsigned long long int s_l =
540 (o.solutions() == 0) ? ULLONG_MAX : o.solutions();
542 for (
unsigned int k = o.iterations(); !stopped && k--; ) {
543 unsigned long long int s_n = 0;
547 sok.threads = o.threads();
548 sok.assets = o.assets();
549 sok.slice = o.slice();
553 sok.stop = CombinedStop::create(o.node(),o.fail(), o.time(), o.restart_limit(),
556 sok.nogoods_limit = o.nogoods() ? o.nogoods_limit() : 0U;
558 Meta<Script,Engine> e(s1,sok);
571 ts[ns] = t.stop() / o.iterations();
574 l_out <<
"\tSTOPPED" << endl;
576 double m =
am(ts,o.samples());
577 double d =
dev(ts,o.samples()) * 100.0;
578 l_out <<
"\truntime: "
580 << showpoint << fixed
581 << setprecision(6) << m <<
"ms"
582 << setprecision(2) <<
" (" << d <<
"% deviation)"
589 }
catch (Exception& e) {
590 cerr <<
"Exception: " << e.what() <<
"." << endl
591 <<
"Stopping..." << endl;
592 if (sol_file.is_open())
594 if (log_file.is_open())
598 if (sol_file.is_open())
600 if (log_file.is_open())
Depth-first branch-and-bound search engine.
Class to send solution information to CPProfiler.
Class to record search trace info for CPProfiler.
Depth-first search engine.
~CombinedStop(void)
Destructor.
static void installCtrlHandler(bool install, bool force=false)
Install handler for catching Ctrl-C.
virtual bool stop(const Search::Statistics &s, const Search::Options &o)
Test whether search must be stopped.
static void interrupt(int)
Handler for catching Ctrl-C.
@ SR_INT
Interrupted by user.
@ SR_NODE
Node limit reached.
@ SR_FAIL
Fail limit reached.
@ SR_TIME
Time limit reached.
@ SR_RESTART
Time limit reached.
static Search::Stop * create(unsigned long long int node, unsigned long long int fail, double time, unsigned long long int restart, bool intr)
Create appropriate stop-object.
int reason(const Search::Statistics &s, const Search::Options &o)
Report reason why search has been stopped.
static void explore(S *root, const Gist::Options &opt)
static void explore(S *root, const Gist::Options &opt)
static void explore(S *root, const Gist::Options &opt)
Traits class for search engines.
static void explore(Space *root, const Gist::Options &opt)
Parametric base-class for scripts.
static void run(const Options &opt, Script *s=nullptr)
virtual void compare(const Space &home, std::ostream &os) const
Compare with s.
virtual void print(std::ostream &os) const
Print a solution to os.
static std::ostream & select_ostream(const char *sn, std::ofstream &ofs)
Choose output stream according to sn.
ScriptBase(const Options &opt)
Constructor.
ScriptGetInfo(void)
Initialize.
virtual std::string getInfo(const Space &home) const
Return info for a space (which must be a script).
An inspector for printing simple text output.
Limited discrepancy search engine.
void restart(RestartMode r)
Set default restart mode.
void assets(unsigned int n)
Set default number of assets in a portfolio.
void restart_scale(unsigned int scale)
Set default restart scale factor.
void restart_base(double base)
Set default restart base.
Base class for cutoff generators for restart-based meta engine.
static Cutoff * linear(unsigned long long int scale=Config::slice)
Create generator for linear sequence scaled by scale.
static Cutoff * constant(unsigned long long int scale=Config::slice)
Create generator for constant sequence with constant s.
static Cutoff * luby(unsigned long long int scale=Config::slice)
Create generator for luby sequence with scale-factor scale.
static Cutoff * geometric(unsigned long long int scale=Config::slice, double base=Config::base)
Stop-object based on number of failures
Stop-object based on number of nodes
unsigned int c_d
Create a clone after every c_d commits (commit distance).
bool clone
Whether engines create a clone when being initialized.
unsigned int d_l
Discrepancy limit (for LDS).
Cutoff * cutoff
Cutoff for restart-based search.
unsigned int a_d
Create a clone during recomputation if distance is greater than a_d (adaptive distance).
Stop * stop
Stop object for stopping search.
SearchTracer * tracer
Tracer object for tracing search.
unsigned int assets
Number of assets (engines) in a portfolio.
unsigned int slice
Size of a slice in a portfolio (in number of failures).
unsigned int nogoods_limit
Depth limit for extraction of no-goods.
double threads
Number of threads to use.
Stop-object based on number of restarts
Base-class for Stop-object.
static Stop * node(unsigned long long int l)
Stop if node limit l has been exceeded.
static Stop * time(double l)
Stop if time limit l (in milliseconds) has been exceeded.
static Stop * fail(unsigned long long int l)
Stop if failure limit l has been exceeded.
static Stop * restart(unsigned long long int l)
Stop if restart limit l has been exceeded.
Stop-object based on time
#define GECODE_DRIVER_EXPORT
Heap heap
The single global heap.
@ SM_STAT
Print statistics for script.
@ SM_SOLUTION
Print solution and some statistics.
@ SM_GIST
Run script in Gist.
@ SM_TIME
Measure average runtime.
@ RM_CONSTANT
Restart with constant sequence.
@ RM_LINEAR
Restart with linear sequence.
@ RM_LUBY
Restart with Luby sequence.
@ RM_GEOMETRIC
Restart with geometric sequence.
Driver::ScriptBase< Driver::IgnoreStepOption< Space > > Script
Base-class for scripts.
int bab(Space *root, const Gist::Options &opt=Gist::Options::def)
Create a new stand-alone Gist for branch-and-bound search of root.
int dfs(Space *root, const Gist::Options &opt=Gist::Options::def)
Create a new stand-alone Gist for root.
Script commandline driver.
double dev(double t[], unsigned int n)
Compute deviation of n elements in t.
void stop(Support::Timer &t, std::ostream &os)
Get time since start of timer and print user friendly time information.
Search::Cutoff * createCutoff(const Options &o)
Create cutoff object from options.
double am(double t[], unsigned int n)
Compute arithmetic mean of n elements in t.
Gecode toplevel namespace
#define GECODE_NEVER
Assert that this command is never executed.