5
$\begingroup$

If I have an IntVar s[j] stored in a vector s, is it possible to iterate for (a period of time) t and create a BoolVar b such that b[t] is true if and only if s[j]==t? I tried setting some restrictions:

    for (int j = 0; j < nbTasks; ++j)
    {
        for (int t = 0; t < tmax; ++t)
        {
            const IntVar expr = cp_model.NewIntVar(Domain(-1000000000,100000000000));
            const IntVar actual_t = cp_model.NewConstant(t).WithName("actual_t");
            const BoolVar b = cp_model.NewBoolVar().WithName("b");
            const IntVar value = cp_model.NewConstant(w[j][t]);

            obj_final.push_back(expr);
            actuals[j].push_back(actual_t);
            expressions[j].push_back(expr);
            values[j].push_back(value);

            cp_model.AddEquality(b, starts[j]==actual_t);
            cp_model.AddProductEquality(expr, {value, b});
        }
    }  

I created the BoolVar b and then set an equality to the bool value of s[j]==t, then I used the constraint expr == value*b and added the expression to the vector obj_final, and finally set the objective: cp_model.Maximize(LinearExpr::Sum(obj_final)); The problem is that my solution is optimal but the objective is zero, so I guess b is always false.

My goal is to assign a value to an expression if and only if s[j]==t. Enforce constraints isn't what i need because the other expressions must be zero. I'll be thankful for any help.

$\endgroup$
  • 2
    $\begingroup$ You should read this: github.com/google/or-tools/blob/stable/ortools/sat/doc/… $\endgroup$ – Stradivari Jan 31 at 14:41
  • $\begingroup$ Thanks for your answer! The problem is that OnlyEnforceIf takes only BoolVar as argument, and the condition i need (s[j]==t) is just bool , i tried but the function don't match the argument. $\endgroup$ – Diego R. Troncoso Jan 31 at 15:06
  • $\begingroup$ I might be wrong, but isn't what you want: cp_model.AddEquality(s[j], t).OnlyEnforceIf(b) and cp_model.AddEquality(s[j], 0).OnlyEnforceIf(Not(b)) ? Which is more or less the same as the example linked $\endgroup$ – Stradivari Jan 31 at 15:08
  • $\begingroup$ Nope, i want to cp_model.AddEquality(expr, value).OnlyEnforceIf(s[j]==t) but OnlyEnforceIf takes only BoolVar arguments and not bool (as s[j]==t). So i want to create a BoolVar that is true if s[j]==t, else false. $\endgroup$ – Diego R. Troncoso Jan 31 at 15:24
5
$\begingroup$

To create an intermediate boolean that is true iff s[j] == t you just have to create 2 constraints:

cp_model.AddEquality(s[j], t).OnlyEnforceIf(b);
cp_model.AddNotEqual(s[j], t).OnlyEnforceIf(Not(b));

The problem with this line:

cp_model.AddEquality(b, starts[j]==actual_t);

is that starts[j]==actual_t "always" evaluates to false.

To learn more about channeling, see:

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks! its solving. I'm modelling an RCPSP with discount rate (precomputed and rounded) do you think that it is the best way to model it? $\endgroup$ – Diego R. Troncoso Jan 31 at 18:01
  • $\begingroup$ I am no expert in that, sorry. It might be better to ask a new question explaining your model so people can comment on it $\endgroup$ – Stradivari Jan 31 at 18:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.