more work on set variables, no constraints

This commit is contained in:
lperron@google.com
2012-06-17 21:15:38 +00:00
parent d3dba93a66
commit 1deac8352b
7 changed files with 110 additions and 51 deletions

View File

@@ -0,0 +1,3 @@
var set of 1..5: s :: output_var = {1, 3};
var 3..3: val :: output_var = 3;
solve satisfy;

View File

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

View File

@@ -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 += "])";

View File

@@ -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()) {

View File

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

View File

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

View File

@@ -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_;
};