简体   繁体   中英

How do I add constraint to pyomo with a range inequality

I am working on a constraint optimization problem and I am using pyomo with abc solver and I am trying to add a constraint with a range.

The code I have written so far is

# 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]))

The constraint I am trying to add that the minimum hours of shift should be 8 hours and maximum hours of shift should be 12 hours. The total hours work in a week should not exceed 52 hours. I am following the below article for optimized shift allocations.

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

The last constraint ensures of 12 hour shift, and I am not sure how to add a constraint for 8 hour shift.

I am very new to pyomo and optimization problem.

Is the length of a shift something that is given ie a model parameter or something that you want your model to decide ie a decision variable?

Depending on the case, you will need to define either a parameter or a variable, respectively, indexed per [day, shift] to represent this. If for instance, we call this shift_len[day, shift] , then your constraint will become:

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]))

Note that if it is a decision variable, then your model becomes nonlinear due to the product of two variables (there are still ways to linearize the product, though). If it is a parameter, then your model remains linear.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM