Я работал с OR-Tools над созданием расписания баскетбольного турнира.
Мне не удается найти идеальный способ выразить определенные оптимизации/ограничения, которые я хочу наложить. на модели.
Оба исходят из довольно простого мыслительного процесса: я хочу сделать так, чтобы связанные игры (с одинаковыми игровыми идентификаторами пула или одинаковыми идентификаторами команды) не могли возникнуть. подряд.
Мои основные вопросы:
Как мне ввести ограничение, которое означает, что последовательные игры для команды должны проходить с интервалом в 120 минут в определенный день. Например, команда y должна сыграть в 13:00. Затем, если в этот день у них будет еще одна игра, она должна состояться в 11:00 или 15:00.
Как я могу уменьшить количество переменных/времени, добавляемых в решатель, при попытке минимизировать штрафы? для оптимизации. Я попытался сузить его, чтобы иметь как можно меньше связей, но он все равно кажется невероятно большим.
Мои переменные выглядят следующим образом:
for g in unscheduled_games:
for slot in game_slots:
var_name = f"game_{g.Id}_slot_{slot.Id}"
game_vars[(g.Id, slot.Id)] = model.NewBoolVar(var_name)
А моя оптимизация выглядит так:
def get_associated_optimization(model, game_vars, unscheduled_games, game_slots):
penalty_vars = []
minutes since a fixed start:
slot_time_map = {}
base_time = min(s.DateTime for s in game_slots)
for slot in game_slots:
delta = slot.DateTime - base_time
slot_time_map[slot.Id] = int(delta.total_seconds() // 60)
conflict_graph = {}
all_games = unscheduled_games[:] # so we can index them
for i in range(len(all_games)):
for j in range(i+1, len(all_games)):
gameA = all_games
gameB = all_games[j]
order = deduce_relationship(gameA, gameB)
if order is not None:
conflict_graph[(gameA.Id, gameB.Id)] = order
for (gameA_id, gameB_id), rel in conflict_graph.items():
for slotA in game_slots:
gameA_var = game_vars.get((gameA_id, slotA.Id))
if gameA_var is None:
continue
for slotB in game_slots:
gameB_var = game_vars.get((gameB_id, slotB.Id))
if gameB_var is None:
continue
if slotA.Date != slotB.Date:
continue
timeA = slot_time_map[slotA.Id]
timeB = slot_time_map[slotB.Id]
if rel == 'na':
time_difference = abs(timeA - timeB)
if time_difference >=240 or time_difference = 180:
penalty_var = model.NewBoolVar(f'penalty_{gameA_id}_{slotA.Id}_{gameB_id}_{slotB.Id}')
model.AddMultiplicationEquality(penalty_var, [gameA_var, gameB_var])
penalty_vars.append((penalty_var, 4))
elif rel == 'this_first':
time_difference = timeB - timeA
if time_difference >=240:
penalty_var = model.NewBoolVar(f'penalty_{gameA_id}_{slotA.Id}_{gameB_id}_{slotB.Id}')
model.AddMultiplicationEquality(penalty_var, [gameA_var, gameB_var])
penalty_vars.append((penalty_var, 20))
elif time_difference >= 180:
penalty_var = model.NewBoolVar(f'penalty_{gameA_id}_{slotA.Id}_{gameB_id}_{slotB.Id}')
model.AddMultiplicationEquality(penalty_var, [gameA_var, gameB_var])
penalty_vars.append((penalty_var, 4))
elif rel == 'other_first':
time_difference = timeA - timeB
if time_difference >=240:
penalty_var = model.NewBoolVar(f'penalty_{gameA_id}_{slotA.Id}_{gameB_id}_{slotB.Id}')
model.AddMultiplicationEquality(penalty_var, [gameA_var, gameB_var])
penalty_vars.append((penalty_var, 20))
elif time_difference >= 180:
penalty_var = model.NewBoolVar(f'penalty_{gameA_id}_{slotA.Id}_{gameB_id}_{slotB.Id}')
model.AddMultiplicationEquality(penalty_var, [gameA_var, gameB_var])
penalty_vars.append((penalty_var, 4))
return penalty_vars
Подробнее здесь: https://stackoverflow.com/questions/793 ... ity-silent
Решатель OR-Tools CP-SAT Оптимизация Python, медленное время выполнения, невозможность, тихий сбой ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Почему мой решатель IDA* дает более длинный путь, чем мой решатель A*? [закрыто]
Anonymous » » в форуме JAVA - 0 Ответы
- 24 Просмотры
-
Последнее сообщение Anonymous
-