I am trying to formulate a flowshop scheduling problem in Pyomo. This is an Abstract model
Problem description
There are 3 jobs (chest, door and chair) and 3 machines (cutting, welding, packing in that order). Objective is to minimise the makespan. The python code and the data are as follows.
## flowshop.py ##
from pyomo.environ import *
flowshop = AbstractModel()
flowshop.jobs = Set()
flowshop.machines = Set()
flowshop.machinesN = Param()
flowshop.jobsN = Param()
flowshop.proc_T = Param(flowshop.jobs,
flowshop.machines,
within=NonNegativeReals)
flowshop.start_T = Var(flowshop.jobs,
flowshop.machines,
within=NonNegativeReals)
flowshop.makespan = Var(within=NonNegativeReals)
def makespan_rule(flowshop,i,j):
return flowshop.makespan >= flowshop.start_T[i,j]+flowshop.proc_T[i,j]
flowshop.makespan_cons = Constraint(flowshop.jobs,
flowshop.machines,
rule=makespan_rule)
def objective_rule(flowshop):
return flowshop.makespan
flowshop.objc = Objective(rule=objective_rule,sense=minimize)
## data.dat ##
set jobs := chest door chair ;
set machines := cutting welding packing ;
param: machinesN := 3 ;
param: jobsN := 3 ;
param proc_T:
cutting welding packing :=
chest 10 40 45
door 30 20 25
chair 05 30 15
;
I havent added all the constraints yet, I plan to add them after this issue gets fixed. In the code (flowhop.py) above, for the makespan_rule
, I want the makespan to be more that the completion time of only the last machine.
Currently, it is set to be more than completion times of all the machines.
For that, I believe, I have to get the last index of the machines
set.
For that, I tried flowshop.machines[-1]
, but it gives an error saying:
Cannot index unordered set machines
How do I solve this issue?
Thanks for the help.
PS - I am also struggling to model the binary variables used to define the precedence of a job. If you have any ideas regarding that, that would also be helpful.
As the error says Cannot index unordered sets
, the set flowshop.machines
is not ordered. One needs to provide ordered=True
argument in the while declaring the set -
flowshop.machines = Set(ordered=True)
After this, one can access any element by normal indexing - flowshop.machines[i]
For the binary variables, one can declare them as -
c = flowshop.jobsN*(flowshop.jobsN-1)/2
flowshop.prec = Var(RangeSet(1,c),within=Binary)
Then, this variable can be used to decide the precedence between 2 jobs and to formulate the assignment constraints. The precedence variable corresponding to a pair of jobs can be found out using the indices of the jobs (for which the flowshop.jobs
has to be an ordered set - flowshop.jobs = Set(ordered=True)
)