class AllDifferentExcept : public Constraint {
public:
AllDifferentExcept(Solver* const s, std::vector<IntVar*> vars, int64 escape_value)
: Constraint(s), vars_(vars), escape_value_(escape_value) {}
virtual ~AllDifferentExcept() {}
virtual void Post() {
for (int i = 0; i < vars_.size(); ++i) {
IntVar* const var = vars_[i];
Demon* const d = MakeConstraintDemon1(
solver(), this, &AllDifferentExcept::Propagate, "Propagate", i);
var->WhenBound(d);
}
}
virtual void InitialPropagate() {
for (int i = 0; i < vars_.size(); ++i) {
if (vars_[i]->Bound()) {
Propagate(i);
}
}
}
void Propagate(int index) {
const int64 val = vars_[index]->Value();
if (val != escape_value_) {
for (int j = 0; j < vars_.size(); ++j) {
if (index != j) {
vars_[j]->RemoveValue(val);
}
}
}
}
virtual std::string DebugString() const {
return StringPrintf("AllDifferentExcept([%s], %" GG_LL_FORMAT "d",
JoinDebugStringPtr(vars_, ", ").c_str(), escape_value_);
}
virtual void Accept(ModelVisitor* const visitor) const {
visitor->BeginVisitConstraint(ModelVisitor::kAllDifferent, this);
visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
vars_);
visitor->VisitIntegerArgument(ModelVisitor::kValueArgument, escape_value_);
visitor->EndVisitConstraint(ModelVisitor::kAllDifferent, this);
}
private:
std::vector<IntVar*> vars_;
const int64 escape_value_;
};
basic_constraint_example