Как определить продукт в Choco (CSP)
Я пытаюсь смоделировать проблему планирования игры в теннис, как я объясню в этом посте. Мне повезло получить ответ с уравнениями, описывающими проблему, которые позволили мне реализовать ее в Choco, и похоже, что она работает достаточно хорошо.
Так что я собираюсь объяснить, о продукте реализации ответа предыдущего поста.
В основном я получу две трехмерные матрицы и одну двумерную, описанную ниже:
// 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
или подобным образом это делается прямо сейчас.
Поэтому мои вопросы таковы, так как в Чоко есть ограничение, которое называется 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 ответ
Из ваших комментариев к коду x - это набор двоичных переменных (значение равно 0 или 1), поэтому вы должны объявить его с помощью BoolVar (который расширяет IntVar).
Умножение двоичных переменных дает 1, если все двоичные файлы установлены в 1 или 0 в противном случае. Другими словами, вы можете использовать ограничения "LogicalConstraintFactory.and" или "IntConstraintFactory.minimum", чтобы получить это умножение. Посмотрите на IntConstraintFactory, у вас также есть ограничения импликации, которые могут быть полезны.
Это помогает?
Жан-Гийом, https://www.cosling.com/