initial support for 'keep'

This commit is contained in:
Denys Duchier
2011-12-03 23:31:28 +01:00
parent 696e0e91e7
commit 8aa813d342
3 changed files with 242 additions and 61 deletions

View File

@@ -41,14 +41,17 @@ namespace generic_gecode
Optimizing(): num(-1), den(-1), what(OPT_NONE), how(OPT_MAX) {}
Optimizing(Optimizing& o)
: num(o.num), den(o.den), what(o.what), how(o.how) {}
void check_ok() const
{ if (what!=OPT_NONE)
throw Exception("gecode-python","too many optimization criteria"); }
void maximize(int i)
{ what = OPT_INT; how = OPT_MAX; num = i; };
{ check_ok(); what = OPT_INT; how = OPT_MAX; num = i; };
void maximize(int i,int j)
{ what = OPT_RATIO; how = OPT_MAX; num = i; den = j; };
{ check_ok(); what = OPT_RATIO; how = OPT_MAX; num = i; den = j; };
void minimize(int i)
{ what = OPT_INT; how = OPT_MIN; num = i; };
{ check_ok(); what = OPT_INT; how = OPT_MIN; num = i; };
void minimize(int i,int j)
{ what = OPT_RATIO; how = OPT_MIN; num = i; den = j; };
{ check_ok(); what = OPT_RATIO; how = OPT_MIN; num = i; den = j; };
};
struct GenericSpace;
@@ -80,21 +83,106 @@ namespace generic_gecode
virtual GenericSpace* next(void) { return engine.next(); }
};
struct LoadingDock
{
vector<IntVar> ivars;
vector<BoolVar> bvars;
vector<SetVar> svars;
vector<int> ikeep;
vector<int> bkeep;
vector<int> skeep;
bool keeping_some() const
{
return (ikeep.size() != 0)
|| (bkeep.size() != 0)
|| (skeep.size() != 0);
}
IntVar get_ivar(int i) const { return ivars[i]; }
BoolVar get_bvar(int i) const { return bvars[i]; }
SetVar get_svar(int i) const { return svars[i]; }
int enter_ivar(const IntVar& v)
{ ivars.push_back(v); return static_cast<int>(ivars.size()-1); }
int enter_bvar(const BoolVar& v)
{ bvars.push_back(v); return static_cast<int>(bvars.size()-1); }
int enter_svar(const SetVar& v)
{ svars.push_back(v); return static_cast<int>(svars.size()-1); }
int keep_ivar(int i) { ikeep.push_back(i); return static_cast<int>(ikeep.size()-1); }
int keep_bvar(int i) { bkeep.push_back(i); return static_cast<int>(bkeep.size()-1); }
int keep_svar(int i) { skeep.push_back(i); return static_cast<int>(skeep.size()-1); }
void freeze(Space& home,
IntVarArray& iarr, BoolVarArray& barr, SetVarArray& sarr,
int& num, int& den)
{
if (keeping_some())
{
// make sure that optimization vars (if any) are kept
if (num != -1)
{
const int _num(num);
const int _den(den);
int n = static_cast<int>(ikeep.size());
bool num_found(false);
bool den_found(false);
for (;n--;)
{
const int idx(ikeep[n]);
if (idx==_num)
{ num_found=true; if (den_found) break; }
if (idx==_den)
{ den_found=true; if (num_found) break; }
}
if (!num_found)
{ ikeep.push_back(_num);
num=static_cast<int>(ikeep.size()-1); }
if (_den != -1 && !den_found)
{ ikeep.push_back(_den);
den=static_cast<int>(ikeep.size()-1); }
}
{ int n = static_cast<int>(ikeep.size());
iarr = IntVarArray(home, n);
for (;n--;) iarr[n]=ivars[ikeep[n]]; }
{ int n = static_cast<int>(bkeep.size());
barr = BoolVarArray(home, n);
for (;n--;) barr[n]=bvars[bkeep[n]]; }
{ int n = static_cast<int>(skeep.size());
sarr = SetVarArray(home, n);
for (;n--;) sarr[n]=svars[skeep[n]]; }
}
else
{
{ int n = static_cast<int>(ivars.size());
iarr = IntVarArray(home, n);
for (;n--;) iarr[n]=ivars[n]; }
{ int n = static_cast<int>(bvars.size());
barr = BoolVarArray(home, n);
for (;n--;) barr[n]=bvars[n]; }
{ int n = static_cast<int>(svars.size());
sarr = SetVarArray(home, n);
for (;n--;) sarr[n]=svars[n]; }
}
}
};
struct GenericSpace: Space
{
Optimizing optim;
IntVarArray ivars;
BoolVarArray bvars;
SetVarArray svars;
vector<IntVar>* _ivars;
vector<BoolVar>* _bvars;
vector<SetVar>* _svars;
LoadingDock* dock;
bool keeping_some; // iff only SOME of the vars are kept
Space* space() { return this; }
GenericSpace(bool share, GenericSpace& s)
: Space(share, s), optim(s.optim),
_ivars(NULL), _bvars(NULL), _svars(NULL)
: Space(share, s), optim(s.optim), dock(NULL), keeping_some(s.keeping_some)
{
ivars.update(*this, share, s.ivars);
bvars.update(*this, share, s.bvars);
@@ -104,45 +192,53 @@ namespace generic_gecode
Space* copy(bool share)
{ freeze(); return new GenericSpace(share, *this); }
GenericSpace() : _ivars(NULL), _bvars(NULL), _svars(NULL) {}
GenericSpace() : dock(new LoadingDock()), keeping_some(false) {}
~GenericSpace() { delete dock; }
// throw some C++ exception on behalf of glue code
void kaboom(const char* s)
{ throw Exception("gecode-python", s); }
int ikaboom(const char* s)
{ kaboom(s); return 0; }
// freeze the space before handing it off to a search engine
void freeze()
{
if (_ivars)
if (dock)
{
int n = _ivars->size();
ivars = IntVarArray(*this, n);
vector<IntVar>& v(*_ivars);
for (; n--;) ivars[n] = v[n];
delete _ivars;
_ivars = NULL;
}
if (_bvars)
{
int n = _bvars->size();
bvars = BoolVarArray(*this, n);
vector<BoolVar>& v(*_bvars);
for (; n--;) bvars[n] = v[n];
delete _bvars;
_bvars = NULL;
}
if (_svars)
{
int n = _svars->size();
svars = SetVarArray(*this, n);
vector<SetVar>& v(*_svars);
for (; n--;) svars[n] = v[n];
delete _svars;
_svars = NULL;
keeping_some = dock->keeping_some();
dock->freeze(*this, ivars, bvars, svars, optim.num, optim.den);
delete dock;
dock = NULL;
}
}
IntVar get_ivar(int i) const { return (_ivars) ? (*_ivars)[i] : ivars[i]; }
BoolVar get_bvar(int i) const { return (_bvars) ? (*_bvars)[i] : bvars[i]; }
SetVar get_svar(int i) const { return (_svars) ? (*_svars)[i] : svars[i]; }
IntVar get_ivar(int i) const { return (dock)?dock->get_ivar(i):ivars[i]; }
BoolVar get_bvar(int i) const { return (dock)?dock->get_bvar(i):bvars[i]; }
SetVar get_svar(int i) const { return (dock)?dock->get_svar(i):svars[i]; }
int keep_ivar(int i)
{
if (dock) return dock->keep_ivar(i);
else return ikaboom("too late to keep");
}
int keep_bvar(int i)
{
if (dock) return dock->keep_bvar(i);
else return ikaboom("too late to keep");
}
int keep_svar(int i)
{
if (dock) return dock->keep_svar(i);
else return ikaboom("too late to keep");
}
bool frozen() const { return dock==NULL; }
bool has_keepers() const { return keeping_some; }
// when frozen and has_keepers: which is just has_keepers actually
bool use_keep_index() const { return has_keepers(); }
GenericEngine* new_engine(bool restart, Search::Options& opt)
{
@@ -156,10 +252,8 @@ namespace generic_gecode
int _new_ivar(IntVar& v)
{
if (!_ivars) _ivars = new vector<IntVar>;
int i = _ivars->size();
_ivars->push_back(v);
return i;
if (dock) return dock->enter_ivar(v);
else return ikaboom("too late to create vars");
}
int new_ivar(int lo, int hi)
@@ -176,10 +270,8 @@ namespace generic_gecode
int _new_bvar(BoolVar& v)
{
if (!_bvars) _bvars = new vector<BoolVar>;
int i = _bvars->size();
_bvars->push_back(v);
return i;
if (dock) return dock->enter_bvar(v);
else return ikaboom("too late to create vars");
}
int new_bvar()
@@ -190,10 +282,8 @@ namespace generic_gecode
int _new_svar(SetVar& v)
{
if (!_svars) _svars = new vector<SetVar>;
int i = _svars->size();
_svars->push_back(v);
return i;
if (dock) return dock->enter_svar(v);
else return ikaboom("too late to create vars");
}
int new_svar(int glbMin, int glbMax, int lubMin, int lubMax,