I can remember that I spent some time in understanding how to formulate my first model. So I aimed at presenting a complete model here, wishing to save some time for students or researchers needing it.
The model is a flow shop scheduling problem, presented in Wilson (1989), as following:
\begin{equation} \label{eq1} z = \min (s_{m,n} + \sum_{j=1}^{n}{p_{m,j} z_{j,n}}) \end{equation}
subject to
\begin{equation} \sum_{j=1}^{n}{z_{j,i}} = 1, \quad 1 \leqslant i \leqslant n \end{equation}
\begin{equation} \sum_{i=1}^{n}{z_{j,i}} = 1, \quad 1 \leqslant j \leqslant n \end{equation}
\begin{equation} s_{1,1}=0 \end{equation}
\begin{equation} s_{1,i} + \sum_{j=1}^{n}{p_{1,j} z_{j,i} = s_{1,i+1}}, \quad 1 \leqslant i \leqslant n-1 \end{equation}
\begin{equation} s_{r,1} + \sum_{j=1}^{n}{p_{r,j} z_{j,1} = s_{r+1,1}}, \quad 1 \leqslant r \leqslant m-1 \end{equation}
\begin{equation} s_{r,i} + \sum_{j=1}^{n}{p_{r,j} z_{j,i}\leqslant s_{r+1,i}}, \quad 1 \leqslant r \leqslant m-1, \quad 2 \leqslant i \leqslant n \end{equation}
\begin{equation} s_{r,i} + \sum_{j=1}^{n}{p_{r,j} z_{j,i}\leqslant s_{r,i+1}}, \quad 2 \leqslant r \leqslant m, \quad 1 \leqslant i \leqslant n-1 \end{equation}
\begin{equation} z_{j,i} \in \{0,1\}, \quad 1 \leqslant j \leqslant n, \quad 1 \leqslant i \leqslant n \end{equation}
\begin{equation} s_{r,i} \geqslant 0, \quad 1 \leqslant r \leqslant m, \quad 1 \leqslant i \leqslant n \end{equation}
Note that $s_{r,i}$ is the starting time of job in position $i$ on machine $r$, and $z_{j,i}$ is equal to 1 if job $j$ is assigned to position $i$. Also, $p_{r,j}$ is the processing time of job $j$ on machine $r$. I don't go to the details of the model as in not the purpose of this post.
So, the question is how to formulate this model in Python, using the Gurobi solver. i.e. using the module gurobipy.
Details of model can be found in: Wilson JM. Alternative formulations of a flow-shop scheduling problem. Journal of the Operational Research Society (1989) 40:395–399.
from gurobipy import *toimport gurobipy as grb(this is better design imo and also helps when you have bigger models, multiple files, etc.). Also, variables can be added more efficiently without for loops:z=m.addVars(NumofJobs, NumofJobs, vtype=grb.GRB.BINARY). – David M. Jun 27 '19 at 13:15csvmodule, so no need to import it! – David M. Jun 27 '19 at 13:21update()in most programs (including your small example here) – EhsanK Jun 27 '19 at 13:40