**6. The General Framework for Problem** 1|*rj*|*L*max

In this section, we describe our main algorithmic framework which basic components form the binary search and the verification procedures. The framework is for the general setting 1|*rj*|*L*max (in the next section, we give an explicit condition when the framework guarantees the optimal solution of the problem). At every iteration in the binary search procedure, we intend to keep the delay of jobs from each partial schedule *S*∗[*K*], *K* ∈ K within the allowable margin determined by the current *Lδ*-boundary.

For a given threshold *Lδ*, we are concerned with the existence of a partial *Lδ*-schedule that includes all the jobs of schedule *S*∗[*K*] and probably some external jobs. We refer to such partial schedule as an *augmented Lδ-schedule* for kernel *K* and denote it by *SL<sup>δ</sup>* [*K*] (we specify the scope of that schedule more accurately later in this section).

Due to the allowable maximum job lateness of *<sup>L</sup><sup>δ</sup>* <sup>≥</sup> *<sup>L</sup>*opt in schedule *<sup>S</sup>L<sup>δ</sup>* [*K*], in the case that the earliest scheduled job of kernel *K*∗ gets pushed by some (external) job *l* <sup>∗</sup> in schedule *SL<sup>δ</sup>* [*K*], that job will be considered as the delaying emerging job iff

$$c\_{l^\*}\left(S^L[K]\right) \ge r(K^\*) + \delta(K^\*) + \delta.$$

For a given threshold *L* = *Lδ*, the allowable *L*-*bias* for jobs of kernel *K*<sup>∗</sup> in schedule *SL*[*K*]

$$\beta\_L(K^\*) = L - L\_{\text{max}}(K^\*). \tag{11}$$

The intuition behind this definition is that the jobs of kernel *K*∗ in schedule *S*∗[*K*] can be right-shifted by *βL*(*K*∗) time units without surpassing the *L*-boundary (see Proposition 9 below).

**Proposition 9.** *In an L-schedule SL, all the jobs of schedule S*∗[*K*] *are included in the interval of schedule S*∗[*K*]*. Furthermore, any job in S*∗[*K*] \ *K*<sup>∗</sup> *can be right-shifted provided that it remains scheduled before the jobs of kernel K*∗*, whereas the jobs from kernel K*<sup>∗</sup> *can be right-shifted by at most βL*(*K*∗)*.*

**Proof.** Let *j* be the earliest scheduled job of atomic kernel *K*∗ in schedule *S*∗[*K*]. By right-shifting job *j* by *βL*(*K*∗) time units (Equation (11)) we get a new (partial) schedule *S* in which all the jobs are delayed by *βL*(*K*∗) time units with respect to schedule *S*∗[*K*] (note that the processing order of the jobs of atomic kernel *K*∗ need not be altered in schedule *S* as the jobs of kernel *K*∗ are scheduled in ED-order in schedule *S*∗[*K*]). Hence,

$$\max\_{i \in \mathcal{S}^\*[K]} L\_i(\mathcal{S}^\prime) \le \max\_{i \in \mathcal{S}^\*[K]} \{ L\_i(\mathcal{S}^\*[K]) + \beta\_L(K^\*) \} = \max\_{i \in \mathcal{S}^\*[K]} \{ L\_i(\mathcal{S}^\*[K]) \} + \beta\_L(K^\*).$$

By substituting for *<sup>β</sup>L*(*K*∗) using Equation (11) and applying that max*i*∈*S*∗[*K*]{*Li*(*S*∗[*K*])} = *L*max(*K*∗), we obtain

$$\max\_{i \in S^\*[K]} L\_i(S^\prime) \le L\_{-}$$

Hence, the lateness of any job of atomic kernel *K*∗ is no more than *L*. Likewise, any other job from schedule *S*∗[*K*] can be right-shifted within the interval of *S*∗[*K*] without surpassing the magnitude *L*max(*K*∗) ≤ *L* given that it is included before the jobs of kernel *K*<sup>∗</sup> (see the proof of Lemma 4).

#### *6.1. Partitioning the Scheduling Horizon into the Bin and Kernel Segments*

By Proposition 9, all jobs from the atomic kernel *K*∗ are to be included with a possible delay (right-shift) of at most *βL*(*K*∗) in *L*-schedule *SL*. The rest of the jobs from schedule *S*∗[*K*] are to "dispelled" before the jobs of *K*∗ within the interval of that schedule. Since schedule *S*∗[*K*] contains the gaps, some additional external jobs may also be included within the same time interval. According to this observation, we partition every complete feasible *L*-schedule into two types of segments, rigid and flexible ones. The rigid segments are to be occupied by the atomic kernels, and the rest of the (flexible) segments, which are called *bin* segments or intervals, are left for the rest of the jobs (we use term bin for both, the corresponding time interval and for the corresponding schedule portion interchangeably). For simplicity, we refer to the segments corresponding to the atomic kernels as kernel segments or intervals.

In general, we have a bin between two adjacent kernel intervals, and a bin before the first and after the last kernel interval. Because of the allowable right-shift *βL*(*K*∗) for the jobs of an atomic kernel *K*∗, the starting and completion times of the corresponding kernel and bin intervals are not priory fixed. We denote by *B*−(*K*) (*B*+(*K*), respectively) the bin before (after, respectively) the kernel interval corresponding to the atomic kernel *K*<sup>∗</sup> of kernel *K*. There are two bins in schedule *σl*,3,2, surrounding the atomic kernel consisting of Job 1 in Figure 6. We have three bins in schedules depicted in

Figures 8 and 9 for the problem instance of Example 2, *B*<sup>1</sup> = *B*−(*K*1), *B*<sup>2</sup> = *B*+(*K*1) = *B*−(*K*2) and *B*<sup>3</sup> = *B*+(*K*2) (schedule of Figure 9 incorporates an optimal arrangement of jobs in these bins).

 - -

**Figure 9.** An optimal *L*-schedule for Example 2 with three bins (*L* = *L*∗ max = 4).

The scope of augmented *L*-schedule *SL*[*K*] for kernel *K* includes that of bin *B*−(*K*) and that of the atomic kernel *K*∗. These two parts are scheduled independently. The construction of second part relies on the next proposition that easily follows from Proposition 9:

**Proposition 10.** *No job of the atomic kernel K*∗ *will surpass the L-boundary if the latest scheduled job of bin B*−(*K*) *completes no later than at time moment*

$$
\psi\_L(K) = r(K^\*) + \beta\_L(K^\*) \tag{12}
$$

*(the latest time moment when atomic kernel K*∗ *may start in an L-schedule) and the jobs of that kernel are scheduled by ED-heuristics from time moment ψL*(*K*)*.*

We easily arrange the second part of augmented schedule *SL*[*K*], i.e., one including the atomic kernel *K*∗, as specified in Proposition 10. Hence, from here on, we are solely concerned with the construction of the the first part, i.e., that of bin *B*−(*K*), which is a complicated task and basically contributes to the complexity status of problem 1|*rj*|*L*max.

We refer to a partial feasible *L*-schedule for the first part of schedule *SL*[*K*] (with its latest job completion time not exceeding the magnitude *ψL*(*K*), at which the second part initiates) as a *preschedule* of kernel *K* and denote it by *PreS*(*K*). Note that the time interval of preschedule *PreS*(*K*) coincides with that of bin *B*−(*K*); in this sense, *PreS*(*K*) is a schedule for bin *B*−(*K*).

Kernel preschedules are generated in Phase 1, described in Section 7. If Phase 1 fails to construct an *L*-preschedule for some kernel, then Phase 2 described in Section 9 is invoked (see Proposition 12 in Section 5). Phase 2 basically uses the construction procedure of Phase 1 for the new problem instances that it derives.

#### 6.1.1. The Main Partitioning Procedure

Now, we describe the main procedure (PROCEDURE MAIN) of our algorithm, that is in charge of the partitioning of the scheduling horizon into the kernel and the corresponding bin intervals. This partition is dynamically changed and is updated in a recurrent fashion each time a new kernel arises. The occurrence of each new kernel *K* during the construction of a bin, the split of this bin into smaller bins and the collapsing of kernel *K* induce the recurrent nature in our method (not surprising, the recurrence is a common feature in the most common algorithmic frameworks such are dynamic programming and branch-and-bound).

Invoked for kernel *K* (*K* is a global variable), PROCEDURE MAIN first calls PROCEDURE Decomposition(*S*, *K*, *l*) that forms schedule *S*∗[*K*] ending with the atomic kernel *K*∗ (see the beginning of Section 5 and Propositions 5 and 9).

PROCEDURE MAIN incorporates properly kernel *K* into the current partition updating respectively the current *configuration* C(*δ*, *K*) defined by a trial *δ*, the current set of kernels K together with the corresponding *<sup>δ</sup>*(*M*∗)s (see Equation (7)) and the augmented schedules *<sup>S</sup>L<sup>δ</sup>* [*M*], for *<sup>M</sup>* ∈ K, constructed so far.

Given trial *δ* and kernel *K*, the configuration C(*δ*, *K*) is unique, and there is a unique corresponding schedule <sup>Σ</sup>C(*δ*,*K*) with *<sup>K</sup>* = *<sup>K</sup>*(ΣC(*δ*,*K*)) that includes the latest generated (so far) augmented schedules *<sup>S</sup>L<sup>δ</sup>* [*M*], *<sup>M</sup>* ∈ K.

PROCEDURE MAIN starts with the initial configuration C(Δ, *<sup>K</sup>*) with *<sup>δ</sup>* = <sup>Δ</sup>, *<sup>K</sup>* = *<sup>K</sup>*(*σ*), <sup>Σ</sup>C(Δ,*K*) = *σ* and K = ∅ (no bin exists yet in that configuration).

Iteratively, PROCEDURE MAIN, invoked for kernel *K*, creates a new configuration C(Δ, *K*) with two new surrounding bins *B*−(*K*) and *B*+(*K*) and the atomic kernel *K*<sup>∗</sup> in between these bins. These bins arise within a bin of the previous configuration (the later bin disappears in the updated configuration). Initially, atomic kernel (*K*(*σ*))<sup>∗</sup> splits schedule *σ* in two bins *B*−(*K*(*σ*)) and *B*+(*K*(*σ*)).

Two (atomic) kernels in schedule <sup>Σ</sup>C(*δ*,*K*) are *tied* if they belong to the same block in that schedule. Given configuration C(*δ*, *K*), the longest sequence of the augmented *L*-schedules of the pairwise tied kernels in schedule <sup>Σ</sup>C(*δ*,*K*) is called a *secondary block*.

We basically deal with the secondary block containing kernel *K* and denote it by B*<sup>K</sup>* (we may omit argument *K* when this is not important). An essential characteristic of a secondary block is that every job that pushes a job from that secondary block belongs to the same secondary block. Therefore, the configuration update in PROCEDURE MAIN can be carried out solely within the current secondary block B*K*.

As we show below, PROCEDURE MAIN will create an *L*-schedule for an instance of 1|*pj* : *divisible*,*rj*|*L*max whenever it exists (otherwise, it affirms that no *L*-schedule for that instance exists). The same outcome is not guaranteed for an instance of 1|*rj*|*L*max, in general. In Theorem 3, we give an explicit condition under which an *L*-schedule for an instance of 1|*rj*|*L*max will always be created, yielding a polynomial-time solution for the general setting. Unfortunately, if the above condition is not satisfied, we cannot, in general, affirm that there exists no feasible *L*-augmented schedule, even if our framework fails to find it for an instance of problem 1|*rj*|*L*max.

#### 6.1.2. PROCEDURE AUGMENTED(*K*, *δ*), Rise of New Kernels and Bin Split

PROCEDURE MAIN uses PROCEDURE AUGMENTED(*K*, *δ*) as a subroutine. PROCEDURE AUGMENTED(*K*, *δ*), called for kernel *K* with threshold *Lδ*, is in charge of the creation of an *<sup>L</sup>δ*-augmented schedule *<sup>S</sup>L<sup>δ</sup>* [*K*] respecting the current configuration <sup>C</sup>(*δ*, *<sup>K</sup>*). PROCEDURE AUGMENTED(*K*, *δ*) constructs the second part of schedule *SL<sup>δ</sup>* [*K*] (one including the atomic kernel *K*∗) directly as specified in Proposition 10. The most time consuming part of PROCEDURE AUGMENTED(*K*, *δ*) is that of the construction of the preschedule *PreS*(*K*) of schedule *SL<sup>δ</sup>* [*K*]. This construction is carried out at Phase 1 described in Section 7.

After a call of PROCEDURE AUGMENTED(*K*, *δ*), during the construction of an *L*-preschedule *PreS*(*K*) at Phase 1, a new kernel *K* may arise (the reader may have a look at Proposition 12 and Lemma 5 from the next section). Then, PROCEDURE AUGMENTED(*K*, *δ*) returns the newly arisen kernel *K* and PROCEDURE MAIN, invoked for that kernel, updates the current configuration. Since the rise of kernel *K* splits the earlier bin *B*−(*K*) into two new surrounding bins *B*−(*K* ) and *B*+(*K* ) = *B*−(*K*) of the new configuration, the bin *B*−(*K*) of the previous configuration disappears and is "replaced" by a new bin *B*−(*K*) = *B*+(*K* ) of the new configuration. Correspondingly, the scope of a preschedule for kernel *K* is narrowed (the former bin *B*−(*K*) is "reduced" to the newly arisen bin *B*+(*K* ) = *B*−(*K*)).

In this way, as a result of the rise of a new kernel within the (current) bin *B*−(*K*) and the resultant bin split, PROCEDURE AUGMENTED(*K*, *δ*) may be called more than once for different (gradually decreasing in size) bins: The initial bin *B*−(*K*) splits into two bins, the resultant new smaller bin *B*−(*K*) may again be split, and so on. Thus, to the first call of PROCEDURE AUGMENTED(*K*, *δ*) the largest bin *B*−(*K*) corresponds, and the interval of the new arisen bin for every next call of the procedure is a proper sub-interval of that of the bin corresponding to the previous call of the procedure. Note that each next created preschedule is composed of the jobs from the corresponding bin.

PROCEDURE AUGMENTED(*K*, *δ*) has three outcomes. If no new kernel during the construction of preschedule *PreS*(*K*) respecting the current configuration arises, the procedure completes with the successful outcome generating an *L*-augmented schedule *SL<sup>δ</sup>* [*K*] respecting the current configuration (in this case, schedule *SL<sup>δ</sup>* [*K*] may form part of the complete *L*-augmented schedule if the later schedule exists). PROCEDURE MAIN incorporates *Lδ*-augmented schedule *SL<sup>δ</sup>* [*K*] into the current configuration (the first IF statement in the iterative step in the description of the next subsection).

With the second outcome, a new kernel *K* during the construction of preschedule *PreS*(*K*) within bin *B*−(*K*) arises (Proposition 12 and Lemma 5). Then, PROCEDURE AUGMENTED(*K*, *δ*) returns kernel *K* and PROCEDURE MAIN is invoked for this newly arisen kernel and it updates the current configuration, respectively (see the iterative step in the description). Then, PROCEDURE MAIN calls recursively PROCEDURE AUGMENTED(*K* , *δ*) for kernel *K* and the corresponding newly arisen bin *B*−(*K* ) (this call is now in charge of the generation of an *L*-preschedule *PreS*(*K* ) for kernel *K* , see the second IF statement in the iterative step of the description in the next subsection).

With the third (failure) outcome, Phase 1 (invoked by PROCEDURE AUGMENTED(*K*, *δ*) for the creation of an *L*-preschedule *PreS*(*K*)) fails to create an *L*-preschedule respecting the current configuration (an IA(b2), defined in the next section, occurs (see Proposition 12). In this case, PROCEDURE MAIN invokes Phase 2. Phase 2 is described in Section 9. Nevertheless, the reader can see a brief description of that phase below:

Phase 2 uses two subroutines, PROCEDURE sl-SUBSTITUTION(*K*) and PROCEDURE ACTIVATE(*s*), where *s* is an emerging job. PROCEDURE sl-SUBSTITUTION(*K*) generates modified configurations with an attempt to create an *L*-preschedule *PreS*(*K*) respecting a newly created configuration, in which some preschedules of the kernels, preceding kernel *K* in the secondary block B*<sup>K</sup>* are reconstructed. These preschedules are reconstructed by the procedure of Phase 1, which is called by PROCEDURE ACTIVATE(*s*). PROCEDURE ACTIVATE(*s*), in turn, is repeatedly called by PROCEDURE sl-SUBSTITUTION(*K*) for different emerging jobs in the search of a proper configuration (each call of PROCEDURE ACTIVATE(*s*) creates a new configuration by a call of Phase 1). If at Phase 2 a configuration is generated for which Phase 1 succeeds to create an *L*-preschedule *PreS*(*K*) respecting that configuration (the successful outcome), the augmented *L*-schedules corresponding to the reconstructed preschedules remain incorporated into the current schedule <sup>Σ</sup>C(*δ*,*K*).

#### 6.1.3. Formal Description of PROCEDURE MAIN

The formal description of PROCEDURE MAIN below is completed by the descriptions of Phases 1 and 2 in the following sections. For notation simplicity, in set operations, we use schedule notation for the corresponding set of jobs. Given a set of jobs *A*, we denote by *ED*(*A*) the ED-schedule obtained by the application of ED-heuristics to the jobs of set *A*.

Whenever a call of PROCEDURE MAIN for kernel *K* creates an augmented *L*-schedule *<sup>S</sup>L<sup>δ</sup>* [*K*], the procedure completes secondary block <sup>B</sup>*<sup>K</sup>* by merely applying ED-heuristics to the remaining available jobs, ones to be included in that secondary block; i.e., partial ED-schedule *ED*(B*<sup>K</sup>* \ ∪*M*∈B*<sup>K</sup>* {*SL<sup>δ</sup>* [*M*]}) is generated and is merged with the already created part of block <sup>B</sup>*<sup>K</sup>* to complete the block (the rest of the secondary blocks are left untouched in the updated schedule <sup>Σ</sup>C(*δ*,*K*)).

PROCEDURE MAIN returns *Lδ*-schedule with the minimal *δ*, which is optimal by Lemma 8.

#### PROCEDURE MAIN

*Initial step:* {Determine the initial configuration C(Δ, *K*), *K* = *K*(*σ*)}

Start the binary search with trial *δ* = Δ

{see Equation (9) and the inequality in Equation (10)}

<sup>Σ</sup>C(Δ,*K*) := *<sup>σ</sup>*

{initialize the set of kernels}

*K* := *K*(*σ*); K := *K*

{set the initial lower bound and the initial allowable delay for kernel *K*}

*L*∗ max := *L*max(*K*∗); *δ*(*K*∗) := 0

IF schedule *σ* contains no kernel with the delaying emerging job, output *σ* and halt {*σ* is optimal by Proposition 1}

*Iterative step:*

{Update the current configuration C(*δ*, *<sup>K</sup>*) with schedule <sup>Σ</sup>C(*δ*,*K*) as follows:}

{update the current set of kernels}

K := K ∪ *K*;

{update the current lower bound}

*L*∗ max := max{*L*<sup>∗</sup> max, *L*max(*K*∗)};

{update the corresponding allowable kernel delays (see Equation (7))}

*δ*(*M*∗) := *L*∗ max − *L*max(*M*∗), for every kernel *M* ∈ K

Call PROCEDURE AUGMENTED(*K*, *δ*) {construct an *Lδ*-augmented schedule *SL<sup>δ</sup>* [*K*]} IF during the execution of PROCEDURE AUGMENTED(*K*, *δ*) a new kernel *K* arises

{update the current configuration according to the newly arisen kernel}

THEN *K* := *K* ; repeat *Iterative step*

IF the outcome of PROCEDURE AUGMENTED(*K*, *δ*) is failure THEN call Phase 2 {at Phase 2 new configuration is looked for such that there exist preschedule *PreS*(*K*) respecting that configuration, see Section 9}

IF *Lδ*-augmented schedule *SL<sup>δ</sup>* [*K*] is successfully created {the outcome of PROCEDURE AUGMENTED(*K*, *δ*) and that of Phase 2 is successful, hence complete secondary block B*<sup>K</sup>* by ED-heuristics if there are available jobs which were not included in any of the constructed augmented schedules, i.e., <sup>B</sup>*<sup>K</sup>* \ ∪*M*∈B*<sup>K</sup>* {*SL<sup>δ</sup>* [*M*]} <sup>=</sup> <sup>∅</sup>}

THEN update block B*<sup>K</sup>* and schedule <sup>Σ</sup>C(*δ*,*K*) by merging it with partial ED-schedule

*ED*(B*<sup>K</sup>* \ ∪*M*∈B*<sup>K</sup>* {*SL<sup>δ</sup>* [*M*]})

(leave in the updated schedule <sup>Σ</sup>C(*δ*,*K*) the rest of the secondary blocks as they are)

IF (the so updated) schedule <sup>Σ</sup>C(*δ*,*K*) is an *<sup>L</sup>δ*-schedule

{continue the binary search with the next trial *δ*}

THEN *δ* :=the next trial value and repeat *Iterative step*; return the generated *Lδ*-schedule with the minimum *δ* and halt if all the trial *δ*s were already considered

ELSE {there is a kernel with the delaying emerging job in schedule <sup>Σ</sup>C(*δ*,*K*)}

*<sup>K</sup>* := *<sup>K</sup>*(ΣC(*δ*,*K*)); repeat *Iterative step*

IF *Lδ*-augmented schedule *SL<sup>δ</sup>* [*K*] could not been created

{the outcome of Phase 2 is failure and hence there exists no *Lδ*-schedule; continue the binary search with the next trial *δ*}

THEN *δ* := the next trial value and repeat *Iterative step*; return the generated *Lδ*-schedule with the minimum *δ* and halt if all the trial *δ*s were already considered.

### **7. Construction of Kernel Preschedules at Phase 1**

At Phase 1, we distinguish two basic types of the available (yet unscheduled) jobs which can feasibly be included in bin *B*−(*K*), for every *K* ∈ K. Given a current configuration, we call jobs that can only be scheduled within bin *B*−(*K*) y-jobs; we call jobs which can also be scheduled within some succeeding bin(s) the *x-jobs* for bin *B*−(*K*) or for kernel *K*. In this context, y-jobs have higher priority.

We have two different types of the y-jobs for bin *B*−(*K*). The set of the *Type (a)* y-jobs is formed by the jobs in set *K* \ *K*<sup>∗</sup> and yet unscheduled jobs not from kernel *K* released within the interval of bin *B*−(*K*). The rest of the y-jobs are ones released before the interval of bin *B*−(*K*), and they are referred to as the *Type (b)* y-jobs.

Recall that the interval of bin *B*−(*K*) begins right after the atomic kernel of the preceding bin (or at min*<sup>i</sup> ri* if *K* is the earliest kernel in K) and ends with the interval of schedule *S*∗[*K*]. The following proposition immediately follows:

**Proposition 11.** *Every x-job for bin B*−(*K*) *is an external job for kernel K, and there may also exist the external y-jobs for that kernel. A Type (a) y-job can feasibly be scheduled only within bin B*−(*K*)*, whereas Type (b) y-jobs can potentially be scheduled within a preceding bin (as they are released before the interval of bin B*−(*K*)*).*

Phase 1 for the construction of preschedule *PreS*(*K*) of kernel *K* consists of two passes. In Pass 1 y-jobs of bin *B*−(*K*) are scheduled. In Pass 2, x-jobs of bin *B*−(*K*) are distributed within that bin. We know that all Type (a) y-jobs can be feasibly scheduled within bin *B*−(*K*) without surpassing the *L*-boundary (since they were so scheduled in that bin), and these jobs may only be feasibly scheduled within that bin. Note that, respecting the current configuration with the already created augmented schedules for the kernels in set K), we are forced to include, besides Type (a) y-jobs, also all the Type (b) y-jobs into bin *B*−(*K*). If this does not work at Phase 1 in the current configuration, we try to reschedule some Type (b) y-jobs to the earlier bins in Phase 2 by changing the configuration.

#### *7.1. Pass 1*

Pass 1 consists of two steps. In Step 1, ED-heuristics is merely applied to all the y-jobs for scheduling bin *B*−(*K*).

If the resultant ED-schedule *PreS*(*K*, *y*) is a feasible *L*-schedule (i.e., no job in it surpasses the current *L*-boundary and/or finishes after time *ψL*(*K*)), Step 1 completes with the successful outcome and Pass 1 outputs *PreS*(*K*, *y*) (in this case, there is no need in Step 2), and Phase 1 continues with Pass 2 that augments *PreS*(*K*, *y*) with x-jobs, as described in the next subsection.

If schedule *PreS*(*K*, *y*) is not an *L*-schedule (there is a y-job in that schedule surpassing the *L*-boundary), *Pass 1* continues with Step 2.

Proposition 12 specifies two possible cases when preschedule *PreS*(*K*, *y*) does not contain all the y-jobs for bin *B*−(*K*), and Step 1 fails to create an *L*-preschedule for kernel *K* at the current configuration.

**Proposition 12.** *Suppose PreS*(*K*, *y*) *is not a feasible L-schedule, i.e., there arises a y-job surpassing the current L-boundary and/or completing after time ψL*(*K*)*.*

*(1) If there is a Type (b) y-job surpassing the L-boundary, then there exists no feasible partial L-preschedule for kernel K containing all the Type (b) y-jobs for this kernel (hence there is no complete feasible L-schedule respecting the current configuration).*

*(2) If there is a Type (a) y-job y surpassing the L-boundary and there exists a feasible partial L-preschedule for kernel K containing all the y-jobs, it contains a new kernel consisting of some Type (a) y-jobs including job y.*

**Proof.** We first show Case (2). As already mentioned, all Type (a) y-jobs may potentially be included in bin *B*−(*K*) without surpassing the *L*-boundary and be completed by time *ψL*(*K*) (recall Equation (12)). Hence, since *y* is a Type (a) y-job, it should have been pushed by at least one y-job *i* with *di* > *dy* in preschedule *PreS*(*K*, *y*). Then, there exists the corresponding kernel with the delaying emerging y-job (containing job *y* and possibly other Type (a) y-jobs).

Now, we prove Case (1). Let *y* be a Type (b) y-job that was forced to surpass the *L*-boundary and/or could not be completed by time moment *ψL*(*K*). In the latter case, ED-heuristics could create no gap in preschedule *PreS*(*K*, *y*) as all the Type (b) y-jobs were released from the beginning of the construction, and Case (1) obviously follows. In the former case, job *y* is clearly pushed by either another Type (b) y-job or a Type (a) y-job. Let *k* be a job pushing job *y*. Independently of whether *k* is a Type (a) or Type (b) y-job, since job *y* is released from the beginning of the construction and job *k* was included ahead job *y*, by ED-heuristics, *dk* ≤ *dy*. Then, no emerging job for job *y* may exist in preschedule *PreS*(*K*, *y*) and Case (1) again follows as all the Type (a) y-jobs must be included before time *ψL*(*K*).

For convenience, we refer to Case (1) in Proposition 12 as an *instance of Alternative (b2)* (IA(b2) for short) with Type (b) y-job *y* (we let *y* be the latest Type (b) y-job surpassing the *L*-boundary and/or completing after time *ψL*(*K*)). (The behavior alternatives were introduced in a wider context earlier in [13].) If an IA(b2) in bin *B*−(*K*) arises and there exists a complete *L*-schedule, then, in that schedule, some Type (b) y-job(s) from bin *B*−(*K*) is (are) included within the interval of some bin(s) preceding bin *B*−(*K*) in the current secondary block B*<sup>K</sup>* (we prove this in Proposition 16 in Section 7).

In *Step 2*, Cases (1) and (2) are dealt with as follows. For Case (1) (an IA(b2)), Step 2 invokes PROCEDURE sl-SUBSTITUTION(*K*) of Phase 2. PROCEDURE sl-SUBSTITUTION(*K*) creates one or more new (temporary) configurations, as described in Section 7. For every created configuration, it reconstructs some bins, preceding bin *B*−(*K*) in the secondary block B*<sup>K</sup>* incorporating some Type (b) y-jobs for bin *B*(*K*) into the reconstructed preschedules. The purpose of this is to find out if there exists an *L*-preschedule *PreS*(*K*) respecting the current configuration and construct it if it exists.

For Case (2) in Proposition 12, Step 2 returns the newly arisen kernel *K* and PROCEDURE MAIN is invoked with that kernel, which updates the current configuration respectively. PROCEDURE MAIN then returns the call to PROCEDURE AUGMENTED(*K* , *δ*) (see the description of Section 4) (note that, since PROCEDURE AUGMENTED(*K* , *δ*) invokes *Phase 1* now, for kernel *K* , Case (2) yields recursive calls of Phase 1).

#### *7.2. Pass 2: DEF-Heuristics*

If Pass 1 successfully completes, i.e., creates a feasible *L*-preschedule *PreS*(*K*¯, *y*), Pass 2, described in this subsection, is invoked (otherwise, IA(b2) with a Type (b) y-job from bin *B*−(*K*) arises and Phase 2 is invoked). Throughout this section, *PreS*(*K*, *y*) stands for the output of Pass 1 containing all the y-jobs for bin *B*−(*K*). At Pass 2, the x-jobs released within the remaining available room in preschedule *PreS*(*K*, *y*) are included by a variation of the *Next Fit Decreasing* heuristics, adopted for our scheduling problem with job release times. We call this variation *Decreasing Earliest Fit* heuristics, DEF-heuristics for short. It works with a *list* of x-jobs for kernel *K* sorted in non-increasing order of their processing times, the ties being broken by sorting jobs with the same processing time in the non-decreasing order of their due-dates.

DEF-heuristics, iteratively, selects next job *x* from the list and initially appends this job to the current schedule *PreS*(*K*, *y*) by scheduling it at the earliest idle-time moment *t* before time *ψL*(*K*) (any unoccupied time interval in bin *B*−(*K*) before time *ψL*(*K*) is an idle-time interval in that bin). Let *PreS*(*K*, *y*, +*x*) be the resultant partial schedule, that is obtained by the application of ED-heuristics from time moment *t* to job *x* and to the following y-jobs from schedule *PreS*(*K*, *y*) which may possibly right-shifted in schedule *PreS*(*K*, *y*, +*x*)) (compared to their positions in schedule *PreS*(*K*, *y*)). In the description below, the assignment *PreS*(*K*, *y*) := *PreS*(*K*, *y*, +*x*) updates the current partial schedule *PreS*(*K*, *y*) according to the rearrangement in schedule *PreS*(*K*, *y*, +*x*), removes job *x* from the list and assigns to variable *x* the next x-job from the list.

PROCEDURE DEF(*PreS*(*K*, *y*), *x*)

IF job *x* completes before or at time *ψL*(*K*) in schedule *PreS*(*K*, *y*, +*x*) {i.e., *t* + *px* falls within the current bin}

THEN GO TO Step (A) {verify the conditions in Steps (A) and (B)}

ELSE remove job *x* from the list {job *x* is ignored for bin *B*−(*K*)}; set *x* to the next job from the list; CALL PROCEDURE DEF(*PreS*(*K*, *y*), *x*)

(A) IF job *x* does not push any y-job in schedule *PreS*(*K*, *y*, +*x*) {*x* can be scheduled at time moment *t* without the interference with any y-job, i.e., *t* + *px* is no greater than the starting time of the next y-job in preschedule *PreS*(*K*, *y*)} and it completes by time moment *ψL*(*K*) in schedule *PreS*(*K*, *y*, +*x*)

THEN *PreS*(*K*, *y*) := *PreS*(*K*, *y*, +*x*); CALL PROCEDURE DEF(*PreS*(*K*, *y*), *x*)

(B) IF job *x* pushes some y-job in schedule *PreS*(*K*, *y*, +*x*)

THEN {verify the conditions in Steps (B.1)–(B.3)}

(B.1) IF in schedule *PreS*(*K*, *y*, +*x*) no (right-shifted) y-job surpasses *L*-boundary and all the jobs are completed by time moment *ψL*(*K*)

THEN *PreS*(*K*, *y*) := *PreS*(*K*, *y*, +*x*); CALL PROCEDURE DEF(*PreS*(*K*, *y*), *x*)

(B.2) IF in schedule *PreS*(*K*, *y*, +*x*) some y-job completes after time moment *ψL*(*K*)

THEN set *x* to the next x-job from the list and CALL PROCEDURE DEF(*PreS*(*K*, *y*), *x*). We need the following auxiliary lemma before we describe Step (B.3):

**Lemma 5.** *If a (right-shifted) y-job surpasses L-boundary in schedule PreS*(*K*, *y*, +*x*)*, then there arises a new kernel in that schedule (in bin B*−(*K*)*) consisting of solely Type (a) y-jobs, and x is the delaying emerging job of that kernel.*

**Proof.** Obviously, by the condition in the lemma, there arises a new kernel in schedule *PreS*(*K*, *y*, +*x*), call it *K* , and it consists of y-jobs following job *x* in schedule *PreS*(*K*, *y*, +*x*). Clearly, *x* is the delaying emerging job of kernel *K* . Such a right-shifted job *y* cannot be of Type (b) as otherwise it would have been included within the idle-time interval (occupied by job *x*) at Pass 1. Hence, kernel *K* consists of only Type (a) y-jobs.

Due to the above lemma, PROCEDURE DEF continues as follows:

(B.3) IF in schedule *PreS*(*K*, *y*, +*x*) the lateness of some (right-shifted) y-job exceeds *L*

THEN return the newly arisen kernel *K* and invoke PROCEDURE MAIN with kernel *K* {this updates the current configuration respectively and makes a recursive call of Phase 1 now for kernel *K* }

IF the list is empty THEN OUTPUT(*PreS*(*K*, *y*)) and halt.

This completes the description of Pass 2 and that of Phase 1.

From here on, we let *PreS*(*K*) = *PreS*(*K*, *y*, *x*) be the output of Phase 1 (a feasible *L*-preschedule for kernel *K* containing all the y-jobs for bin *B*−(*K*)). An easily seen property of PROCEDURE DEF and preschedule *PreS*(*K*, *y*, *x*) is summarized in the following proposition.

**Proposition 13.** *An L-preschedule cannot be obtained by replacing any x-job x* ∈ *PreS*(*K*, *y*, *x*) *with a longer available x-job in preschedule PreS*(*K*, *y*, *x*)*. Hence, the omission of job x from preschedule PreS*(*K*, *y*, *x*) *will create a new gap which may only be filled in by including job(s) with the same or smaller processing time.*

Let *υ* and *χ* be the number of y-jobs and x-jobs of bin *B*−(*K*), respectively, *ν* = *υ* + *χ* is the total number of jobs in that bin, and let *υ*<sup>1</sup> be the number of Type (b) y-jobs. The next theorem gives a valid upper bound on the cost of a call of PROCEDURE AUGMENTED(*K*, *δ*) at Phase 1 (including all the recursive calls that the initial call may yield).

**Theorem 2.** *The total cost of a call of Phase 1 for a kernel K is O*(*ν*<sup>2</sup> log *ν*)*. Hence, the cost of a call of PROCEDURE AUGMENTED*(*K*, *δ*) *is the same.*

**Proof.** At Step 1 of Pass 1, during the construction of preschedule *PreS*(*K*) ED-heuristics with an upper bound on its running time *O*(*υ* log *υ*) for scheduling up to *υ* y-jobs is used, whereas at less than *υ*<sup>1</sup> scheduling times a new kernel may arise (as the delaying emerging job may only be a Type (b) y-job). Phase 1 invokes PROCEDURE MAIN which, in turn, calls the decomposition procedure for each of these kernels. By Lemma 2, the total cost of all the calls of the decomposition procedure can be estimated as *O*(*κ*<sup>2</sup> <sup>1</sup> log *<sup>κ</sup>*<sup>1</sup> + *<sup>κ</sup>*<sup>2</sup> <sup>2</sup> log *<sup>κ</sup>*<sup>2</sup> <sup>+</sup> ··· <sup>+</sup> *<sup>κ</sup>*<sup>2</sup> *<sup>υ</sup>*<sup>1</sup> log *κυ*<sup>1</sup> ), where *κ*1, ... , *κυ*<sup>1</sup> is the number of jobs in each of the *υ*<sup>1</sup> arisen kernels, correspondingly. Let *m* be the mean arithmetic of all these *κ*s. Since any newly arisen kernel may contain only y-jobs for bin *B*−(*K*) and no two kernels may have a common job, *υ*1*m* ≤ *υ*. The maximum in the sum is reached when all the *κ*s are equal to *m*, and from the above sum another no-smaller magnitude *<sup>O</sup>*(*υ*1*m*<sup>2</sup> log *<sup>m</sup>*) <sup>≤</sup> *<sup>O</sup>*(*υ*1(*υ*/*υ*1)<sup>2</sup> log(*υ*/*υ*1)) <sup>≤</sup> *<sup>O</sup>*(*υ*<sup>2</sup> log *<sup>υ</sup>*) is obtained (in the first and second inequalities, *υ*1*m* ≤ *υ* and *υ*<sup>1</sup> ≥ 1, respectively, are applied).

Then, the total cost of Pass 1 for kernel *K* (including that of Step 2, Case (2)) is *O*(*υ*1*υ* log *υ* + *υ*<sup>2</sup> log *υ*) = *O*(*υ*<sup>2</sup> log *υ*). The cost of Steps (A), (B.1) and (B.2) of Pass 2 is that of ED-heuristics, i.e., *O*(*χ* log *χ*). At Step (B.3), since the delaying emerging job for every newly arisen kernel is a distinct x-job for bin *B*−(*K*), the number of the calls of PROCEDURE MAIN for all the newly arisen kernels after the initial call of PROCEDURE AUGMENTED(*K*, *δ*), and hence the number of the recursive calls of Phase 1 for kernel *K*, is bounded by *χ*. Similar to what is done for Pass 1, we let *κ*1, ... , *κυ*<sup>1</sup> be the number of jobs in each of the *χ* arisen kernels, respectively. Again, by Lemma 2, the total cost of all the calls of PROCEDURE MAIN to the decomposition procedure is

*O*(*κ*<sup>2</sup> <sup>1</sup> log *<sup>κ</sup>*<sup>1</sup> + *<sup>κ</sup>*<sup>2</sup> <sup>2</sup> log *<sup>κ</sup>*<sup>2</sup> <sup>+</sup> ··· <sup>+</sup> *<sup>κ</sup>*<sup>2</sup> *<sup>χ</sup>* log *κχ*). We let again *m* be the mean arithmetic of all these *κ*s, *χm* ≤ *υ* and obtain an upper bound *<sup>O</sup>*(*χ*<sup>2</sup> log *<sup>χ</sup>* <sup>+</sup> *<sup>χ</sup>m*<sup>2</sup> log *<sup>m</sup>*) <sup>≤</sup> *<sup>O</sup>*(*χ*<sup>2</sup> log *<sup>χ</sup>* <sup>+</sup> *<sup>χ</sup>*(*υ*/*χ*)<sup>2</sup> log(*υ*/*χ*)) <sup>≤</sup> *<sup>O</sup>*(*ν*<sup>2</sup> log *<sup>ν</sup>*) on the cost of Pass 2 and hence the total cost of Phase 1 is *O*(*ν*<sup>2</sup> log *ν*).

The second claim in theorem follows as the cost of the generation of the second part of an augmented *Lδ*-schedule is absorbed by that of the first part. Indeed, recall that for a call of PROCEDURE AUGMENTED(*K*, *δ*), the second part of schedule *SL<sup>δ</sup>* [*K*] consisting of the jobs of the atomic kernel *K*∗, is constructed by ED-heuristics in time *O*(*κ* log *κ* ), where *κ* ≤ *κ* is the total number of jobs in atomic kernel *K*∗, and *κ* is the number of jobs in kernel *K* (Proposition 10). Similar to above in this proof, we can show that the construction of the second part of the augmented schedules for the calls of PROCEDURE AUGMENTED for all the arisen kernels (for the same *δ*) is *O*(*n* log *n*).

At this stage, we can give an optimality (sufficient) condition for problem 1|*rj*|*L*max, that is helpful also in that it exhibits where the complex nature of the problem is "hidden". Dealing with an IA(b2) is a complicated task as it implies the solution of NP-hard set/numerical problems such as 3-PARTITION yet with additional restrictions that impose job release times. As to the solution provided by PROCEDURE MAIN, as we have seen above, the recurrences at Step 2, Case (2) in Pass 1, and at Step (B.3) at Pass 2 do not, in fact, cause an exponential behavior.

**Theorem 3.** *PROCEDURE MAIN finds an optimal solution to problem* 1|*rj*|*L*max *in time O*(*n*<sup>2</sup> log *n* log *p*max) *if no IA(b2) at Phase 1 arises.*

**Proof.** The proof is quite straightforward, we give a scratch. The initial step takes time *O*(*n* log *n*) (the cost of ED-heuristics). At iterative step, the cost of updates of *L*∗ max and *δ*(*M*∗), *M* ∈ K and that of the detection of every newly arisen kernel is bounded by the same magnitude. It is easy to see that an *L*-preschedule for every kernel in K will be generated at Phase 1 if no Type (b) y-job is forced to surpasses the *L*-boundary, or, equivalently, no IA(b2) arises (only a y-job may be forced to surpass the *L*-boundary, whereas, if a Type (a) y-job surpasses it, PROCEDURE MAIN proceeds with the newly arisen kernel). Hence, PROCEDURE AUGMENTED(*K*, *δ*) will create a feasible *L*-augmented schedule for every kernel (since no IA(b2) at Pass 1 arises). Then, it remains to estimate the calls of PROCEDURE AUGMENTED(*K*, *δ*) in the iterative step. The cost of a call of PROCEDURE AUGMENTED(*K*, *δ*) for a given kernel *K* including all the embedded recursive calls is *O*(*ν*<sup>2</sup> log *ν*) (Theorem 2). These recursive calls include the calls for all the kernels which may arise within bin *B*−(*K*). Hence, for the purpose of our estimation, it suffices to distinguish the calls PROCEDURE AUGMENTED(*K*, *δ*) and PROCEDURE AUGMENTED(*M*, *δ*) for two distinct kernels *K* and *M* such that bins *B*−(*K*) and *B*−(*M*) have no jobs in common. Then, similar to what is done to estimate the cost of Pass 1 in the proof of Theorem 2, we easily get an overall (amortized) cost of *O*(*n*<sup>2</sup> log *n*) for PROCEDURE MAIN for a given trial *δ*. Then, we obtain the overall cost of *O*(*n*<sup>2</sup> log *n* log *p*max) for PROCEDURE MAIN taking into account that there are no more than log *p*max trial *δ*s.
