首页 > 解决方案 > 如何使用范围不等式向 pyomo 添加约束

问题描述

我正在研究一个约束优化问题,我正在使用 pyomo 和 abc 求解器,我正在尝试添加一个范围的约束。

到目前为止我写的代码是

# 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 小时轮班添加约束。

我对pyomo和优化问题很陌生。

标签: pythonoptimizationconstraintspyomorostering

解决方案


班次的长度是给定的,即模型参数,还是您希望模型决定的东西,即决策变量?

根据具体情况,您需要分别定义一个参数或变量,按 [day, shift] 索引来表示这一点。例如,如果我们称之为 this 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]))

请注意,如果它是一个决策变量,那么您的模型会由于两个变量的乘积而变为非线性(不过,仍有一些方法可以使乘积线性化)。如果它是一个参数,那么您的模型将保持线性。


推荐阅读