00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stddef.h>
00015 #include <string.h>
00016 #include "base/hash.h"
00017 #include <string>
00018 #include <vector>
00019
00020 #include "base/integral_types.h"
00021 #include "base/logging.h"
00022 #include "base/macros.h"
00023 #include "base/scoped_ptr.h"
00024 #include "base/stl_util.h"
00025 #include "constraint_solver/constraint_solver.h"
00026 #include "constraint_solver/constraint_solveri.h"
00027
00028 namespace operations_research {
00029 namespace {
00030 class CollectVariablesVisitor : public ModelParser {
00031 public:
00032 CollectVariablesVisitor(std::vector<IntVar*>* const primary_integer_variables,
00033 std::vector<IntVar*>* const secondary_integer_variables,
00034 std::vector<SequenceVar*>* const sequence_variables,
00035 std::vector<IntervalVar*>* const interval_variables)
00036 : primaries_(primary_integer_variables),
00037 secondaries_(secondary_integer_variables),
00038 sequences_(sequence_variables),
00039 intervals_(interval_variables) {}
00040
00041 virtual ~CollectVariablesVisitor() {}
00042
00043
00044 virtual void EndVisitModel(const string& solver_name) {
00045 PopArgumentHolder();
00046 primaries_->assign(primary_set_.begin(), primary_set_.end());
00047 secondaries_->assign(secondary_set_.begin(), secondary_set_.end());
00048 intervals_->assign(interval_set_.begin(), interval_set_.end());
00049 sequences_->assign(sequence_set_.begin(), sequence_set_.end());
00050 }
00051
00052 virtual void EndVisitConstraint(const string& type_name,
00053 const Constraint* const constraint) {
00054 if (type_name.compare(ModelVisitor::kLinkExprVar) == 0 ||
00055 type_name.compare(ModelVisitor::kSumEqual) == 0 ||
00056 type_name.compare(ModelVisitor::kElementEqual) == 0 ||
00057 type_name.compare(ModelVisitor::kScalProdEqual) == 0 ||
00058 type_name.compare(ModelVisitor::kIsEqual) == 0 ||
00059 type_name.compare(ModelVisitor::kIsDifferent) == 0 ||
00060 type_name.compare(ModelVisitor::kIsGreaterOrEqual) == 0 ||
00061 type_name.compare(ModelVisitor::kIsLessOrEqual) == 0) {
00062 IntExpr* const target_expr =
00063 const_cast<IntExpr*>(
00064 Top()->FindIntegerExpressionArgumentOrDie(
00065 ModelVisitor::kTargetArgument));
00066 IntVar* const target_var = target_expr->Var();
00067 IgnoreIntegerVariable(target_var);
00068 } else if (type_name.compare(ModelVisitor::kCountEqual) == 0 &&
00069 Top()->HasIntegerExpressionArgument(
00070 ModelVisitor::kCountArgument)) {
00071 IntExpr* const count_expr =
00072 const_cast<IntExpr*>(
00073 Top()->FindIntegerExpressionArgumentOrDie(
00074 ModelVisitor::kCountArgument));
00075 IntVar* const count_var = count_expr->Var();
00076 IgnoreIntegerVariable(count_var);
00077 } else if (type_name.compare(ModelVisitor::kAllowedAssignments) == 0) {
00078 const IntTupleSet& matrix =
00079 Top()->FindIntegerMatrixArgumentOrDie(ModelVisitor::kTuplesArgument);
00080 std::vector<hash_set<int> > counters(matrix.Arity());
00081 for (int i = 0; i < matrix.NumTuples(); ++i) {
00082 for (int j = 0; j < matrix.Arity(); ++j) {
00083 counters[j].insert(matrix.Value(i, j));
00084 }
00085 }
00086 for (int j = 0; j < matrix.Arity(); ++j) {
00087 if (counters[j].size() == matrix.NumTuples()) {
00088 const std::vector<const IntVar*>& vars =
00089 Top()->FindIntegerVariableArrayArgumentOrDie(
00090 ModelVisitor::kVarsArgument);
00091 for (int k = 0; k < matrix.Arity(); ++k) {
00092 if (j != k) {
00093 IgnoreIntegerVariable(const_cast<IntVar*>(vars[k]));
00094 }
00095 }
00096 break;
00097 }
00098 }
00099 } else if (type_name.compare(ModelVisitor::kNoCycle) == 0) {
00100 const std::vector<const IntVar*>& vars =
00101 Top()->FindIntegerVariableArrayArgumentOrDie(
00102 ModelVisitor::kActiveArgument);
00103 for (int i = 0; i < vars.size(); ++i) {
00104 IgnoreIntegerVariable(const_cast<IntVar*>(vars[i]));
00105 }
00106 } else if (type_name.compare(ModelVisitor::kPathCumul) == 0) {
00107 const std::vector<const IntVar*>& vars =
00108 Top()->FindIntegerVariableArrayArgumentOrDie(
00109 ModelVisitor::kActiveArgument);
00110 for (int i = 0; i < vars.size(); ++i) {
00111 IgnoreIntegerVariable(const_cast<IntVar*>(vars[i]));
00112 }
00113 } else if (type_name.compare(ModelVisitor::kDistribute) == 0) {
00114 const std::vector<const IntVar*>& vars =
00115 Top()->FindIntegerVariableArrayArgumentOrDie(
00116 ModelVisitor::kCardsArgument);
00117 for (int i = 0; i < vars.size(); ++i) {
00118 IgnoreIntegerVariable(const_cast<IntVar*>(vars[i]));
00119 }
00120 }
00121 PopArgumentHolder();
00122 }
00123
00124 virtual void VisitIntegerVariable(const IntVar* const variable,
00125 const IntExpr* const delegate) {
00126 IntVar* const var = const_cast<IntVar*>(variable);
00127 if (delegate != NULL) {
00128 delegate->Accept(this);
00129 IgnoreIntegerVariable(const_cast<IntVar*>(variable));
00130 } else {
00131 if (!ContainsKey(primary_set_, var) &&
00132 !ContainsKey(secondary_set_, var) &&
00133 !ContainsKey(ignored_set_, var) &&
00134 !var->Bound()) {
00135 primary_set_.insert(var);
00136 }
00137 }
00138 }
00139
00140 virtual void VisitIntegerVariable(const IntVar* const variable,
00141 const string& operation,
00142 int64 value,
00143 const IntVar* const delegate) {
00144 IgnoreIntegerVariable(const_cast<IntVar*>(variable));
00145 delegate->Accept(this);
00146 }
00147
00148 virtual void VisitIntervalVariable(const IntervalVar* const variable,
00149 const string& operation,
00150 const IntervalVar* const delegate) {
00151 if (delegate != NULL) {
00152 delegate->Accept(this);
00153 } else {
00154 DeclareInterval(const_cast<IntervalVar*>(variable));
00155 }
00156 }
00157
00158 virtual void VisitIntervalVariable(const IntervalVar* const variable,
00159 const string& operation,
00160 const IntervalVar* const * delegates,
00161 int size) {
00162 for (int i = 0; i < size; ++i) {
00163 IntervalVar* const var = const_cast<IntervalVar*>(delegates[i]);
00164 DeclareInterval(var);
00165 delegates[i]->Accept(this);
00166 }
00167 }
00168
00169 virtual void VisitSequenceVariable(const SequenceVar* const variable) {
00170 SequenceVar* const var = const_cast<SequenceVar*>(variable);
00171 sequence_set_.insert(var);
00172 for (int i = 0; i < var->size(); ++i) {
00173 var->Interval(i)->Accept(this);
00174 DeclareInterval(var->Interval(i));
00175 }
00176 }
00177
00178 private:
00179 void IgnoreIntegerVariable(IntVar* const var) {
00180 primary_set_.erase(var);
00181 secondary_set_.erase(var);
00182 ignored_set_.insert(var);
00183 }
00184
00185 void DeclareInterval(IntervalVar* const var) {
00186 interval_set_.insert(var);
00187 }
00188
00189 std::vector<IntVar*>* const primaries_;
00190 std::vector<IntVar*>* const secondaries_;
00191 std::vector<SequenceVar*>* const sequences_;
00192 std::vector<IntervalVar*>* const intervals_;
00193 hash_set<IntVar*> primary_set_;
00194 hash_set<IntVar*> secondary_set_;
00195 hash_set<IntVar*> ignored_set_;
00196 hash_set<SequenceVar*> sequence_set_;
00197 hash_set<IntervalVar*> interval_set_;
00198 };
00199 }
00200
00201 bool Solver::CollectDecisionVariables(
00202 std::vector<IntVar*>* const primary_integer_variables,
00203 std::vector<IntVar*>* const secondary_integer_variables,
00204 std::vector<SequenceVar*>* const sequence_variables,
00205 std::vector<IntervalVar*>* const interval_variables) {
00206 CollectVariablesVisitor collector(primary_integer_variables,
00207 secondary_integer_variables,
00208 sequence_variables,
00209 interval_variables);
00210 Accept(&collector);
00211 return true;
00212 }
00213 }