Как добавить ограничение к pyomo с неравенством диапазона - PullRequest
1 голос
/ 15 марта 2020

Я работаю над проблемой оптимизации ограничений и использую pyomo с решателем ab c и пытаюсь добавить ограничение с диапазоном.

Код, который я написал до сих пор:

# Initialize model
model = ConcreteModel()

# binary variables representing if a worker is scheduled somewhere
model.works = Var(((worker, day, shift) for worker in workers for day in date for shift in days_shifts[day]),
                  within=Binary, initialize=0)

# binary variables representing if a worker is necessary
model.needed = Var(workers, within=Binary, initialize=0)

def obj_rule(m):
    c = len(workers)
    return sum(m.needed[worker] for worker in workers)

model.obj = Objective(rule=obj_rule, sense=minimize)

 # Create a set of constraints
model.constraints = ConstraintList()

for day in date:
    for shift in days_shifts[day]:
        model.constraints.add(33 == sum(model.works[worker, day, shift] for worker in workers))                       

# Constraint: no more than 52 hours worked
for worker in workers:
    model.constraints.add(
        52 >= sum(12 * model.works[worker, day, shift] for day in date for shift in days_shifts[day]))

Я пытаюсь добавить ограничение: минимальные часы смены должны составлять 8 часов, а максимальные часы смены - 12 часов. Общее количество часов работы в неделю не должно превышать 52 часа. Я следую приведенной ниже статье, чтобы оптимизировать распределение смен.

https://towardsdatascience.com/modeling-and-optimization-of-a-weekly-workforce-with-python-and-pyomo-29484ba065bb

Последнее ограничение обеспечивает 12-часовую смену, и я не уверен, как добавить ограничение на 8-часовую смену.

Я очень плохо знаком с проблемой пиомо и оптимизации.

1 Ответ

0 голосов
/ 26 марта 2020

Является ли длина сдвига тем, что задано, т.е. параметром модели, или тем, что вы хотите, чтобы ваша модель решала, например, переменной решения?

В зависимости от случая вам потребуется определить либо параметр, либо или переменная, соответственно, проиндексированная за [день, смена], чтобы представить это. Если, например, мы назовем это shift_len[day, shift], тогда ваше ограничение станет:

for worker in workers:
    model.constraints.add(
        52 >= sum(shift_len[day, shift] * model.works[worker, day, shift] for day in date for shift in days_shifts[day]))

Обратите внимание, что если это переменная решения, то ваша модель становится нелинейной из-за произведения двух переменных (есть все же способы линеаризации продукта, хотя). Если это параметр, то ваша модель остается линейной.

...