如何在Choco(CSP)中定义产品

时间:2016-03-04 16:43:31

标签: java constraints constraint-programming choco

我正试图模拟网球排程问题,正如我在post中解释的那样。我很幸运能够用描述问题的方程得到一个答案,这个方程式允许我在Choco中实现它,看起来它的工作效果还不错。

所以我要解释的是关于上一篇文章答案实施的结果。

基本上我最终会得到2个三维矩阵和1个二维矩阵,如下所示:

// 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;

使用这种方法,将计划矩阵映射到游戏开始矩阵的约束如下所示:

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));
    }
}

这会使用times约束技巧将x[p][c][t]x[p][c][t + 1]映射到g[p][c][t]

但是,该定义认为每个匹配的固定持续时间为2个时隙。我想改变它,以便持续时间可变。

但是如果我想要一个可变的匹配持续时间,我必须在x中映射两个以上的值来定义g中的值。例如,如果匹配持续时间为3个广告位,则map g[p][c][t]我需要x[p][c][t] * x[p][c][t + 1] * x[p][c][t + 2],但我无法使用times或以类似​​的方式执行此操作。

所以我的问题是,因为Choco中有一个名为sum的约束,你可以确保一组值的总和等于一个值,是否有一个来定义产品

基本上我要做的是:

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]

1 个答案:

答案 0 :(得分:1)

从代码注释中,x是一组二进制变量(值为0或1),因此您应该使用BoolVar(扩展IntVar)声明它。

如果所有二进制文件都设置为1,则乘以二进制变量得1,否则为0。换句话说,您可以使用“LogicalConstraintFactory.and”或“IntConstraintFactory.minimum”约束来获得该乘法。看看IntConstraintFactory,你也有可能有用的蕴涵约束。

有帮助吗?

让 - 纪尧姆 https://www.cosling.com/