1
0

Merge commit '67191769756e84fc5b7b3c401048fef6b8adff67' into develop

This commit is contained in:
Jip J. Dekker 2021-07-11 16:26:15 +10:00
commit 93c38edc9f
No known key found for this signature in database
GPG Key ID: 517DF4A00618C9C3
22 changed files with 684 additions and 379 deletions

View File

@ -817,11 +817,11 @@ endif
# FLATZINC
#
FLATZINCSRC0 = flatzinc.cpp registry.cpp branch.cpp lastval.cpp
FLATZINCSRC0 = flatzinc.cpp registry.cpp branch.cpp lastval.cpp complete.cpp
FLATZINC_GENSRC0 = parser.tab.cpp lexer.yy.cpp
FLATZINCHDR0 = ast.hh conexpr.hh option.hh parser.hh \
plugin.hh registry.hh symboltable.hh varspec.hh \
branch.hh branch.hpp lastval.hh
branch.hh branch.hpp lastval.hh complete.hh
FLATZINCSRC = $(FLATZINCSRC0:%=gecode/flatzinc/%)
FLATZINC_GENSRC = $(FLATZINC_GENSRC0:%=gecode/flatzinc/%)

View File

@ -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-??-??

View File

@ -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
@ -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

View File

@ -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),
@ -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);

View File

@ -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);

View File

@ -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:
@ -69,7 +72,8 @@ 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) {
@ -77,7 +81,8 @@ namespace Gecode { namespace Driver {
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) {
@ -85,6 +90,7 @@ namespace Gecode { namespace Driver {
(((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
@ -92,11 +98,12 @@ namespace Gecode { namespace Driver {
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
@ -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;
}
};
@ -378,7 +385,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;
@ -430,6 +437,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;
}
}
@ -479,7 +488,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;
@ -541,7 +550,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;

View File

@ -244,6 +244,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
@ -281,6 +282,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),
@ -312,7 +314,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);
@ -368,6 +370,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(); }
@ -482,6 +485,9 @@ namespace Gecode { namespace FlatZinc {
/// The integer variables used in LNS
Gecode::IntVarArray iv_lns;
/// Complete() variable
Gecode::BoolVarArray restart_complete;
std::shared_ptr<bool> complete_marker;
/// Status() variable
Gecode::IntVarArray restart_status;
/// int_uniform arguments

View File

@ -0,0 +1,70 @@
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Jip J. Dekker <jip.dekker@monash.edu>
*
* Copyright:
* Jip J. Dekker, 2018
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "complete.hh"
namespace Gecode { namespace FlatZinc {
Complete::Complete(Space &home, Complete &p)
: UnaryPropagator<BoolView, PC_BOOL_VAL>(home,p), c(p.c) {}
Complete::Complete(Home home, BoolView x0, std::shared_ptr<bool> c)
: c(c), UnaryPropagator<BoolView, PC_BOOL_VAL>(home, x0) {}
Actor* Complete::copy(Space &home) {
return new (home) Complete(home,*this);
}
PropCost Complete::cost(const Space &home, const ModEventDelta &med) const {
return PropCost::record();
}
ExecStatus Complete::propagate(Space &home, const ModEventDelta &med) {
assert(x0.assigned());
(*c) = x0.val();
return ES_FAILED;
}
ExecStatus Complete::post(Home home, BoolView x0, std::shared_ptr<bool> c) {
assert(c != nullptr);
if (x0.assigned()) {
(*c) = x0.val();
} else {
(void) new (home) Complete(home, x0, c);
}
return ES_OK;
}
}}

View File

@ -0,0 +1,65 @@
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
* Jip J. Dekker <jip.dekker@monash.edu>
*
* Copyright:
* Jip J. Dekker, 2018
*
* This file is part of Gecode, the generic constraint
* development environment:
* http://www.gecode.org
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __FLATZINC_COMPLETE_HH__
#define __FLATZINC_COMPLETE_HH__
#include <gecode/int.hh>
#include <memory>
using namespace Gecode::Int;
namespace Gecode { namespace FlatZinc {
class Complete : public UnaryPropagator<BoolView, PC_BOOL_VAL> {
protected:
using UnaryPropagator<BoolView,PC_BOOL_VAL>::x0;
std::shared_ptr<bool> c;
/// Constructor for cloning \a p
Complete(Space& home, Complete& p);
/// Constructor for posting
Complete(Home home, BoolView x0, std::shared_ptr<bool> c);
public:
/// Copy propagator during cloning
virtual Actor* copy(Space& home);
/// Cost function (defined as TODO)
virtual PropCost cost(const Space& home, const ModEventDelta& med) const;
/// Perform propagation
virtual ExecStatus propagate(Space& home, const ModEventDelta& med);
static ExecStatus post(Home home, BoolView x0, std::shared_ptr<bool> c);
};
}}
#endif //__FLATZINC_COMPLETE_HH__

View File

@ -790,6 +790,7 @@ namespace Gecode { namespace FlatZinc {
iv_lns.update(*this, f.iv_lns);
intVarCount = f.intVarCount;
restart_complete.update(*this, f.restart_complete);
restart_status.update(*this, f.restart_status);
int_uniform_var.update(*this, f.int_uniform_var);
int_uniform_lb = f.int_uniform_lb;
@ -1847,7 +1848,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();
@ -2012,16 +2013,37 @@ namespace Gecode { namespace FlatZinc {
bool
FlatZincSpace::slave(const MetaInfo& mi) {
if (mi.type() == MetaInfo::RESTART) {
if (restart_complete.size() > 0) {
assert(restart_complete.size() == 1);
assert(complete_marker != nullptr);
if (*complete_marker) {
// Fail the space
this->fail();
// Return true to signal we are in the global search space
return true;
}
}
bool ret = false;
if (restart_status.size() > 0) {
assert(restart_status.size() == 1);
if (!mi.last()) {
rel(*this, restart_status[0], IRT_EQ, 1); // 1: START
} else if (mi.solution() > 0) {
rel(*this, restart_status[0], IRT_EQ, 4); // 4: SAT
} else {
rel(*this, restart_status[0], IRT_EQ, 2); // 2: UNKNOWN
}
switch(mi.reason()) {
case MetaInfo::RR_INIT:
assert(!mi.last());
rel(*this, restart_status[0], IRT_EQ, 1); // 1: START
break;
case MetaInfo::RR_SOL:
assert(mi.solution() > 0);
rel(*this, restart_status[0], IRT_EQ, 4); // 4: SAT
break;
case MetaInfo::RR_CMPL:
rel(*this, restart_status[0], IRT_EQ, 3); // 3: UNSAT
break;
default:
assert(mi.reason() == MetaInfo::RR_LIM);
rel(*this, restart_status[0], IRT_EQ, 2); // 2: UNKNOWN
break;
}
restart_status = IntVarArray(*this, 0);
ret = true;
}

View File

@ -597,7 +597,7 @@ static const flex_int32_t yy_rule_can_match_eol[57] =
#define yymore() yymore_used_but_not_detected
#define YY_MORE_ADJ 0
#define YY_RESTORE_YY_MORE_OFFSET
#line 1 "../gecode/flatzinc/lexer.lxx"
#line 1 "gecode/flatzinc/lexer.lxx"
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
* Main authors:
@ -630,7 +630,7 @@ static const flex_int32_t yy_rule_can_match_eol[57] =
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#line 40 "../gecode/flatzinc/lexer.lxx"
#line 40 "gecode/flatzinc/lexer.lxx"
#if defined __GNUC__
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-parameter"
@ -939,7 +939,7 @@ YY_DECL
}
{
#line 75 "../gecode/flatzinc/lexer.lxx"
#line 75 "gecode/flatzinc/lexer.lxx"
#line 945 "gecode/flatzinc/lexer.yy.cpp"
@ -1014,32 +1014,32 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
/* rule 1 can match eol */
YY_RULE_SETUP
#line 77 "../gecode/flatzinc/lexer.lxx"
#line 77 "gecode/flatzinc/lexer.lxx"
{ /*yylineno++;*/ /* ignore EOL */ }
YY_BREAK
case 2:
YY_RULE_SETUP
#line 78 "../gecode/flatzinc/lexer.lxx"
#line 78 "gecode/flatzinc/lexer.lxx"
{ /* ignore whitespace */ }
YY_BREAK
case 3:
YY_RULE_SETUP
#line 79 "../gecode/flatzinc/lexer.lxx"
#line 79 "gecode/flatzinc/lexer.lxx"
{ /* ignore comments */ }
YY_BREAK
case 4:
YY_RULE_SETUP
#line 81 "../gecode/flatzinc/lexer.lxx"
#line 81 "gecode/flatzinc/lexer.lxx"
{ yylval->iValue = 1; return FZ_BOOL_LIT; }
YY_BREAK
case 5:
YY_RULE_SETUP
#line 82 "../gecode/flatzinc/lexer.lxx"
#line 82 "gecode/flatzinc/lexer.lxx"
{ yylval->iValue = 0; return FZ_BOOL_LIT; }
YY_BREAK
case 6:
YY_RULE_SETUP
#line 83 "../gecode/flatzinc/lexer.lxx"
#line 83 "gecode/flatzinc/lexer.lxx"
{ if (parseInt(yytext,yylval->iValue))
return FZ_INT_LIT;
else
@ -1052,7 +1052,7 @@ YY_RULE_SETUP
YY_BREAK
case 7:
YY_RULE_SETUP
#line 92 "../gecode/flatzinc/lexer.lxx"
#line 92 "gecode/flatzinc/lexer.lxx"
{ if (parseInt(yytext,yylval->iValue))
return FZ_INT_LIT;
else
@ -1065,7 +1065,7 @@ YY_RULE_SETUP
YY_BREAK
case 8:
YY_RULE_SETUP
#line 101 "../gecode/flatzinc/lexer.lxx"
#line 101 "gecode/flatzinc/lexer.lxx"
{ if (parseInt(yytext,yylval->iValue))
return FZ_INT_LIT;
else
@ -1078,235 +1078,235 @@ YY_RULE_SETUP
YY_BREAK
case 9:
YY_RULE_SETUP
#line 110 "../gecode/flatzinc/lexer.lxx"
#line 110 "gecode/flatzinc/lexer.lxx"
{ yylval->dValue = strtod(yytext,NULL);
return FZ_FLOAT_LIT; }
YY_BREAK
case 10:
YY_RULE_SETUP
#line 112 "../gecode/flatzinc/lexer.lxx"
#line 112 "gecode/flatzinc/lexer.lxx"
{ yylval->dValue = strtod(yytext,NULL);
return FZ_FLOAT_LIT; }
YY_BREAK
case 11:
YY_RULE_SETUP
#line 114 "../gecode/flatzinc/lexer.lxx"
#line 114 "gecode/flatzinc/lexer.lxx"
{ yylval->dValue = strtod(yytext,NULL);
return FZ_FLOAT_LIT; }
YY_BREAK
case 12:
YY_RULE_SETUP
#line 116 "../gecode/flatzinc/lexer.lxx"
#line 116 "gecode/flatzinc/lexer.lxx"
{ return *yytext; }
YY_BREAK
case 13:
YY_RULE_SETUP
#line 117 "../gecode/flatzinc/lexer.lxx"
#line 117 "gecode/flatzinc/lexer.lxx"
{ return FZ_DOTDOT; }
YY_BREAK
case 14:
YY_RULE_SETUP
#line 118 "../gecode/flatzinc/lexer.lxx"
#line 118 "gecode/flatzinc/lexer.lxx"
{ return FZ_COLONCOLON; }
YY_BREAK
case 15:
YY_RULE_SETUP
#line 119 "../gecode/flatzinc/lexer.lxx"
#line 119 "gecode/flatzinc/lexer.lxx"
{ return FZ_ANNOTATION; }
YY_BREAK
case 16:
YY_RULE_SETUP
#line 120 "../gecode/flatzinc/lexer.lxx"
#line 120 "gecode/flatzinc/lexer.lxx"
{ return FZ_ANY; }
YY_BREAK
case 17:
YY_RULE_SETUP
#line 121 "../gecode/flatzinc/lexer.lxx"
#line 121 "gecode/flatzinc/lexer.lxx"
{ return FZ_ARRAY; }
YY_BREAK
case 18:
YY_RULE_SETUP
#line 122 "../gecode/flatzinc/lexer.lxx"
#line 122 "gecode/flatzinc/lexer.lxx"
{ return FZ_BOOL; }
YY_BREAK
case 19:
YY_RULE_SETUP
#line 123 "../gecode/flatzinc/lexer.lxx"
#line 123 "gecode/flatzinc/lexer.lxx"
{ return FZ_CASE; }
YY_BREAK
case 20:
YY_RULE_SETUP
#line 124 "../gecode/flatzinc/lexer.lxx"
#line 124 "gecode/flatzinc/lexer.lxx"
{ return FZ_CONSTRAINT; }
YY_BREAK
case 21:
YY_RULE_SETUP
#line 125 "../gecode/flatzinc/lexer.lxx"
#line 125 "gecode/flatzinc/lexer.lxx"
{ return FZ_DEFAULT; }
YY_BREAK
case 22:
YY_RULE_SETUP
#line 126 "../gecode/flatzinc/lexer.lxx"
#line 126 "gecode/flatzinc/lexer.lxx"
{ return FZ_ELSE; }
YY_BREAK
case 23:
YY_RULE_SETUP
#line 127 "../gecode/flatzinc/lexer.lxx"
#line 127 "gecode/flatzinc/lexer.lxx"
{ return FZ_ELSEIF; }
YY_BREAK
case 24:
YY_RULE_SETUP
#line 128 "../gecode/flatzinc/lexer.lxx"
#line 128 "gecode/flatzinc/lexer.lxx"
{ return FZ_ENDIF; }
YY_BREAK
case 25:
YY_RULE_SETUP
#line 129 "../gecode/flatzinc/lexer.lxx"
#line 129 "gecode/flatzinc/lexer.lxx"
{ return FZ_ENUM; }
YY_BREAK
case 26:
YY_RULE_SETUP
#line 130 "../gecode/flatzinc/lexer.lxx"
#line 130 "gecode/flatzinc/lexer.lxx"
{ return FZ_FLOAT; }
YY_BREAK
case 27:
YY_RULE_SETUP
#line 131 "../gecode/flatzinc/lexer.lxx"
#line 131 "gecode/flatzinc/lexer.lxx"
{ return FZ_FUNCTION; }
YY_BREAK
case 28:
YY_RULE_SETUP
#line 132 "../gecode/flatzinc/lexer.lxx"
#line 132 "gecode/flatzinc/lexer.lxx"
{ return FZ_IF; }
YY_BREAK
case 29:
YY_RULE_SETUP
#line 133 "../gecode/flatzinc/lexer.lxx"
#line 133 "gecode/flatzinc/lexer.lxx"
{ return FZ_INCLUDE; }
YY_BREAK
case 30:
YY_RULE_SETUP
#line 134 "../gecode/flatzinc/lexer.lxx"
#line 134 "gecode/flatzinc/lexer.lxx"
{ return FZ_INT; }
YY_BREAK
case 31:
YY_RULE_SETUP
#line 135 "../gecode/flatzinc/lexer.lxx"
#line 135 "gecode/flatzinc/lexer.lxx"
{ return FZ_LET; }
YY_BREAK
case 32:
YY_RULE_SETUP
#line 136 "../gecode/flatzinc/lexer.lxx"
#line 136 "gecode/flatzinc/lexer.lxx"
{ yylval->bValue = false; return FZ_MAXIMIZE; }
YY_BREAK
case 33:
YY_RULE_SETUP
#line 137 "../gecode/flatzinc/lexer.lxx"
#line 137 "gecode/flatzinc/lexer.lxx"
{ yylval->bValue = true; return FZ_MINIMIZE; }
YY_BREAK
case 34:
YY_RULE_SETUP
#line 138 "../gecode/flatzinc/lexer.lxx"
#line 138 "gecode/flatzinc/lexer.lxx"
{ return FZ_OF; }
YY_BREAK
case 35:
YY_RULE_SETUP
#line 139 "../gecode/flatzinc/lexer.lxx"
#line 139 "gecode/flatzinc/lexer.lxx"
{ return FZ_SATISFY; }
YY_BREAK
case 36:
YY_RULE_SETUP
#line 140 "../gecode/flatzinc/lexer.lxx"
#line 140 "gecode/flatzinc/lexer.lxx"
{ return FZ_OUTPUT; }
YY_BREAK
case 37:
YY_RULE_SETUP
#line 141 "../gecode/flatzinc/lexer.lxx"
#line 141 "gecode/flatzinc/lexer.lxx"
{ yylval->bValue = false; return FZ_PAR; }
YY_BREAK
case 38:
YY_RULE_SETUP
#line 142 "../gecode/flatzinc/lexer.lxx"
#line 142 "gecode/flatzinc/lexer.lxx"
{ return FZ_PREDICATE; }
YY_BREAK
case 39:
YY_RULE_SETUP
#line 143 "../gecode/flatzinc/lexer.lxx"
#line 143 "gecode/flatzinc/lexer.lxx"
{ return FZ_RECORD; }
YY_BREAK
case 40:
YY_RULE_SETUP
#line 144 "../gecode/flatzinc/lexer.lxx"
#line 144 "gecode/flatzinc/lexer.lxx"
{ return FZ_SET; }
YY_BREAK
case 41:
YY_RULE_SETUP
#line 145 "../gecode/flatzinc/lexer.lxx"
#line 145 "gecode/flatzinc/lexer.lxx"
{ return FZ_SHOWCOND; }
YY_BREAK
case 42:
YY_RULE_SETUP
#line 146 "../gecode/flatzinc/lexer.lxx"
#line 146 "gecode/flatzinc/lexer.lxx"
{ return FZ_SHOW; }
YY_BREAK
case 43:
YY_RULE_SETUP
#line 147 "../gecode/flatzinc/lexer.lxx"
#line 147 "gecode/flatzinc/lexer.lxx"
{ return FZ_SOLVE; }
YY_BREAK
case 44:
YY_RULE_SETUP
#line 148 "../gecode/flatzinc/lexer.lxx"
#line 148 "gecode/flatzinc/lexer.lxx"
{ return FZ_STRING; }
YY_BREAK
case 45:
YY_RULE_SETUP
#line 149 "../gecode/flatzinc/lexer.lxx"
#line 149 "gecode/flatzinc/lexer.lxx"
{ return FZ_TEST; }
YY_BREAK
case 46:
YY_RULE_SETUP
#line 150 "../gecode/flatzinc/lexer.lxx"
#line 150 "gecode/flatzinc/lexer.lxx"
{ return FZ_THEN; }
YY_BREAK
case 47:
YY_RULE_SETUP
#line 151 "../gecode/flatzinc/lexer.lxx"
#line 151 "gecode/flatzinc/lexer.lxx"
{ return FZ_TUPLE; }
YY_BREAK
case 48:
YY_RULE_SETUP
#line 152 "../gecode/flatzinc/lexer.lxx"
#line 152 "gecode/flatzinc/lexer.lxx"
{ return FZ_TYPE; }
YY_BREAK
case 49:
YY_RULE_SETUP
#line 153 "../gecode/flatzinc/lexer.lxx"
#line 153 "gecode/flatzinc/lexer.lxx"
{ yylval->bValue = true; return FZ_VAR; }
YY_BREAK
case 50:
YY_RULE_SETUP
#line 154 "../gecode/flatzinc/lexer.lxx"
#line 154 "gecode/flatzinc/lexer.lxx"
{ return FZ_VARIANT_RECORD; }
YY_BREAK
case 51:
YY_RULE_SETUP
#line 155 "../gecode/flatzinc/lexer.lxx"
#line 155 "gecode/flatzinc/lexer.lxx"
{ return FZ_WHERE; }
YY_BREAK
case 52:
YY_RULE_SETUP
#line 156 "../gecode/flatzinc/lexer.lxx"
#line 156 "gecode/flatzinc/lexer.lxx"
{ yylval->sValue = strdup(yytext); return FZ_ID; }
YY_BREAK
case 53:
YY_RULE_SETUP
#line 157 "../gecode/flatzinc/lexer.lxx"
#line 157 "gecode/flatzinc/lexer.lxx"
{ yylval->sValue = strdup(yytext); return FZ_U_ID; }
YY_BREAK
case 54:
YY_RULE_SETUP
#line 158 "../gecode/flatzinc/lexer.lxx"
#line 158 "gecode/flatzinc/lexer.lxx"
{
yylval->sValue = strdup(yytext+1);
yylval->sValue[strlen(yytext)-2] = 0;
@ -1314,12 +1314,12 @@ YY_RULE_SETUP
YY_BREAK
case 55:
YY_RULE_SETUP
#line 162 "../gecode/flatzinc/lexer.lxx"
#line 162 "gecode/flatzinc/lexer.lxx"
{ yyerror("Unknown character"); }
YY_BREAK
case 56:
YY_RULE_SETUP
#line 163 "../gecode/flatzinc/lexer.lxx"
#line 163 "gecode/flatzinc/lexer.lxx"
ECHO;
YY_BREAK
#line 1325 "gecode/flatzinc/lexer.yy.cpp"
@ -2514,7 +2514,7 @@ void yyfree (void * ptr , yyscan_t yyscanner)
#define YYTABLES_NAME "yytables"
#line 163 "../gecode/flatzinc/lexer.lxx"
#line 163 "gecode/flatzinc/lexer.lxx"
int yy_input_proc(char* buf, int size, yyscan_t yyscanner) {
Gecode::FlatZinc::ParserState* parm =

View File

@ -213,6 +213,7 @@ namespace Gecode { namespace FlatZinc {
std::vector<ConExpr*> domainConstraints;
int status_idx = -1;
int complete_idx = -1;
std::vector<std::array<int, 3>> int_uniform;
std::vector<std::array<int, 2>> int_sol;
std::vector<std::array<int, 2>> int_lastval;

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* A Bison parser, made by GNU Bison 3.7.2. */
/* A Bison parser, made by GNU Bison 3.7.6. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software: you can redistribute it and/or modify
@ -16,7 +16,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@ -107,7 +107,7 @@ extern int yydebug;
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
#line 502 "../gecode/flatzinc/parser.yxx"
#line 509 "gecode/flatzinc/parser.yxx"
int iValue; char* sValue; bool bValue; double dValue;
std::vector<int>* setValue;
Gecode::FlatZinc::AST::SetLit* setLit;

View File

@ -40,6 +40,7 @@
#include <gecode/flatzinc.hh>
#include <gecode/flatzinc/parser.hh>
#include <gecode/flatzinc/lastval.hh>
#include <gecode/flatzinc/complete.hh>
#include <iostream>
#include <fstream>
@ -321,6 +322,12 @@ void initfg(ParserState* pp) {
pp->fg->restart_status = IntVarArray(*(pp->fg), 1);
pp->fg->restart_status[0] = pp->fg->iv[pp->status_idx];
}
if (pp->complete_idx >= 0) {
pp->fg->restart_complete = BoolVarArray(*(pp->fg), 1);
pp->fg->restart_complete[0] = pp->fg->bv[pp->complete_idx];
pp->fg->complete_marker = std::make_shared<bool>(false);
Complete::post(*(pp->fg), pp->fg->restart_complete[0], pp->fg->complete_marker);
}
if (!(pp->int_uniform.empty())) {
pp->fg->int_uniform_var = IntVarArray(*(pp->fg), pp->int_uniform.size());
pp->fg->int_uniform_lb = new int[pp->int_uniform.size()];
@ -1463,6 +1470,8 @@ constraint_item :
std::string cid($2);
if (cid=="status" && $4->a[0]->isIntVar()) {
pp->status_idx = $4->a[0]->getIntVar();
} else if (cid=="complete_reif" && $4->a[0]->isBoolVar()) {
pp->complete_idx = $4->a[0]->getBoolVar();
} else if (cid=="int_lastval" && $4->a[0]->isIntVar() && $4->a[1]->isIntVar()) {
int base0 = getBaseIntVar(pp,$4->a[0]->getIntVar());
int base1 = getBaseIntVar(pp,$4->a[1]->getIntVar());

View File

@ -1621,6 +1621,19 @@ namespace Gecode {
/// Information is provided by a portfolio-based engine
PORTFOLIO
};
/// Reason for restarting
enum RReason {
/// No reason - used for PORTFOLIO
RR_NO,
/// Restarting after initialisation
RR_INIT,
/// Restarting after a solution is found
RR_SOL,
/// Restarting after exhausting search space
RR_CMPL,
/// Restarting after reaching restart limit
RR_LIM
};
protected:
/// Type of information
const Type t;
@ -1628,6 +1641,8 @@ namespace Gecode {
//@{
/// Number of restarts
const unsigned long int r;
/// Reason for restarting
const RReason rr;
/// Number of solutions since last restart
const unsigned long long int s;
/// Number of failures since last restart
@ -1647,6 +1662,7 @@ namespace Gecode {
//@{
/// Constructor for restart-based engine
MetaInfo(unsigned long int r,
RReason rr,
unsigned long long int s,
unsigned long long int f,
const Space* l,
@ -1660,6 +1676,8 @@ namespace Gecode {
//@{
/// Return number of restarts
unsigned long int restart(void) const;
/// Return reason for restarting
RReason reason(void) const;
/// Return number of solutions since last restart
unsigned long long int solution(void) const;
/// Return number of failures since last restart
@ -3079,15 +3097,16 @@ namespace Gecode {
*/
forceinline
MetaInfo::MetaInfo(unsigned long int r0,
RReason rr0,
unsigned long long int s0,
unsigned long long int f0,
const Space* l0,
NoGoods& ng0)
: t(RESTART), r(r0), s(s0), f(f0), l(l0), ng(ng0), a(0) {}
: t(RESTART), r(r0), rr(rr0), s(s0), f(f0), l(l0), ng(ng0), a(0) {}
forceinline
MetaInfo::MetaInfo(unsigned int a0)
: t(PORTFOLIO), r(0), s(0), f(0), l(nullptr), ng(NoGoods::eng), a(a0) {}
: t(PORTFOLIO), r(0), rr(RR_NO), s(0), f(0), l(nullptr), ng(NoGoods::eng), a(a0) {}
forceinline MetaInfo::Type
MetaInfo::type(void) const {
@ -3098,6 +3117,10 @@ namespace Gecode {
assert(type() == RESTART);
return r;
}
forceinline MetaInfo::RReason
MetaInfo::reason(void) const {
return rr;
}
forceinline unsigned long long int
MetaInfo::solution(void) const {
assert(type() == RESTART);

View File

@ -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);
//@}
};
@ -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>

View File

@ -97,7 +97,7 @@ namespace Gecode {
} else {
Space* master = m_opt.clone ? s->clone() : s;
Space* slave = master->clone();
MetaInfo mi(0,0,0,nullptr,NoGoods::eng);
MetaInfo mi(0,MetaInfo::RR_INIT,0,0,nullptr,NoGoods::eng);
slave->slave(mi);
e = Search::Seq::rbsengine(master,e_opt.stop,
Search::build<T,E>(slave,e_opt),

View File

@ -60,7 +60,7 @@ namespace Gecode { namespace Search { namespace Seq {
NoGoods& ng = e->nogoods();
// Reset number of no-goods found
ng.ng(0);
MetaInfo mi(stop->m_stat.restart,sslr,e->statistics().fail,last,ng);
MetaInfo mi(stop->m_stat.restart,MetaInfo::RR_SOL,sslr,e->statistics().fail,last,ng);
bool r = master->master(mi);
stop->m_stat.nogood += ng.ng();
if (master->status(stop->m_stat) == SS_FAILED) {
@ -96,7 +96,7 @@ namespace Gecode { namespace Search { namespace Seq {
sslr = 0;
NoGoods& ng = e->nogoods();
ng.ng(0);
MetaInfo mi(stop->m_stat.restart,sslr,e->statistics().fail,last,ng);
MetaInfo mi(stop->m_stat.restart,e->stopped() ? MetaInfo::RR_LIM : MetaInfo::RR_CMPL,sslr,e->statistics().fail,last,ng);
(void) master->master(mi);
stop->m_stat.nogood += ng.ng();
unsigned long long int nl = ++(*co);

View File

@ -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);
}
/*
@ -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;
}
}}

View File

@ -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

View File

@ -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"]
],