## 4 Materials and Methods
### Model  
In this section, the model of the problem is rigorously presented using a Constraint Programming point of view. Let \(\mathbb{J}\) be the set of jobs, \(\mathbb{F}\) be the set of factories, and \(\mathbb{M}\) be a set of machines. Note that each factory has an identical set of machines \(\mathbb{M}\). Let \(x_{jfi}\) be optional interval variables defined over all combinations of \(j\in\mathbb{J},f\in\mathbb{F},i\in\mathbb{M}\). Each optional interval variable is defined by its start time, size, and optionality. The size is a parameter integer value \(D_{j_{i}},\forall j\in\mathbb{J},i\in\mathbb{M}\), denoting the processing time needed for job \(j\) at machine \(i\), which is known in advance. Since the machines in each factory are identical, the index \(f\) does not appear at parameters \(D_{j_{i}}\). An important point is that for each job \(j\) and factory \(f\), the interval variables for the machines of the factory share the same optional indicator, meaning that either all these interval variables are present in the solution or all of them are not present. Another set of auxiliary decision variables are boolean variables \(b_{j_{1}j_{2}}\) for every pair of different jobs \(j_{1},j_{2}\in\mathbb{J}\) and factory \(f\in\mathbb{F}\). The role of these variables is to define the order of appearance of jobs in the schedule. So, \(b_{j_{1}j_{2}}\) assumes value 1 when job \(j_{1}\) starts before job \(j_{2}\) at factory \(f\) and assumes value 0 for all other cases (i.e., when \(j_{2}\) starts before \(j_{1}\) at factory \(f\), or when jobs \(j_{1},j_{2}\) are scheduled at different factories). In DPFSP, each job passes through all machines of the factory that it is scheduled to, occupying the machines in the same order (permutation) as all other jobs. Hereafter, a \"task\" will be each process of a job at a machine. Therefore, each job comprises a sequence of tasks, with each task executed to a machine (i.e., the first task in the sequence is executed at the first machine of a factory, the second task in the sequence is executed at the second machine of the same factory, etc., as dictated by the workflow). The objective is simply the finish time of the latest job and it should be minimized. Since each job is a sequence of tasks for the objective, examining the end times of the last tasks of all jobs as shown in Equation (1) suffices. Next, the constraints of the problem are defined. Some constraints focus on tasks executed on machine 0 (i.e., the first machine in the series of machines that undertake the workflow) of the jobs. These constraints define how the jobs are distributed to factories and the permutation of jobs that the machines of each factory will follow. This is modeled with Equations (2) and (3). Equation (2) defines that the task of each job executed at machine 0 should be scheduled without overlaps with other tasks also executed at machine 0 of the same factory. Note that Equation (2) also determines the permutation of jobs that the machines of each factory will process. Equation (3) ensures that each job will be scheduled at exactly one factory. The equation is applied only to the first machines of each factory since, as stated earlier, all optional interval variables \(x\) for each job, factory, and factory's machines are either all present in the solution or all of them are absent from it. Equation (4) sets the order of appearance of jobs at each factory by enforcing order between jobs for all possible pairs of jobs. It examines the presence of \(x\) variables at the first machines of factories and whether the end time of a job is no later than the start time of another job, setting the corresponding \(b\) variable to 1. Equation (5) ensures that binary variables \(b\) involving job \(j\) and factory \(f\) assume value 0 if job \(j\) is not scheduled to factory \(f\). This occurs because if job \(j\) is not present in factory \(f\), the left parts of the inequalities in Equation (5) will be 0, pushing both \(b\) variables of the right parts to 0 values.