javaconstraintsconstraint-programmingchoco

How to define a product in Choco (CSP)


I am trying to model a tennis scheduling problem, as I explain in this post. I was lucky to get an answer with the equations describing the problem which allowed me to implement it in Choco, and it looks like it's working good enough.

So what I am about to explain is about the product of the implementation of the previous post's answer.

Basically I will end up having 2 three-dimensional matrices and 1 two-dimensional one, described as follows:

// Matches schedule
// i -> players, j-> courts, k -> timeslots
// x[i][j][k] holds a value 0..1 where 0 means the player doesn't play in court_j in the timeslot_k, and 1 the opposite
IntVar[][][] x;

// Beginning of all matches
// i -> players, j-> courts, k -> timeslots
// g[i][j][k] holds a value 0..1 where 0 means the player doesn't play in court_j in the timeslot_k, and 1 the opposite
// Basically the same matrix as the previous one but it only holds the first timeslot of a match
IntVar[][][] g;

// Occupied courts
// i-> courts, j-> timeslots
// crt[i][j] holds a value 0..1 where 0 means the court_i is occupied in the timeslot_j, and 1 means the opposite
IntVar[][] crt;

With this approach the constraint that maps the schedule matrix to the game-starts matrix looks like this:

for (int p = 0; p < nPlayers; p++) {
    for (int c = 0; c < nCourts; c++) {
        for (int t = 0; t < nTimeslots - nTimeslotsPerMatch; t++) {
            if (nTimeslotsPerMatch == 1)
                solver.post(IntConstraintFactory.arithm(g[p][c][t], "=", x[p][c][t]));
            else
                solver.post(IntConstraintFactory.times(x[p][c][t], x[p][c][t + 1], g[p][c][t]));
        }               

        if (nTimeslotsPerMatch == 1)
            solver.post(IntConstraintFactory.arithm(g[p][c][nTimeslots - 1], "=", x[p][c][nTimeslots - 1]));
        else
            for (int i = 0; i < nTimeslotsPerMatch - 1; i++)
                solver.post(IntConstraintFactory.arithm(g[p][c][nTimeslots - i - 1], "=", 0));
    }
}

This uses the times constraint trick to map x[p][c][t] and x[p][c][t + 1] into g[p][c][t].

However, that definition considers each match has a fixed duration of 2 timeslots. I want to change it so that duration is variable.

But if I want to have a variable match duration I would have to map more than two values in x to define the value in g. For example, if the match duration is 3 slots, to map g[p][c][t] I need to do x[p][c][t] * x[p][c][t + 1] * x[p][c][t + 2] but I can't do that with times or in a similar fashion it's being done right now.

So my questions is, as there is a constraint in Choco called sum where you can ensure the summation of a set of values is equal to a value, is there one to define the product of this set of values? If not, how can I do this?

Basically what I achieve to do is:

g[i][j][k] = x[i][j][k] + x[i][j][k + 1] * x[i][j][k + 2] * x[i][j][k + 3] * ... * x[i][j][nTimeslotsPerMatch - 1]

Solution

  • From your code comments, x is a set of binary variables (value is either 0 or 1), so you should declare it using BoolVar (which extends IntVar).

    Multiplying binary variables gives 1 if all binaries are set to 1 or 0 otherwise. In other terms, you can use "LogicalConstraintFactory.and" or "IntConstraintFactory.minimum" constraints to get that multiplication. Look at IntConstraintFactory, you also have implication constraints that may be usefull.

    Does it help?

    Jean-Guillaume, https://www.cosling.com/