我正在研究约束优化问题,并且我将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小时。我正在关注以下文章,以优化轮班分配。
最后一个约束确保了12个小时的班次,我不确定如何为8个小时的班次添加约束。
我对pyomo和优化问题很陌生。
移位的长度是给定的东西,即模型参数,还是您希望模型决定的东西,即决策变量?
[视情况而定,您将需要定义一个参数或变量,每个[天,班次]都必须为此索引。例如,如果我们将此称为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]))
请注意,如果它是一个决策变量,则由于两个变量的乘积,您的模型将变为非线性(不过,仍有一些方法可以线性化该乘积)。如果它是一个参数,那么您的模型将保持线性。