more work on set variables, no constraints
This commit is contained in:
3
examples/flatzinc/in_set.fzn
Normal file
3
examples/flatzinc/in_set.fzn
Normal file
@@ -0,0 +1,3 @@
|
||||
var set of 1..5: s :: output_var = {1, 3};
|
||||
var 3..3: val :: output_var = 3;
|
||||
solve satisfy;
|
||||
@@ -4210,6 +4210,30 @@ class SequenceVar : public PropagationBaseObject {
|
||||
hash_set<int> last_set_;
|
||||
};
|
||||
|
||||
// ----- Class Set Var -----
|
||||
|
||||
class SetVar : public PropagationBaseObject {
|
||||
public:
|
||||
SetVar(Solver* const s, int64 min_value, int64 max_value);
|
||||
SetVar(Solver* const s, const std::vector<int64>& values);
|
||||
SetVar(Solver* const s, const std::vector<int>& values);
|
||||
virtual ~SetVar();
|
||||
|
||||
IntVar* Var(int64 value) const;
|
||||
IntVar* CardVar() const;
|
||||
|
||||
virtual string DebugString() const;
|
||||
|
||||
int64 SetMin() const;
|
||||
int64 SetMax() const;
|
||||
|
||||
private:
|
||||
const int64 min_value_;
|
||||
const int64 max_value_;
|
||||
std::vector<IntVar*> elements_;
|
||||
IntVar* card_var_;
|
||||
};
|
||||
|
||||
// --------- Assignments ----------------------------
|
||||
|
||||
// ---------- Assignment Elements ----------
|
||||
|
||||
@@ -31,28 +31,6 @@
|
||||
#include "util/const_int_array.h"
|
||||
|
||||
namespace operations_research {
|
||||
class SetVar : public PropagationBaseObject {
|
||||
public:
|
||||
SetVar(Solver* const s, int64 min_value, int64 max_value);
|
||||
SetVar(Solver* const s, const std::vector<int64>& values);
|
||||
SetVar(Solver* const s, const std::vector<int>& values);
|
||||
virtual ~SetVar();
|
||||
|
||||
IntVar* Var(int64 value) const;
|
||||
IntVar* CardVar() const;
|
||||
|
||||
virtual string DebugString() const;
|
||||
|
||||
int64 SetMin() const;
|
||||
int64 SetMax() const;
|
||||
|
||||
private:
|
||||
const int64 min_value_;
|
||||
const int64 max_value_;
|
||||
std::vector<IntVar*> elements_;
|
||||
IntVar* card_var_;
|
||||
};
|
||||
|
||||
namespace {
|
||||
template <class T> int64 MinValue(const std::vector<T>& values) {
|
||||
int64 result = kint64max;
|
||||
@@ -146,6 +124,9 @@ string SetVar::DebugString() const {
|
||||
} else {
|
||||
result += StringPrintf("?%" GG_LL_FORMAT "d", i + min_value_);
|
||||
}
|
||||
if (i != elements_.size() - 1) {
|
||||
result += " ";
|
||||
}
|
||||
}
|
||||
}
|
||||
result += "])";
|
||||
|
||||
@@ -61,6 +61,7 @@ void FlatZincModel::Init(int intVars, int boolVars, int setVars) {
|
||||
bool_var_count = 0;
|
||||
boolean_variables_.resize(boolVars);
|
||||
set_var_count = 0;
|
||||
set_variables_.resize(setVars);
|
||||
}
|
||||
|
||||
void FlatZincModel::NewIntVar(const std::string& name, IntVarSpec* const vs) {
|
||||
@@ -117,15 +118,20 @@ void FlatZincModel::SkipBoolVar() {
|
||||
boolean_variables_[bool_var_count++] = NULL;
|
||||
}
|
||||
|
||||
// void FlatZincModel::newSetVar(SetVarSpec* vs) {
|
||||
// if (vs->alias) {
|
||||
// sv[set_var_count++] = sv[vs->i];
|
||||
// } else {
|
||||
// LOG(FATAL) << "SetVar not supported";
|
||||
// sv[set_var_count++] = SetVar();
|
||||
// }
|
||||
// sv_introduced[set_var_count-1] = vs->introduced;
|
||||
// }
|
||||
void FlatZincModel::NewSetVar(const std::string& name, SetVarSpec* vs) {
|
||||
if (vs->alias) {
|
||||
set_variables_[set_var_count++] = set_variables_[vs->i];
|
||||
} else {
|
||||
AST::SetLit* const domain = vs->domain_.value();
|
||||
if (domain->interval) {
|
||||
set_variables_[set_var_count++] =
|
||||
solver_.RevAlloc(new SetVar(&solver_, domain->min, domain->max));
|
||||
} else {
|
||||
set_variables_[set_var_count++] =
|
||||
solver_.RevAlloc(new SetVar(&solver_, domain->s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FlattenAnnotations(AST::Array* const annotations,
|
||||
std::vector<AST::Node*>& out) {
|
||||
@@ -241,7 +247,7 @@ void FlatZincModel::CreateDecisionBuilders(bool ignore_unknown,
|
||||
}
|
||||
} else {
|
||||
builders_.push_back(solver_.MakePhase(active_variables_,
|
||||
Solver::CHOOSE_MIN_SIZE_LOWEST_MIN,
|
||||
Solver::CHOOSE_FIRST_UNBOUND,
|
||||
Solver::ASSIGN_MIN_VALUE));
|
||||
VLOG(1) << "Decision builder = " << builders_.back()->DebugString();
|
||||
builders_.push_back(solver_.MakePhase(introduced_variables_,
|
||||
@@ -430,7 +436,8 @@ string FlatZincModel::DebugString(AST::Node* const ai) const {
|
||||
IntVar* const var = boolean_variables_[ai->getBoolVar()];
|
||||
output += var->Value() ? "true" : "false";
|
||||
} else if (ai->isSetVar()) {
|
||||
LOG(FATAL) << "Set variables not implemented";
|
||||
SetVar* const var = set_variables_[ai->getSetVar()];
|
||||
output += var->DebugString();
|
||||
} else if (ai->isBool()) {
|
||||
output += (ai->getBool() ? "true" : "false");
|
||||
} else if (ai->isSet()) {
|
||||
|
||||
@@ -56,8 +56,6 @@
|
||||
*/
|
||||
|
||||
namespace operations_research {
|
||||
class SetVar {};
|
||||
|
||||
/**
|
||||
* \brief A space that can be initialized with a %FlatZinc model
|
||||
*
|
||||
@@ -81,16 +79,17 @@ class FlatZincModel {
|
||||
|
||||
void InitOutput(AST::Array* const output);
|
||||
|
||||
/// Create new integer variable from specification
|
||||
/// Creates a new integer variable from specification.
|
||||
void NewIntVar(const std::string& name, IntVarSpec* const vs);
|
||||
// Skips the creation of the variable.
|
||||
void SkipIntVar();
|
||||
/// Create new Boolean variable from specification
|
||||
/// Creates a new boolean variable from specification.
|
||||
int IntVarCount() const { return integer_variables_.size(); }
|
||||
void NewBoolVar(const std::string& name, BoolVarSpec* const vs);
|
||||
// Skips the creation of the variable.
|
||||
void SkipBoolVar();
|
||||
|
||||
// Creates a new set variable from specification.
|
||||
void NewSetVar(const std::string& name, SetVarSpec* const vs);
|
||||
|
||||
IntVar* GetIntVar(AST::Node* const node);
|
||||
|
||||
@@ -110,6 +109,14 @@ class FlatZincModel {
|
||||
boolean_variables_[index] = var;
|
||||
}
|
||||
|
||||
SetVar* SetVariable(int index) const {
|
||||
return set_variables_[index];
|
||||
}
|
||||
|
||||
void SetSetVariable(int index, SetVar* const var) {
|
||||
set_variables_[index] = var;
|
||||
}
|
||||
|
||||
/// Post a constraint specified by \a ce
|
||||
void PostConstraint(CtSpec* const spec);
|
||||
|
||||
@@ -170,7 +177,8 @@ class FlatZincModel {
|
||||
/// The Boolean variables
|
||||
std::vector<IntVar*> boolean_variables_;
|
||||
/// The set variables
|
||||
std::vector<SetVar> sv;
|
||||
std::vector<SetVar*> set_variables_;
|
||||
// Useful for search.
|
||||
std::vector<IntVar*> active_variables_;
|
||||
std::vector<IntVar*> introduced_variables_;
|
||||
bool parsed_ok_;
|
||||
|
||||
@@ -349,11 +349,24 @@ void ParserState::CreateModel() {
|
||||
}
|
||||
}
|
||||
|
||||
// for (unsigned int i=0; i<set_variables_.size(); i++) {
|
||||
// if (!hadError) {
|
||||
// model->newSetVar(static_cast<Set_Variables_pec*>(set_variables_[i]));
|
||||
// }
|
||||
// }
|
||||
array_index = 0;
|
||||
for (unsigned int i = 0; i < set_variables_.size(); i++) {
|
||||
if (!hadError) {
|
||||
const std::string& raw_name = set_variables_[i]->Name();
|
||||
std::string name;
|
||||
if (raw_name[0] == '[') {
|
||||
name = StringPrintf("%s[%d]", raw_name.c_str() + 1, ++array_index);
|
||||
} else {
|
||||
if (array_index == 0) {
|
||||
name = raw_name;
|
||||
} else {
|
||||
name = StringPrintf("%s[%d]", raw_name.c_str(), array_index + 1);
|
||||
array_index = 0;
|
||||
}
|
||||
}
|
||||
model_->NewSetVar(name, set_variables_[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < constraints_.size(); i++) {
|
||||
if (!hadError) {
|
||||
|
||||
@@ -282,35 +282,58 @@ class FloatVarSpec : public VarSpec {
|
||||
/// Specification for set variables
|
||||
class SetVarSpec : public VarSpec {
|
||||
public:
|
||||
Option<AST::SetLit*> upperBound;
|
||||
Option<AST::SetLit*> domain_;
|
||||
SetVarSpec(const string& name, bool introduced)
|
||||
: VarSpec(name, introduced, false, false),
|
||||
own_domain_(false) {
|
||||
upperBound = Option<AST::SetLit*>::none();
|
||||
domain_ = Option<AST::SetLit*>::none();
|
||||
}
|
||||
SetVarSpec(const string& name,
|
||||
const Option<AST::SetLit*>& v,
|
||||
bool introduced, bool own_domain)
|
||||
: VarSpec(name, introduced, false, false),
|
||||
own_domain_(own_domain) {
|
||||
upperBound = v;
|
||||
domain_ = v;
|
||||
|
||||
}
|
||||
SetVarSpec(const string& name, AST::SetLit* v, bool introduced)
|
||||
: VarSpec(name, introduced, false, true),
|
||||
own_domain_(false) {
|
||||
upperBound = Option<AST::SetLit*>::some(v);
|
||||
domain_ = Option<AST::SetLit*>::some(v);
|
||||
}
|
||||
SetVarSpec(const string& name, const Alias& eq, bool introduced)
|
||||
: VarSpec(name, introduced, true, false),
|
||||
own_domain_(false) {
|
||||
i = eq.v;
|
||||
}
|
||||
~SetVarSpec(void) {
|
||||
if (!alias && upperBound.defined() && own_domain_)
|
||||
delete upperBound.value();
|
||||
virtual ~SetVarSpec(void) {
|
||||
if (!alias && domain_.defined() && own_domain_)
|
||||
delete domain_.value();
|
||||
}
|
||||
|
||||
virtual string DebugString() const {
|
||||
if (alias) {
|
||||
return StringPrintf(
|
||||
"SetVarSpec(name = %s, alias to = %d)",
|
||||
name.c_str(),
|
||||
i);
|
||||
} else if (assigned) {
|
||||
return StringPrintf(
|
||||
"SetVarSpec(name = %s, assigned to = %d)",
|
||||
name.c_str(),
|
||||
i);
|
||||
} else {
|
||||
return StringPrintf(
|
||||
"SetVarSpec(name = %s, id = %d, domain = %s)",
|
||||
name.c_str(),
|
||||
i,
|
||||
(domain_.defined() ?
|
||||
domain_.value()->DebugString().c_str() :
|
||||
"no domain"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
const bool own_domain_;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user