1 Introduction

The problem considered is the non-preemptive scheduling of n jobs on m parallel identical machines such that each unit time interval cannot intersect more than B jobs on each machine. That is, for a time interval \([\alpha , \alpha +1)\), for \(\alpha \in \mathbb {R}_{+}\) and for a given machine i, the number of jobs being (partially or completely) processed on i in this time interval cannot be more than B. This constraint is referred to as time constraint and the problem is denoted as STS (Scheduling with Time Restrictions on identical machines). Formally, the problem is defined as follows. The input consists of n independent jobs and m identical parallel machines, each job j has a processing time \(p_j\in \mathbb {R}_{+}{}\) also known as the size of j, and finally there is a positive integer \(B \ge 2\). A non-preemptive schedule assigns every job j a pair consisting of a machine and an interval along the time horizon such that the length of the time interval assigned to j is exactly \(p_j\) and two such time intervals assigned to a pair of jobs \(j,j'\) both of which assigned to a common machine, do not intersect in an inner-point. The makespan, that is the maximum completion time of a job in such non-preemptive schedule is the goal function that we aim to minimize, and our problem, STS is to find a non-preemptive schedule subject to time constraint saying that in every time interval I of length 1 and every machine i, the number of jobs assigned to i that the schedule assigns to time intervals intersecting I is at most B.

A \(\rho \)-approximation algorithm for a minimization problem is a polynomial time algorithm that always finds a feasible solution of cost at most \(\rho \) times the cost of an optimal solution. A polynomial time approximation scheme (PTAS) for a given problem is a family of approximation algorithms such that the family has a \((1+\varepsilon )\)-approximation algorithm for any \(\varepsilon >0\). An efficient polynomial time approximation scheme (EPTAS) (Cesati and Trevisan 1997; Downey and Fellows 1999; Flum and Grohe 2006) is a PTAS whose time complexity is upper bounded by the form \(f(\frac{1}{\varepsilon }) \cdot poly(n)\) where f is some computable (not necessarily polynomial) function and poly(n) is a polynomial of the length of the (binary) encoding of the input. A fully polynomial time approximation scheme (FPTAS) is defined like an EPTAS, with the added requirement that f must be upper bounded by a polynomial in \(\frac{1}{\varepsilon }\).

The time constraint is introduced in Braun et al. (2014) who considers the special case of our problem on a single machine. They prove that the problem is NP-hard when the value of B is a variable and perform the worst-case analysis of List Scheduling (LS) algorithm for this case of our problem. Later studies considering time constraint were considering only the special case of our problem with one machine (i.e., \(m=1\)). Benmansour et al. (2014) presented a time-indexed mixed integer linear programming formulation for it (see also Benmansour et al. (2019) for other mixed-integer linear programming formulations of the problem). Braun et al. (2016) improved the analysis for LS and analyzed the worst-case behavior of Longest Processing Time schedules. A better permutation of jobs that improved the bounds is derived in Zhang et al. (2017). Most relevant to our work, Zhang et al. (2018) shows that the problem is NP-hard even when \(B=2\) and exhibits a PTAS for the problem with any constant \(B\ge 2\). We mention the fact that the last PTAS of Zhang et al. (2018) is not an EPTAS and does not lead to a PTAS for the special case of STS with one machine and a non-constant value of B. We will show here an EPTAS for STS even for an arbitrary (and no-constant) number of identical machines, and as a by-product improve the approximation guarantee on the problem for one machine.

Minimizing the makespan on identical machines is a special case of STS that corresponds to the case \(B=n\). Hochbaum and Shmoys (1987) showed an EPTAS [see also Hochbaum (1997), Chapter 9 and Alon et al. (1998)] for the makespan minimization objective for this setting. Jansen et al. (2020) improved the time complexity of this EPTAS (also for related problems). Note that minimizing the makespan on identical machines is known to be NP-hard in the strong sense, and thus unless \(P=NP\), there is no FPTAS for it and so also for STS that we study here. Therefore, EPTAS is the fastest class of approximation schemes that can be obtained to approximate our problem.

Last, the special case where the algorithm knows in advance that the optimal makespan is smaller than 1 is equivalent to the scheduling problem on identical machines with the constraint saying that every machine can be assigned at most B jobs. This case known as scheduling with cardinality constraint and its generalization saying that every machine may have different capacity admit EPTAS (on identical machines) (Chen et al. 2016). This EPTAS will be used here for one simple case. See Dell’Amico and Martello (2001), He et al. (2003), Dell’Amico et al. (2006), Kellerer and Kotov (2011), Chen et al. (2016), Kawase et al. (2021) for further studies of scheduling with cardinality constraint.

Outline of our scheme and methods Our scheme starts by rounding the job sizes, guessing the makespan value for using the dual approximation approach of Hochbaum and Shmoys (1987), Hochbaum and Shmoys (1988), and characterizing a sub-class of solutions containing at least one nearly optimal solution, see Sect. 2. Next, we formulate a mixed-integer linear program (MILP) in Sect. 3 based on a hierarchy of configurations. The use of integer linear programs in fixed dimension and of mixed-integer linear programs with fixed number of integral decision variables is common in the design of EPTAS’s for scheduling and load balancing problems, see e.g. Hochbaum and Shmoys (1987), Alon et al. (1998), Jansen (2010), Epstein and Levin (2014), Epstein and Levin (2014), Chen et al. (2016), Jansen et al. (2020), Jansen and Maack (2019), Kones and Levin (2019). Here, we will use the term configuration to encode the schedule of one machine, and we use the term container to refer to a sub-schedule of one configuration restricted to a portion of the time horizon where the jobs assigned to it are relatively short. This will allow us to have a constant number of configurations and a constant number of containers, but the job assignment to machines based on the counters of these terms is not well-defined. Such a notion of hierarchy of configurations was used before, see e.g. Jansen et al. (2019). However, here we have a polynomial number of fractional decision variables and constraints so unlike (Jansen et al. 2019) we will need to allow most of them to be fractional before applying Lenstra’s algorithm (Lenstra 1983; Kannan 1983). The rounding of a MILP solution into a feasible schedule is the main technical part of our scheme. The most non-standard step in this rounding phase is the rounding of the tiny jobs based on a non-standard use of the integrality of polytopes defined using an interval matrix and integer right hand side followed by a step analyzed in Chen et al. (2016). While in Sect. 3 we show that there is a feasible solution for the MILP for a correct guessed value of the makespan, the rounding of the optimal solution of the MILP is presented and analyzed in Sect. 4.

2 Rounding, guessing, and a characterization of near optimal solutions

Preliminaries: definitions and notation Let \(\varepsilon >0\) be such that \(1/\varepsilon \) is an integer larger than 3. A unit time interval is denoted by \(1-\)interval. A time interval of length \(1+\varepsilon \) that starts at integer multiple of \(\varepsilon \) is defined as a \(1'-\)interval. A schedule assigns jobs to machines and starting times to jobs. Let J be the set of jobs and M the set of machines. The load of a machine is the finishing time of the last job assigned to the machine. Note that schedules may have idle time so the load of a machine is not necessarily the total size of jobs assigned to that machine.

We define blocks of schedules in order to facilitate the definition of containers in the next section. A block of schedule of length \(1/\varepsilon \) of one specific machine i is referred to as a \((1/\varepsilon )-\)block and it is the set of jobs that are assigned to start, parts of jobs, and the amount of idle time in \(1/\varepsilon \) length of time of the schedule of machine i. That is, the set of jobs whose processing intervals on machine i intersects (in a non-empty interval) the given time interval of length \(1/\varepsilon \). A block of schedule of one particular machine of length \(\varepsilon {}\) starting at integer multiple of \(\varepsilon \) is called an \(\varepsilon -\)block, i.e., the set of jobs that are assigned to start, parts of jobs, and the amount of idle time assigned to be processed on this machine in the given \(\varepsilon {}\) length time interval that starts at an integer multiple of \(\varepsilon \) of the time horizon.

We define a new (more strict as we show in the next lemma) constraint called modified time constraint. A schedule satisfies modified time constraint if no more than B jobs assigned to a common machine intersect with every \(1'-\)interval of the schedule.

Lemma 1

If a schedule satisfies modified time constraint then it also satisfies the time constraint.

Proof

Every \(1-\)interval that starts at an arbitrary point in time is contained within a \(1'-\)interval. Since the number of jobs being processed in every \(1'-\)interval on a given machine is at most B, every \(1-\)interval of that machine contains at most B jobs. \(\square \)

The rounding step Round up the size of each job to the next integer power of \(1+\varepsilon \). Denote the rounded size of the job j by \(p'_j\). That is, \(p'_j=(1+\varepsilon )^{\lceil \log _{(1+\varepsilon )} p_j \rceil }\). Notice that, \( p_j \le p'_j \le (1+\varepsilon )p_j\).

Denote by \(I'\) the rounded instance where the size of all the jobs are rounded as specified. Next, we analyze this rounding step using the standard argument of time stretching.

Lemma 2

Any schedule \(\sigma \) feasible to instance I, of makespan \(C_{max}\), can be used to generate a schedule \(\sigma '\) which is feasible to the rounded instance \(I'\) with makespan at most \((1+\varepsilon )C_{max}\). Any schedule \(\sigma '\) feasible to the rounded instance \(I'\), of makespan \(C'_{max}\), is feasible to the original instance I with makespan at most \(C'_{max}\).

Proof

Consider a schedule \(\sigma \) feasible to instance I of makespan \(C_{max}\). Consider one specific machine i (we apply the process for each machine) and denote its load in \(\sigma \) by \(L_i\). Convert \(\sigma \) to \(\sigma '\) by rounding up the sizes of all the jobs, without changing the ordering of the jobs assigned to i, and multiplying the starting time of every job by \(1+\varepsilon \). This process guarantees that the number of jobs in each \(1-\)interval is not increased. Thus time constraint is satisfied by \(\sigma '\). The new load of i is at most \((1+\varepsilon )L_i\), and thus the new makespan satisfies \(C'_{max} \le (1+\varepsilon )C_{max}\) as required.

For the other direction, consider a schedule \(\sigma '\) which is feasible to the instance \(I'\) of makespan \(C'_{max}\) and one machine i. The jobs in \(\sigma '\) are rounded down to get instance I but the starting time of the jobs remain fixed, i.e. same as in \(\sigma '\). Thus additional idle time is added as necessary during the conversion. We denote by \(\sigma \) the resulting schedule of I. Since \(\sigma '\) satisfies the time constraint, the number of jobs in every \(1-\)interval of \(\sigma '\) assigned to i is at most B. Since the starting time of the jobs does not change, every \(1-\)interval in \(\sigma \) assigned to i also contains at most B jobs. Thus, \(\sigma \) is feasible and the makespan of \(\sigma \) is at most \(C'_{max}\). \(\square \)

With a slight abuse of notation we assume without loss of generality that the input I is already rounded, that is, \(I=I'\) and so \(p_j\) will denote the rounded size of job j.

Guessing step We guess the makespan of the schedule rounded up to an integer power of \(1+\varepsilon \). An a-priori valid upper bound on the makespan is \(n + \sum _{j\in J}p_j\). The lower bound on the makespan is \(\frac{\sum _{j\in J}p_j}{m}\). Using these bounds will lead to a weakly polynomial upper bound on the number of possibilities for this guessed information. Thus, we consider the following bound. Let i be a machine attaining the makespan in a fixed optimal solution and let \(p_{\max }\) be the maximum size of a job in \(I'\). Since the number of jobs assigned to i is between 1 and n, we conclude that the makespan is not smaller than \(p_{\max }\) and not larger than \(n(1+p_{\max })\). If the guessed makespan is smaller than 1, we will have a different procedure that does not use the guessed value of the makespan. Thus, the number of guessed values of at least 1 is not larger than \(\log _{1+\varepsilon } (2n)\). We conclude the following lemma.

Lemma 3

The number of possible values for the guess of the makespan that are at least 1 is at most \(O(\log _{1+\varepsilon } n)\), that is there are a strongly polynomial number of possibilities.

The guess of the makespan is denoted by \(\texttt{C}_{max}\). If \(\texttt{C}_{max}<1\), then we apply the scheme of Chen et al. (2016) with a uniform capacity bound of B on each machine, to obtain an EPTAS for our problem. In what follows, we assume that \(\texttt{C}_{max}\ge 1\) and observe that the number of such possibilities is at most \(O(\log _{1+\varepsilon } n)\) based on the last lemma.

Classification of jobs Let \(\theta = \max \{\varepsilon \texttt{C}_{max},(1/\varepsilon )\}\). A job j is classified as tiny if \(p_j \le \varepsilon ^2\), small if \(\varepsilon ^2 < p_j \le 1/\varepsilon \), medium if \(1/\varepsilon < p_j \le \theta \), and large if \(\theta < p_j \le \texttt{C}_{max}\). There can be instances where the interval of sizes of medium jobs and perhaps the interval of sizes of large jobs are empty. In particular when \(\texttt{C}_{max}\) is at most \(1/\varepsilon \) there are no medium or large jobs.

The number of distinct sizes of small jobs is at most \(\log _{(1+\varepsilon )}(1/\varepsilon )^3 + 1\). Let \(\texttt{S}\) denote the set of distinct sizes of small jobs. The number of distinct sizes of large jobs is at most \(\log _{(1+\varepsilon )} (1/\varepsilon )+ 1\). Let \(\texttt{L}\) be the set of distinct sizes of large jobs. So \(|\texttt{S}|\) and \(|\texttt{L}|\) are upper bounded by functions of \(\varepsilon \). The number of distinct sizes of medium or tiny jobs cannot be upper bounded by a function of \(\varepsilon \) and these values will be upper bounded by polynomials (e.g., at most n such distinct sizes).

Let \(\texttt{TJ}\), \(\texttt{SJ}\), \(\texttt{MJ}\), \(\texttt{LJ}\) be the set of tiny, small, medium, and large jobs, respectively. Any of the aforementioned job sets with a subscript l denotes the subset of jobs of that set of size l.

Definition of nice solutions A schedule is nice if the schedule on each machine satisfies the following four conditions.

  1. 1.

    The jobs in the schedule appear in the order of tiny or small jobs followed by medium jobs and then large jobs.

  2. 2.

    In every \(\varepsilon -\)block of the schedule the idle time is at the beginning of the \(\varepsilon -\)block or at the completion time of the job that is being processed at the start of the \(\varepsilon -\)block and the jobs that start in the \(\varepsilon -\)block continue their processing continuously, in non-decreasing order of processing time.

  3. 3.

    There is unit idle time between processing a pair of jobs if there is a difference of at least \(1/\varepsilon \) time between their starting times.

  4. 4.

    The schedule satisfies the modified time constraint.

We will use the set of nice solutions as a family of highly-structured solutions with the property that approximating the best solution among this set is sufficient for approximating the original problem. Thus, we base our approach on the following lemma.

Lemma 4

Every feasible schedule \(\sigma \) of makespan \(C_{\sigma }\) can be converted to a nice schedule \(\sigma '\) of makespan at most \((1+17\varepsilon ) C_{\sigma }\).

Proof

Consider a feasible schedule \(\sigma \) of makespan \(C_{\sigma }\). Perform the following operations for each machine i. Let the load of machine i be \(L_i\), and the schedule for machine i in \(\sigma \) be \(\sigma _i\). Feasibility ensures that the starting time of the jobs and the idle time in \(\sigma _i\) are such that the schedule satisfies the time constraint and the scheduling constraints (i.e., this is a non-preemptive schedule on machine i). Convert \(\sigma _i\) to a schedule with the same set of jobs on machine i as follows.

  1. 1.

    At integer points of time in \(\sigma _i\) add idle time of \(2\varepsilon \) as follows. At each integer point of time t there can be one of the following two cases.

    • When no job is being processed at t. Add idle time of \(2\varepsilon \) at t.

    • When a job j is being processed at t. Add idle time of length \(2\varepsilon \) at the completion time and the starting time of j.

    We do this step simultaneously to all points along the schedule that were integer points in time before this step (i.e., in \(\sigma _i\)). No matter how the starting time of the added idle time is modified the added idle time will contain an \(\varepsilon -\)block of idle time. This step can increase the length of the schedule by at most \(4\varepsilon \) for each integral point of time in \(\sigma _i\) so the load of i will increase by at most \(4\varepsilon L_i\).

  2. 2.

    At the starting time and completion time of medium and large jobs add idle time of length 2. This step increases the load of i by at most \(4\varepsilon L_i\) since the size of a medium/large job is at least \(1/\varepsilon \).

  3. 3.

    For each medium and large job do the following. Remove the job from the schedule and then shift the remaining schedule backward to the starting time of the job. After the end of the partial schedule obtained by removing all the medium and large jobs add a unit idle time and then place the medium and large jobs in non-decreasing order of the size.

    This step basically pulls the medium and large jobs from the schedule and moves them to the end of the schedule (of the same machine i). The ordering of small jobs, tiny jobs, and idle time (until the first medium or large job) is kept as the outcome of step 2. The unit length idle time before the first medium/large job adds at most \(\varepsilon L_i\) to the load of i.

  4. 4.

    At integer multiples of \(1/\varepsilon \) in the schedule obtained from \(\sigma _i\) after Step 3 add idle time as follows. At each integer multiple t (simultaneously for all t) one of the following two cases holds.

    • When no job is being processed at \(t/\varepsilon \), add 2 units of idle time at \(t/ \varepsilon \).

    • When a job j is being processed at \(t/ \varepsilon \), add idle time of length 2 at the finishing time of j.

    No matter how the starting time of the added idle period will be modified in the future it will contain a \(1-\)interval of idle time starting at an integer multiple of \(\varepsilon \). This step increases the load of the machine by at most \(8\varepsilon L_i\) since the load of i after the previous step was at most \((1+9\varepsilon )L_i \le 4L_i\).

  5. 5.

    For each \(\varepsilon -\)block do the following. Calculate the total idle time in the \(\varepsilon -\)block. If there is a job that starts in an earlier \(\varepsilon -\)block and finishes in the current \(\varepsilon -\)block, then move this total idle time to the finishing time of that job, else to the beginning of the \(\varepsilon -\)block. Sort all the jobs starting in this \(\varepsilon -\)block in non-decreasing order of size. Now the machine operates continuously till the last job assigned to start in the \(\varepsilon -\)block is finished.

Let \(\sigma '\) be the schedule of machine i obtained after all the above operations. After Step 1, \(\sigma \) is converted to schedule \(\tilde{\sigma }\). Consider a \(1'-\)interval O of machine i in \(\tilde{\sigma }\). There are two cases to deal with. First case is when there is idle time (added in Step 1) of at least \(\varepsilon {}\) in O. Then the set of jobs, complete and fractional, in O used to belong to a \(1-\)interval in \(\sigma \). Thus since this set of jobs in O satisfied the time constraint in \(\sigma \), they do not violate the modified time constraint in \(\tilde{\sigma }\). Second case is when idle time (added in Step 1) in O is of length strictly less than \(\varepsilon \). This happens because the unique job in O, complete or fractional, is of size at least 1. Thus this job (complete or fractional) used to belong to a \(1-\)interval in \(\sigma \) and thus O satisfies modified time constraint in \(\sigma '\). Adding idle time of length 2 to the schedule maintains the modified time constraint.

Thus, steps 2 and 4 maintain the modified time constraint. Step 3 maintains the modified time constraint since every \(1'-\)interval containing small or tiny jobs in the resulting schedule, contains jobs that were in a common \(1'-\)interval prior to this step as there is idle time of length at least 2 between such subsets of small or tiny jobs, and furthermore every other \(1'-\)interval is either empty or contains at most two jobs (that are medium or large jobs and thus of length larger than 2) so modified time constraint is satisfied using \(B\ge 2\). Step 5 maintains modified time constraint because we can permute the jobs starting in every \(\varepsilon -\)block in an arbitrary way as long as the set of jobs starting in this block is not changed and the modified time constraint will continue to hold.

Thus in the schedule \(\sigma '\) of machine i resulting at the end of step 5, the following holds.

  • The jobs in the schedule appear in the order of tiny or small jobs followed by medium jobs and then large jobs.

  • In every \(\varepsilon -\)block of the schedule the idle time is at the beginning of the \(\varepsilon -\)block or at the completion time of the job that is being processed at the start of the \(\varepsilon -\)block and the jobs that start in the \(\varepsilon -\)block continue their processing continuously, in non-decreasing order of processing time.

  • There is a unit length idle time between processing a pair of jobs if there is a difference of at least \(1/\varepsilon \) time between their starting times.

  • The schedule satisfies the modified time constraint.

The load of every machine i is at most \((1+17\varepsilon ) L_i\) and thus the resulting makespan is at most \(1+17\varepsilon \) times the makespan of \(\sigma \). \(\square \)

Let \(\mathcal {C}_{max}^{nice}\) be the makespan of the best nice solution (of \(I'\)) rounded up to the next integer power of \(1+\varepsilon \). Since we have guessed \(\texttt{C}_{max}\) already, we can also guess \(\mathcal {C}_{max}^{nice}\) in a constant number of iterations based on the last lemma. In what follows, we assume that the algorithm knows the value of \(\mathcal {C}_{max}^{nice}\) and shows that if it uses a correct upper bound on the makespan of the best nice solution then it results in a feasible schedule of makespan at most \((1+\varepsilon )^c \mathcal {C}_{max}^{nice}\) for some constant value of c.

3 The mixed-integer linear program

The Mixed Integer Linear program (MILP) we exhibit below uses containers and configurations defined for our problem. A solution of the MILP defines a choice of configurations and containers (among other information regarding the schedule). A configuration or container can be chosen multiple times and the MILP ensures that the containers satisfy the modified time constraint (consequently the time constraint).

Containers A container t stores information for a set of consecutive \(\varepsilon -\)blocks, denoted by \(K_t\) such that \(|K_t|\le (1/\varepsilon )^2\). Each \(k\in K_t\) corresponds to an \(\varepsilon -\)block and each component is associated with a sub-vector of length \(|\texttt{S}| + 4\). A sub-vector associated to the \(\varepsilon -\)block \(k\in K_t\) contains the following components. The first \(|\texttt{S}|\) components store the number of small jobs of size l, for every \(l\in \texttt{S}\), assigned to start in the \(\varepsilon -\)block k, and it is denoted by \(S_{lkt}\). The next component, \(T_{kt}\), stores the lower bound on the total size of tiny jobs rounded down to an integer multiple of \(\varepsilon ^2\) in the sense that \(T_{kt} \varepsilon ^2\) is the lower bound and \(T_{kt}\) is a non-negative integer. The next component, \(T'_{kt}\), is a binary indicator and is 1 if there is at least one tiny job that starts in this \(\varepsilon -\)block. The next component, \(D_{kt}\), stores the length of the idle time in the \(\varepsilon -\)block rounded down to an integer multiple of \(\varepsilon ^2\) in the sense that \(D_{kt} \varepsilon ^2\) is the lower bound on the length of this interval of idle time and \(D_{kt}\) is a non-negative integer. The last component is a binary indicator denoted by \(P_{kt}\). \(P_{kt}\) is 1 when the last job assigned to \(\varepsilon -\)block at most \(k-1\) continues its processing at the beginning of \(\varepsilon -\)block k, else it is 0.

The load of a container t, \(L_t\), is the total size of the jobs and idle time assigned to the container and an additional idle time of one unit at the end of the container i.e.

$$\begin{aligned} L_t = \sum _{k\in K_t}\left( D_{kt}\varepsilon ^2 + T_{kt}\varepsilon ^2 + \sum _{l\in \texttt{S}}l \cdot S_{lkt}\right) + 1. \end{aligned}$$

Since each non-binary component in a sub-vector corresponding to an \(\varepsilon -\)block is a non-negative integer of at most \(1/\varepsilon \), there are at most \(1/\varepsilon +1\) possible values for each such component and we conclude the following lemma.

Lemma 5

The number of possible containers denoted as \(\textsf{CN}\) is at most \(\left( ((1/\varepsilon )+ 1)^{|\texttt{S}|+2}\cdot 4\right) ^{(1/\varepsilon )^2}\).

Short and long containers Containers are further classified based on the load of the container as below. A container is short if the load of the container is at most \(\varepsilon \mathcal {C}_{max}^{nice}\), else it is long. The load of a long container is at most \(\mathcal {C}_{max}^{nice}+1\).

Feasibility of a container Create a partial schedule from a container t. In an increasing order of \(k\in K_t\) do the following. Add \(D_{kt} \varepsilon ^2\) length of idle time at the beginning of the \(\varepsilon -\)block if \(P_{kt}=0\) or the finishing time of the job being processed at the beginning of the \(\varepsilon -\)block if \(P_{kt}=1\). Then add a virtual job of size \(T'_{kt}\cdot T_{kt}\cdot \varepsilon ^2\), to account for the tiny jobs. Then add the small jobs in sequence one after the other in non-decreasing order of the size of the job. Container t is feasible if at most one job continues its processing out of every \(\varepsilon -\)block in the partial schedule generated from the container. Let \(\texttt{T}\) be the set of feasible containers. Let \(\mathtt {T_L}\) be the set of feasible long containers and \(\mathtt {T_S}\) be the set of feasible short containers. The cardinalities of these sets, namely \(|\texttt{T}|\), \(|\mathtt {T_L}|\), and \(|\mathtt {T_S}|\), are upper bounded by \(\textsf{CN}\).

Rounding load of containers The load of each container t is rounded down to the next integer power of \(1+\varepsilon \) and the resulting rounded load is denoted by \(L'_t\), i.e., \(L'_t = (1+\varepsilon )^{\left\lfloor \log _{(1+\varepsilon )} L_t\right\rfloor }\). The number of distinct values of (rounded) load of long containers is at most \(\log _{(1+\varepsilon )}\left( \frac{2}{\varepsilon }\right) + 2\). Let \(\mathtt {CN_L}\) be the set of distinct rounded loads of long containers and \(|\mathtt {CN_L}|\) is upper bounded by a function of \(\varepsilon \).

Configurations A configuration c is a vector of length \(|\mathtt {CN_L}|+|\texttt{L}|+4\). For \(l\in \mathtt {CN_L}\), we have a component \(\alpha _{cl}\) that stores the number of long containers of rounded load l assigned to that configuration. The next component \(\beta _c\) stores the lower bound on the total load of short containers assigned to the configuration rounded down to an integer multiple of \(\varepsilon ^2\mathcal {C}_{max}^{nice}\) in the sense that \(\beta _c \varepsilon ^2 \mathcal {C}_{max}^{nice}\) is the lower bound and \(\beta _c\) is a non-negative integer. The next component is a binary indicator \(\beta '_c\) that is 1 if at least one short container is assigned to c. The next \(|\texttt{L}|\) components store the number of large jobs of each size assigned to a machine with this configuration, for \(\texttt{l}\in \texttt{L}\) the corresponding component is denoted as \(\gamma _{c\texttt{l}}\). The next component \(\delta _c\) stores the lower bound on the total size of the medium jobs rounded down to an integer multiple of \(\varepsilon ^2\mathcal {C}_{max}^{nice}\) in the sense that \(\delta _c \varepsilon ^2 \mathcal {C}_{max}^{nice}\) is the lower bound and \(\delta _c\) is a non-negative integer. The last component \(\delta '_c\) is a binary indicator and is 1 if at least one medium job is assigned to c.

The load of a configuration c is denoted as \(L_c\) and it is defined as

$$\begin{aligned} L_c = \sum _{l\in \mathtt {CN_L}}l\alpha _{cl} + \beta _c\varepsilon ^2\mathcal {C}_{max}^{nice}+ \sum _{\texttt{l}\in \texttt{L}}\texttt{l}\gamma _{c\texttt{l}} + \delta _c\varepsilon ^2\mathcal {C}_{max}^{nice}. \end{aligned}$$

Feasibility of a configuration A configuration is feasible if the containers assigned to the configuration are feasible and the load of the configuration is at most \(\max \{ (1+\varepsilon )\mathcal {C}_{max}^{nice}, \mathcal {C}_{max}^{nice}+1\}\). In addition to that, if \(\mathcal {C}_{max}^{nice}\le 1/\varepsilon \) then the configuration will consist of exactly one long container of load at most \(\mathcal {C}_{max}^{nice}+1\) (and no other containers, medium jobs, or large jobs). Let \(\texttt{C}\) be the set of feasible configurations.

The load of the configuration is upper bounded by \(\mathcal {C}_{max}^{nice}+1\) since the load of the containers is increased by unit idle time, so the load of a unique container could be larger than the last completion time of a job assigned to a machine with this container. The next lemma follows by upper bounding the number of different values each component on a configuration can take.

Lemma 6

The number of possible feasible configurations is at most \((2/\varepsilon )^{{|\mathtt {CN_L}|} + |\texttt{L}|+4}\cdot 4\) and we denote this constant (when \(\varepsilon \) is fixed) as \(\textsf{CF}\).

We summarize the last defined constant terms in Table 1.

Table 1 Upper bounds as functions of \(\varepsilon \)

Formulation of the MILP We are ready to formulate the MILP. First, we explain the set of decision variables, then we present the linear constraints. Our MILP is a feasibility mathematical program, that is, there is no objective function, but we are only interested in finding a feasible solution (if there is such) or report that there is no feasible solution if such solution does not exist.

Decision variables We have two families of decision variables. Assignment variables to assign jobs/containers to containers/configurations, and counters to count the number of times a container/configuration is chosen. There are three types of assignment variables and two types of counters.

Assignment of containers to configurations The variable \(z_{ct}\) indicates the number of times a container t is assigned to configuration c. The total number of assignment variables of containers to configurations is \(\textsf{CN}\cdot \textsf{CF}\), which is a constant when \(\varepsilon \) is fixed. They are forced to be integral.

Assignment of tiny jobs to containers The variable \(y_{jkt}\) is 1 when a tiny job j is assigned to start in the \(k^{th}\) \(\varepsilon -\)block in container t. The total number of assignment variables of tiny jobs to containers is at most \(n\cdot (1/\varepsilon )^2 \cdot \textsf{CN}\), which is upper bounded by a polynomial in the input encoding length. These variables are allowed to be fractional.

Assignment of medium jobs to configurations The variable \(x_{jc}\) is 1 when medium job j is assigned to configuration c. The total number of assignment variables of medium jobs to configurations is at most \(n\cdot \textsf{CF}\), which is upper bounded by a polynomial in the input encoding length. These variables are allowed to be fractional.

Container counters The variable \(w_t\) represents the number of times the container t is chosen. The number of container counters is \(\textsf{CN}\) which is a constant when \(\varepsilon \) is fixed. These variables are forced to be integral.

Configuration counters The variable \(v_c\) represents the number of times the configuration \(c\in C\) is chosen. The number of configuration counters is \(\textsf{CF}\) which is a constant when \(\varepsilon \) is fixed. These variables are forced to be integral.

We conclude that the MILP will have \( \textsf{CN}\cdot \textsf{CF}+ \textsf{CN}+ \textsf{CF}\) integer decision variables and at most \(n \cdot ((1/\varepsilon )^2 \cdot \textsf{CN}+ \textsf{CF})\) fractional decision variables.

The constraints of the MILP Next, we present the constraints of the MILP together with their intuitive explanation. Note that this intuition is described only to assist us in formulating the MILP, but the MILP’s relevance and correctness are not based on this intuition and they will be derived below.

Assigning tiny jobs to containers

$$\begin{aligned} \sum _{t\in \texttt{T}}\sum _{k\in K_t}y_{jkt}&= 1,\forall j\in \texttt{TJ} \end{aligned}$$
(1)
$$\begin{aligned} \sum _{j\in \texttt{TJ}}p_jy_{jkt}&\le w_tT'_{kt}(T_{kt}+1)\varepsilon ^2,\ \forall k\in K_t, \forall t\in \texttt{T} \end{aligned}$$
(2)

There is enough positions for all the small jobs of each size in containers

$$\begin{aligned} \sum _{t\in \texttt{T}}\sum _{k\in K_t}S_{lkt}w_t = |\texttt{SJ}_l|, \forall l\in \texttt{S} \end{aligned}$$
(3)

Assigning medium jobs to configurations

$$\begin{aligned} \sum _{c\in \texttt{C}} x_{jc}&= 1, \forall j\in \texttt{MJ} \end{aligned}$$
(4)
$$\begin{aligned} \sum _{j\in \texttt{MJ}}x_{jc}p_j&\le v_c\delta '_c(\delta _c+1)\varepsilon ^2\mathcal {C}_{max}^{nice},\ \forall c\in \texttt{C} \end{aligned}$$
(5)

There is enough positions for all the large jobs of each size in configurations

$$\begin{aligned} \sum _{c\in \texttt{C}} \gamma _{cl}v_c = |\texttt{LJ}_l|,\ \forall l\in \texttt{L} \end{aligned}$$
(6)

The number of times a container is chosen is equal to the sum of the number of times that container is assigned to all the configurations.

$$\begin{aligned} \sum _{c\in \texttt{C}}z_{ct}&= w_t,\ \forall t\in \texttt{T} \end{aligned}$$
(7)

If a configuration is not chosen, then there are no containers assigned to that configuration. Otherwise, any number of containers (and without loss of generality this is at most n) can be assigned to copies of that configuration

$$\begin{aligned} z_{ct}&\le n v_c,\ \forall t\in \texttt{T}, c\in \texttt{C} \end{aligned}$$
(8)

Assigning short containers to configurations

$$\begin{aligned} \sum _{t\in \mathtt {T_S}} L_tz_{ct}\le v_c\beta '_c(\beta _c+1)\varepsilon ^2\mathcal {C}_{max}^{nice},\ \forall c\in \texttt{C} \end{aligned}$$
(9)

There is enough positions for all the long containers of each rounded load in the configurations

$$\begin{aligned} \sum _{t:L'_t=l}w_t&= \sum _{c\in \texttt{C}} v_c\alpha _{cl},\ \forall l\in \mathtt {CN_L} \end{aligned}$$
(10)

We enforce modified time constraint by enforcing the following average constraints for containers

$$\begin{aligned}&\sum _{k=i}^{i+(1/\varepsilon )} \left( w_t\sum _{l\in \texttt{S}}S_{lkt} + \sum _{j\in \texttt{TJ}}y_{jkt}\right) + w_tP_{it}\le w_t \cdot B,\nonumber \\&\quad i=1,2,\ldots ,(|K_t|-((1/\varepsilon )+1)), \forall t\in \texttt{T} \end{aligned}$$
(11)

Number of configurations chosen equals the number of machines

$$\begin{aligned} \sum _{c\in \texttt{C}}v_c = |M| \end{aligned}$$
(12)

Non-negativity constraints and integrality constraints

$$\begin{aligned} 0 \le y_{jkt}&\le 1,\ \forall j\in \texttt{TJ},k\in K_t,t\in \texttt{T}\end{aligned}$$
(13)
$$\begin{aligned} 0 \le x_{jc}&\le 1,\ \forall j\in \texttt{MJ},c\in \texttt{C}\end{aligned}$$
(14)
$$\begin{aligned} w_t&\in \mathbb {Z}_+,\ \forall t\in \texttt{T}\end{aligned}$$
(15)
$$\begin{aligned} v_c&\in \mathbb {Z}_+,\ \forall c\in \texttt{C}\end{aligned}$$
(16)
$$\begin{aligned} z_{ct}&\in \mathbb {Z}_+,\ \forall c\in \texttt{C},\forall t\in \texttt{T}\end{aligned}$$
(17)

A MILP solution will give \(({\textbf {v}},{\textbf {w}},{\textbf {x}},{\textbf {y}},{\textbf {z}})\). We conclude this section by proving that if there is a feasible nice schedule (for the current guessed value of the approximated makespan of the best nice solution), then the MILP has a feasible solution.

Theorem 1

If there exists a feasible nice schedule to STS with makespan at most \(\mathcal {C}_{max}^{nice}\), then the MILP has a feasible solution.

Proof

Assume that there exists a nearly optimal nice schedule opt for the rounded instance \(I'\). Let the makespan of opt be \(C_{\textsf {opt}}\le \mathcal {C}_{max}^{nice}\). Let the schedule for machine i in this solution be \(\textsf {opt}_i\). We generate a feasible MILP solution from opt along with a set of feasible configurations. For all machines i, we first construct a configuration \(C_i\) corresponding to this machine from \(\textsf {opt}_i\) as below.

Defining containers Consider the prefix of the schedule of this machine consisting only of the time period where all the tiny and small jobs assigned to that machine are scheduled (together with its idle time in between those jobs). Partition the job set assigned to this prefix into containers. Two jobs are assigned to the same container only if there is no unit length idle time between their starting times. By definition, \(\textsf {opt}_i \) has a unit idle time after every container and we add it to the container. If the makespan is at most \(1/\varepsilon \), the entire schedule of i is one container and we do not partition it further. Since opt is nice, the maximum load of a container is at most \(2/\varepsilon +1\). Let \(T_i\) be the set of containers generated from \(\textsf {opt}_i\).

partitioning each container into \(\varepsilon -\)block s Partition each container \(t\in T_i\) into \(\varepsilon -\)blocks and ignore the \(\varepsilon -\)blocks that belong to the \(\varepsilon -\)blocks of the unit idle time at the end of the container and the \(\varepsilon -\)blocks beyond the \(1/\varepsilon ^2\) blocks within the container (if there are such). For each \(\varepsilon -\)block k of t we define the following components of the sub-vector of t corresponding to k. First, let \(D_{kt}\) be so that \(\varepsilon ^2 D_{kt}\) is the idle time in k rounded down to the next integer multiple of \(\varepsilon ^2\). Second, let \( T_{kt} = \left\lfloor \frac{\sum p_j}{\varepsilon ^2}\right\rfloor \), where the summation is over the set of tiny jobs that start in k so \(T_{kt} \cdot \varepsilon ^2\) is the total size of tiny jobs assigned to k of t rounded down to the next integer multiple of \(\varepsilon ^2\). If there are no tiny jobs assigned to start in k then let \(T'_{kt}=0\) else \(T'_{kt}=1\). Third, for each distinct size of small jobs \(l\in \texttt{S}\) let \(S_{lkt}\) be the number of small jobs of size l that start in k of t. Last, set \(P_{kt}\) to be 1 if a job starts in an \(\varepsilon -\)block at most \(k-1\) and continues its processing also in the \(\varepsilon -\)block k, else it is 0. Based on these sub-vectors, we define the container t, and using this vector we define the load of the container.

Defining the configuration \(C_i\) corresponding to machine i. For each l, we count the number of long containers with load rounded to integer powers of \(1+\varepsilon \), l assigned to i. Denote it by \(\alpha _{il}\). We compute the total load of all short containers assigned to i and we round this value down to the next integer multiple of \(\varepsilon ^2\mathcal {C}_{max}^{nice}\). The resulting rounded value is \(\beta _i \varepsilon ^2 \mathcal {C}_{max}^{nice}\). If there are no short containers assigned to i then let \(\beta '_i = 0\), else \(\beta '_i =1\). For each \(l\in \texttt{L}\), count the number of large jobs of size l assigned to i and denote it by \(\gamma _{il}\). Calculate the total size of medium jobs assigned to i and round down the resulting value to the next integer multiple of \(\varepsilon ^2\mathcal {C}_{max}^{nice}\). Let \(\delta _i\) be such that this outcome is \(\delta _i \varepsilon ^2 \mathcal {C}_{max}^{nice}\). If there are no medium jobs assigned to i then let \(\delta '_i=0\) else \(\delta '_i=1\). This defines all components of a configuration that we denote by \(C_i\).

Feasibility of containers and configurations Let T be the multiset of all containers, and let C be the multiset of all configurations we have defined (over all machines). Next we check the feasibility of the containers generated. Create partial schedules from each container. Since a container was created by rounding down the total idle time and the total size of tiny jobs in \(\varepsilon -\)blocks with respect to opt, the number of jobs that continue their processing out of the corresponding \(\varepsilon -\)block does not increase (compared to opt). By the facts that at most one job continued its processing out of every \(\varepsilon -\)block in opt, and opt is a nice solution, we conclude that the partial schedule generated from every container will also have at most one job whose processing continues out of every \(\varepsilon -\)block. Thus, the containers generated are feasible. Consequently we get that the configurations in C are also feasible, since the containers are feasible and the load of each configuration is not increased while the configuration was generated from the schedule (with the rounding down involved) and if \(\mathcal {C}_{max}^{nice}\le 1/\varepsilon \) then the configuration consists of one long container and no other jobs or containers.

Defining the MILP solution Two configurations in C are identical if every parameter of the two configurations are identical. Let \(v_c\) for every feasible configuration c be the number of identical copies of configuration c in the multiset C (perhaps 0 if \(c\notin C\)). Thus now we have \({\textbf {v}}^{\textsf {opt}{}}\). Two containers are identical if every parameter of the two containers are identical. Let \(w_t\) for all feasible containers t be the number of identical copies of container t in the multiset T. Thus now we have \({\textbf {w}}^{\textsf {opt}{}}\). Identify the configurations to which each container is assigned to and obtain \({\textbf {z}}^{\textsf {opt}}\). Identify the \(\varepsilon -\)block and container to which every tiny job is assigned to start to obtain \({\textbf {y}}^{\textsf {opt}}\). Identify the configurations to which each medium job is assigned to obtain \({\textbf {x}}^{\textsf {opt}}\).

Proving that the MILP solution is feasible In order to prove the theorem it suffices to show that the generated MILP solution \(({\textbf {v}}^\textsf {opt},{\textbf {w}}^\textsf {opt},{\textbf {x}}^\textsf {opt},{\textbf {y}}^\textsf {opt},{\textbf {z}}^\textsf {opt})\) is feasible. From the definition of the MILP solution \(({\textbf {v}}^\textsf {opt},{\textbf {w}}^\textsf {opt},{\textbf {x}}^\textsf {opt},{\textbf {y}}^\textsf {opt},{\textbf {z}}^\textsf {opt})\), all of them are non-negative integers and \({\textbf {x}}^\textsf {opt}\) and \({\textbf {y}}^\textsf {opt}\) are binary vectors. Since each tiny job is assigned to start only in one \(\varepsilon -\)block of only one container of one machine, and similarly since each medium job is scheduled only to one machine, constraints (1) and (4) are satisfied. Consider a container \(t\in T\) with only one copy of t and an \(\varepsilon -\)block k of the container. Thus we have

$$\begin{aligned} T_{kt}&= \left\lfloor \sum _{j\in \texttt{TJ}}\frac{p_jy_{jkt}}{\varepsilon ^2}\right\rfloor \\ (T_{kt}+1)\varepsilon ^2&\ge \sum _{j\in \texttt{TJ}}p_jy_{jkt} \end{aligned}$$

Considering all copies of t for an arbitrary container we get

$$\begin{aligned} w_t (T_{kt}+1)\varepsilon ^2&\ge \sum _{j\in \texttt{TJ}}p_jy_{jkt}. \end{aligned}$$

Thus constraint (2) is satisfied as it is trivially satisfied if no tiny jobs are assigned to \(\varepsilon -\)block k of t. Constraint (3) is satisfied trivially from the definition of the variables. Consider a configuration \(c\in C\) with only one copy of c. Thus we have

$$\begin{aligned} \delta _c&= \left\lfloor \sum _{j\in \texttt{MJ}}\frac{x_{jc}p_j}{\varepsilon ^2\mathcal {C}_{max}^{nice}}\right\rfloor \\ (\delta _c+1)\varepsilon ^2\mathcal {C}_{max}^{nice}&\ge \sum _{j\in \texttt{MJ}}x_{jc}p_j \end{aligned}$$

Considering all copies of c for an arbitrary configuration we get

$$\begin{aligned} v_c (\delta _c+1)\varepsilon ^2\mathcal {C}_{max}^{nice}&\ge \sum _{j\in \texttt{MJ}}x_{jc}p_j. \end{aligned}$$

Thus constraint (5) is satisfied as it is trivially satisfied if no medium jobs are assigned to the configuration. If a container was generated from the schedule of a machine, then that container will be placed in only one configuration (of the same machine). Similarly, a large job will also be placed in only one configuration. Thus constraints (6), (7), (8), and (10) are satisfied. Recall that \(\mathtt {T_S}\) is the set of short containers. Consider a configuration c with only one copy of c, we have

$$\begin{aligned} \beta _c&= \left\lfloor \sum _{t\in \mathtt {T_S}}\frac{z_{ct}L_c}{\varepsilon ^2\mathcal {C}_{max}^{nice}}\right\rfloor \\ (\beta _c+1)\varepsilon ^2\mathcal {C}_{max}^{nice}&\ge \sum _{t\in \mathtt {T_S}}z_{ct}L_c \end{aligned}$$

Considering all the copies of c for an arbitrary configuration we get

$$\begin{aligned} v_c(\beta _c+1)\varepsilon ^2\mathcal {C}_{max}^{nice}&\ge \sum _{t\in \mathtt {T_S}}z_{ct}L_c. \end{aligned}$$

Thus constraint (9) is satisfied as it is trivially satisfied if no short container is assigned to c. Constraint (11) is satisfied since opt was a nice schedule and satisfied the modified time constraint. Constraint (12) is satisfied trivially since a configuration was generated from the schedule of each machine. Hence, the solution generated is feasible as required. \(\square \)

4 Rounding a MILP solution into a feasible schedule

Next we state the main claim regarding the performance guarantee of the Best-Fit schedule for scheduling with cardinality constraint (Chen et al. 2016, Lemma 2) which we use later in our algorithm (in their settings, \(c_k\in \mathbb {Z}_+\) is the capacity bound on machine k but here the use will be different).

Lemma 7

Assume that \(c_k\) is a non-negative integer for all k. If there is a feasible solution for the following linear system

$$\begin{aligned} \sum _{j=1}^{n} p_jy_{jk}&\le t_k,\ 1\le k\le m\\ \sum _{j=1}^{n} y_{jk}&= c_k, 1\le k\le m\\ \sum _{k=1}^{m} y_{jk}&= 1, 1\le j\le n\\ 0\le y_{jk}&\le 1, 1 \le j\le n,\ \ 1\le k\le m \end{aligned}$$

then an integer solution satisfying:

$$\begin{aligned} \sum _{j=1}^{n} p_jy_{jk}&\le t_k + p_{max},\ 1\le k\le m\\ \sum _{j=1}^{n} y_{jk}&= c_k,\ 1\le k\le m\\ \sum _{k=1}^{m} y_{jk}&= 1,\ 1\le j\le n\\ y_{jk} \in \{0,1\}, \ 1&\le j\le n,\ \ 1\le k\le m \end{aligned}$$

could be obtained in \(O(n\log n)\) time, where \(p_{\max }=\max _{j}\{p_j\}\).

We are now ready to show the algorithm for rounding the MILP solution and its analysis.

Theorem 2

If there exists a solution to the MILP for the rounded instance \(I'\) with the given guessed value \(\mathcal {C}_{max}^{nice}\), then there exists a feasible schedule to instance \(I'\) of cost at most \((1+10\varepsilon )\mathcal {C}_{max}^{nice}\) that can be obtained in polynomial time.

Proof

Let the MILP solution be denoted by sol and is given as \(({\textbf {v}},{\textbf {w}},{\textbf {x}},{\textbf {y}},{\textbf {z}})\). Let \(\texttt{C}\) be the set of feasible configurations and let \(\texttt{T}\) be the set of feasible containers corresponding to this value of \(\mathcal {C}_{max}^{nice}\). We create a schedule from sol, \(\texttt{T}\), and \(\texttt{C}\).

Assigning configurations to machines Assign the configurations with \(v_c>0\) in \(\texttt{C}\) to the machines in a way that every machine is assigned exactly one configuration and for every c, the number of machines whose assigned configuration is c will be exactly \(v_c\). By constraint (12), \(\sum _{c\in \texttt{C}}v_c = |M|\), this is indeed possible.

Assigning large jobs to machines We assign large jobs to each machine based on the positions available for each distinct size of large jobs in the configuration assigned to that machine. That is, for each size l of large jobs, if the configuration assigned to i has a given number of jobs of size l assigned to it, then i will be assigned exactly the same number of large jobs of that size. From constraint (6), we assign all the large jobs to the machines.

Assigning medium jobs For each machine we have the lower bound on the total size of the medium jobs that can be assigned on that machine based on the configuration assigned to the machine. This lower bound is given by \(\delta '_c\delta _c\varepsilon ^2\mathcal {C}_{max}^{nice}\). Since \(\delta _c\) was rounded down, we increase the space available for the medium jobs by \(\varepsilon ^2\mathcal {C}_{max}^{nice}\). By constraint (5), we have enough space to assign all the medium jobs fractionally. We increase the total space available on each machine for medium jobs by another additive term of \(\varepsilon \mathcal {C}_{max}^{nice}\). We assign the medium jobs in some order to machines in some order of the machines. In this sequential assignment, we move to the next machine if the medium job about to be assigned to the current machine will increase the total size of the medium jobs on the current machine beyond the space available on the current machine. Thus the total increase in makespan due to this step is at most \(\varepsilon ^2\mathcal {C}_{max}^{nice}+ \varepsilon \mathcal {C}_{max}^{nice}\le 2\varepsilon \mathcal {C}_{max}^{nice}\). This assignment of medium jobs will assign all these jobs due to the following reasons. Assume by contradiction that some medium jobs are left unassigned by this process. This means that whenever the procedure decided that some machine should stop being the current machine, the total size of medium jobs assigned to it will be at least \(\delta '_c(\delta _c+1)\varepsilon ^2\mathcal {C}_{max}^{nice}\) (this holds as the size of a medium job is not larger than \(\varepsilon \mathcal {C}_{max}^{nice}\)). Since every machine stops being the current machine at some point, we get a contradiction to constraint (5). So indeed this is a feasible assignment of medium jobs.

Assigning long containers to machines Long containers are assigned to the machines based on the positions available for each distinct rounded load of the long containers defined in the configuration assigned to the machine. The long containers of a common rounded load are assigned in an arbitrary order and from constraint (10) there are enough positions to assign all the long containers to the machines.

Assigning short containers to machines Based on the configurations of machines, we know a lower bound on the total load available for short containers on each machine. We increase this space by \(\varepsilon ^2\mathcal {C}_{max}^{nice}\) (the motivation for this increase is that the load bound of the short containers were rounded down). From constraint (9) we have enough space to assign fractionally all the short containers to the machines. We increase the total space available for short containers on each machine by another additive term of \(\varepsilon \mathcal {C}_{max}^{nice}\). Similarly to the assignment of medium jobs, we apply the following iterative assignment rule. We assign the short containers listed in some order to machines where machines are ordered in some order. We move to the next machine if the short container about to be assigned to the current machine will increase the total load of the short containers on the current machine beyond the space available to short containers on this machine. The increase in makespan is at most \(2\varepsilon \mathcal {C}_{max}^{nice}\). Once again, assume by contradiction that some short containers are left unassigned by this process. This means that whenever the procedure decided that some machine should stop being the current machine, the total load of short containers assigned to it is at least \(\beta '_c(\beta _c+1)\varepsilon ^2\mathcal {C}_{max}^{nice}\) (this holds as the load of a short container is not larger than \(\varepsilon \mathcal {C}_{max}^{nice}\)). Since every machine stops being the current machine at some point, we get a contradiction to constraint (9). So indeed this is a feasible assignment of short containers.

Ordering the containers and medium and large jobs assigned to each machine The containers assigned to the machines are sorted in non-decreasing order of load and are placed sequentially one after the other (starting at time 0). Recall that all containers contain a unit idle time at the end, and containers start and end at integer multiples of \(\varepsilon \). Next, starting at the end-point of the unit idle time of the last container assigned to the machine or at time 0 if there is no such container, we place the medium and large jobs. These jobs are assigned to the machine and placed in non-decreasing order of size sequentially without idle time between consecutive such jobs. This does not increase the load of any machine. That is, at this point in time we have a schedule of containers and medium and large jobs with makespan at most \((1+4\varepsilon ) \mathcal {C}_{max}^{nice}\).

Assigning small jobs to machines We consider the small jobs and positions for each distinct size of small jobs on each machine based on the containers assigned to that machine. The total positions available for each distinct size of small jobs on a machine is obtained by summing up all the positions available for that distinct size of small job over all \(\varepsilon -\)blocks over all the containers assigned to the machine. From constraint (3), we have enough positions to assign all the small jobs of each size of small jobs to the machines and the \(\varepsilon -\)blocks of the machines.

Assigning the tiny jobs We are left with the assignment of the tiny jobs. This is the most delicate part of our proof. In a nutshell we would like to use the MILP solution in order to define a fractional assignment of tiny jobs to \(\varepsilon -\)blocks that maintain the total size of these jobs (to be similar to those defined by the containers), and the capacity, that is, the fractional number of those jobs in each \(\varepsilon -\)block, and then to use the analysis of Best-Fit in Lemma 7. However, the main difficulty in this approach is that the capacity bounds used in that lemma should be integers whereas the fractional assignment of tiny jobs have fractional cardinalities and we should first round those cardinalities while enforcing the modified time constraint.

We define universal \(\varepsilon -\)blocks. The universal \(\varepsilon -\)blocks are common to all machines and every \(\varepsilon -\)block on some machine appear as one of those universal \(\varepsilon -\)block. We treat such universal \(\varepsilon -\)block as an ordered pair where the second component of the pair is the index of the machine and the first component is an index along the time horizon. Let \(\widetilde{U}\) be the set of values of the first components of the universal \(\varepsilon -\)blocks, and let \(U=\widetilde{U}\times M\) denote the set of all universal \(\varepsilon -\)blocks. Each \(\varepsilon -\)block k in a container t assigned to machine i corresponds to a \(u\in U\) with second component equal to i. We define \(T_{u}\), \(S_{lu}\), \(P_{u}\), and \(y_{ju}\) using \(T_{u} = T_{kt}\), \(S_{lu} = S_{lkt}\), \(P_{u} = P_{kt}\) and \(y_{ju} = y_{jkt}\) where u corresponds to an \(\varepsilon -\)block k of container t assigned to machine i.

The MILP solution implies that \(y_{jkt}\) amount of tiny job j is assigned to start in \(\varepsilon -\)block k of container t in total on \(w_t\) copies of container t. We define a temporary fractional assignment of tiny jobs that assigns \(\frac{y_{jkt}}{w_t}\) fraction of job j to start in \(\varepsilon -\)block k of each occurrence of container t. The number of tiny jobs that starts in each \(u\in U\) in this temporary fractional solution is \(\Omega _{u} = \sum _{j\in \texttt{TJ}}y_{jkt}/w_t\) where u corresponds to the \(\varepsilon -\)block k of container t assigned to machine i.

We will apply below the Best-Fit analysis to get integer assignments of tiny jobs. In order to apply it, for each \(u\in U\), we need integer capacity bound. Denote it by \(\Omega '_{u}\). We will have \(\Omega '_{u} = 0\) when \(\Omega _{u} = 0\). The remaining \(\Omega '\) values are obtained by using the LP below. The first constraint is used to round down or up the \(\Omega \) values (in order to not increase by too much the total size of tiny jobs in each \(\varepsilon -\)block in a new fractional assignment that we will construct). The second constraint enforces the modified time constraint while rounding the \(\Omega \) values. The third constraint ensures that there are enough positions to assign all the tiny jobs of the instance with the integer capacities.

$$\begin{aligned} \lfloor \Omega _{u}\rfloor&\le \ \Omega '_{u} \le \lfloor \Omega _{u}\rfloor +1,\ \forall u\in U\\ \sum _{u=(k,i)}^{(k+(1/\varepsilon ),i)} \Omega '_{u}&\le w_t \left( B - \sum _{u=(k,i)}^{(k+(1/\varepsilon ),i)} \sum _{l\in \texttt{S}}S_{lu} - P_{(k,i)}\right) ,\ \forall (k,i): k \text{ and } k+1/\varepsilon \\&\quad \text{ are } \text{ indexes } \text{ of } \varepsilon -block \text{ s } \text{ on } \text{ machine } i\\&\quad \text{ that } \text{ belong } \text{ to } \text{ a } \text{ common } \text{ container } t, \forall t\\ \sum _{u\in U}\Omega '_{u}&= |\texttt{TJ}| \end{aligned}$$
(LP)

LP has a feasible solution since \(\Omega _{u}\) for all u is a feasible solution. The constraint matrix of the given LP satisfies that in every row the 1’s appear consecutively for sorted list of the columns where we order the columns in a non-decreasing order of the machines (second component of u) and break ties in an increasing order of k (first component of u). That is, the constraint matrix satisfies the consecutive 1’s property, and so it is a totally unimodular matrix. Since the constraint matrix of LP is totally unimodular, the right hand side is integral, and there is a fractional feasible solution for LP, we conclude that there exists an integer solution to \(\Omega '_{u}\) that can be found in polynomial time by a basis crashing algorithm. We get integer capacity bound for tiny jobs, for each universal \(\varepsilon -\)block u. Denote by \(\underline{U}\subseteq U\) the subset of indexed universal \(\varepsilon -\)blocks that has an integer capacity bound that is rounded down with respect to the \(\Omega \) values and also those indexed universal \(\varepsilon -\)blocks that already had an integer capacity bound in \(\Omega \). Let \(\overline{U} = U\backslash \underline{U}\) be the subset of indexed universal \(\varepsilon -\)blocks that have integer capacity bounds that are rounded up and strictly larger than the \(\Omega \) values.

In order to create a feasible fractional assignment of the tiny jobs with respect to the integer capacity bounds, we perform the below operations to alter the y values. Let the altered y values be denoted by \(y'\). For each \(u\in \underline{U}\), perform the following transformation. Let

$$\begin{aligned} y'_{ju} = \frac{y_{ju}}{\Omega _u}\cdot \Omega '_u, \end{aligned}$$

Thus for u,

$$\begin{aligned} \sum _{j\in \texttt{TJ}} \frac{y'_{ju}}{w_t} = \sum _{j\in \texttt{TJ}} \frac{y_{ju}}{\Omega _uw_t}\cdot \Omega '_u = \Omega '_u, \end{aligned}$$

the \(y'\) values satisfy the integer capacity bound. This transformation may leave some fractions of jobs unassigned from \(u\in \underline{U}\). Merge the fractions of the common jobs to get the set of fractions Y for the unassigned jobs. For each \(u\in \overline{U}\) perform the following operations. Let

$$\begin{aligned} y'_{ju} = y_{ju}. \end{aligned}$$

In addition to these fractions, assign (fractionally) fractions from Y to u greedily till the total fraction of jobs in u is exactly \(\Omega '_u\), splitting a fraction of the same job when necessary. There is enough place to assign all the fractions in Y since

$$\begin{aligned} \sum _{u\in \underline{U}}\Omega '_u + \sum _{u\in \overline{U}}\Omega '_u = \sum _{u\in U}\Omega '_u = |\texttt{TJ}| = \sum _{j\in \texttt{TJ}}\sum _{t\in \texttt{T}}\sum _{k\in K_t} y_{jkt}, \end{aligned}$$

from LP and MILP. This transformation can increase the total size allocated to tiny jobs in each universal \(\varepsilon -\)block by at most \(\varepsilon ^2\). Furthermore, we apply Lemma 7 to assign integrally the tiny jobs to the universal \(\varepsilon -\)block and this increases the total size of tiny jobs in each universal \(\varepsilon -\)block by another additive term of \(\varepsilon ^2\). Thus, the new load of the schedule of a machine assigned configuration c is increased due to the assignment of tiny jobs by at most

$$\begin{aligned} 2(1+4\varepsilon ) \cdot \frac{\mathcal {C}_{max}^{nice}}{\varepsilon } \cdot \varepsilon ^2 \le 6 \varepsilon \mathcal {C}_{max}^{nice}. \end{aligned}$$

Thus the final value of the makespan of the schedule is at most \((1+10 \varepsilon )\mathcal {C}_{max}^{nice}\) and all the operations are done in polynomial time. \(\square \)

We conclude by the sequence of lemmas and theorems that our problem admits an EPTAS and thus the following corollary holds.

Corollary 1

Problem STS admits an EPTAS.

5 Concluding remarks

We presented an EPTAS for problem STS. Given that the problem is NP-hard in the strong sense, this result can be considered as best possible and it also improves the literature both by generalizing the special cases for which a PTAS was known as well as improving the complexity class of the scheme from a PTAS to an EPTAS. However, like many other such results in this regime of algorithms, the running time for a reasonable choice of \(\varepsilon \) would be very high. Thus, future studies of worst-case guarantees of natural heuristics for this problem may lead to interesting research directions.