• No results found

Offline avionics scheduling subproblems using decomposition methods.: Hybridisation between Constraint Programming and Mixed Integer Programming.

N/A
N/A
Protected

Academic year: 2022

Share "Offline avionics scheduling subproblems using decomposition methods.: Hybridisation between Constraint Programming and Mixed Integer Programming."

Copied!
47
0
0

Loading.... (view fulltext now)

Full text

(1)
(2)
(3)
(4)
(5)

Acknowledgements

I would like to thank my supervisors Elina R¨ onnberg, Pierre Flener, Justin

Pearson, and Emil Karlsson for making this project possible. All of you

have provided invaluable help in completing this project.

(6)

Contents

1 Introduction 8

1.1 Purpose of This Report . . . . 8

1.2 Report Outline . . . . 8

2 Problem 8 2.1 Tasks . . . . 8

2.2 Modules . . . . 9

2.3 Dependencies . . . . 9

2.4 Chains . . . . 10

2.5 The Module Idle Time Requirement . . . . 10

3 Background on Optimisation 11 3.1 Mixed Integer Programming . . . . 11

3.2 Constraint Programming . . . . 12

3.2.1 Modelling . . . . 13

3.2.2 Solving . . . . 13

3.2.3 The Element Constraint . . . . 15

3.2.4 The Cumulative Constraint . . . . 15

3.2.5 The Disjunctive Constraint . . . . 16

3.3 Problem Decomposition . . . . 16

4 Design 16 4.1 Notation . . . . 16

4.1.1 Generator Expressions . . . . 16

4.1.2 List Operators . . . . 17

4.2 The Constraint Formulations . . . . 17

4.2.1 Parameters and Variables . . . . 18

4.2.2 The Non-Overlapping Constraint . . . . 18

4.2.3 The Module Constraint . . . . 20

4.2.4 The Starting Interval Constraint . . . . 21

4.2.5 The Dependency Constraint . . . . 22

4.2.6 The Task Chain Constraint . . . . 23

4.3 Model Decomposition . . . . 23

4.3.1 The Plan . . . . 23

4.3.2 Design Motivation . . . . 24

4.3.3 Design Challenges . . . . 24

4.3.4 Additional Parameters and Variables . . . . 26

4.4 The CP Alpha Model . . . . 27

4.4.1 Blamelist Support . . . . 27

4.4.2 Whichgap and Related Constraints . . . . 27

4.4.3 The Gap Capacity Constraint . . . . 27

4.4.4 The Brancher . . . . 29

(7)

4.4.5 Additional Failure Condition . . . . 30

4.5 The MIP Beta Model . . . . 30

5 Experiments and Results 31 5.1 Memory Usage Analysis . . . . 32

5.1.1 Setup . . . . 32

5.1.2 Results . . . . 32

5.2 Branching Strategy Evaluation . . . . 33

5.2.1 The CP Model and Search Strategies . . . . 34

5.2.2 Results . . . . 35

6 Discussion 36 6.1 CP Beta Model . . . . 36

6.2 Redesign of the Decomposition . . . . 36

6.2.1 Improved Alpha/Beta Communication . . . . 37

6.2.2 Alpha Model Subproblem Enumeration . . . . 37

6.2.3 A Step Towards a Fully Integrated Method . . . . 38

6.2.4 Limitations of Google OR-tools . . . . 38

6.3 Explicit Interval Modelling . . . . 39

References 41

A Branching Strategy Tables 42

(8)

1 Introduction

The focus of this thesis is a decomposition for solving an offline avionics scheduling problem. The purpose is to study the possibility of improving this decomposition by replacing a component previously implemented using mixed integer programming (MIP) [12] with a component implemented using constraint programming (CP) [13].

1.1 Purpose of This Report

The problem described in this report is related to the problems described in [2, 10, 4], and is off interest to solve large instances of for Saab. However, the details for why this is important to them have not been made public. One of the main purposes of this report is to provide a clear, publicly available view of the problem as a means to allow for further study. We also present a decomposition method based on a decomposition described in [10]. This decomposition uses both MIP and CP components, both technologies that have been used to solve similar problems before [10, 2], but this is the first attempt at combining them.

1.2 Report Outline

In chapter 2 we define the problem of interest: it is a relaxation of an avionics scheduling subproblem first described in [10]. In chapter 3 we cover the aspects of MIP and CP that are required to understand this thesis. In chapter 4 we describe the implementation of the decomposition, as well as some insights from previous work [2, 4, 10] using the decomposition design this work is based on. In chapter 5 we present experiments and their results.

In chapter 6 we describe conclusions and future improvements.

2 Problem

We define the problem of interest. This problem is a relaxation of a problem presented in [2, 10] and is of relevance for avionics applications [2, 10].

2.1 Tasks

The objective of our scheduling problem is to find start times for a number

of tasks. The instance data define the task durations, possible task start

times, and which module (Section 2.2) each task is assigned to. Each module

executes at most a single task at each moment in time, and task executions

cannot be pre-empted.

(9)

Figure 1: Sample solution to a problem instance subject to the constraints described under Sections 2.1 and 2.2. This instance has two modules and 9 tasks, labelled T1 to T9. The period of Module 1 is 1 2 of the period of Module 2, and is therefore executed twice during a major frame, which is the period of Module 2.

2.2 Modules

In this report, a module can be seen as a processor. Modules have a period and a number of tasks assigned to them, both defined by the instance data.

Our problem is cyclic, so any solution needs to be repeatable indefinitely. In a valid schedule each module executes all tasks assigned to it exactly once during its period. The longest module period is called the major frame, and all other periods are k 1 of the duration of the major frame, for some integer k. All tasks are pre-assigned to a module.

2.3 Dependencies

Other constraints of our problem are dependencies, each defined by a source task required to precede a target task within a specified interval of time.

This idle time is measured from when the source starts executing to when the target starts executing, and is a non-negative integer.

One important case of these dependencies is that when the idle time is zero, then the tasks are required to start at the same time. As module periods can be of varying lengths, a task can execute multiple times within a major frame. These multiple task instances have dependencies indepen- dently of each other.

For example, as seen in Figure 1, task T1 is executed twice within one

major frame, and there can be dependencies from or to both of those in-

(10)

stances of T1. To separate the different occurrences of tasks, each instance of a task is called a job, so the instance of T1 furthest to the left is T1 job one, and the one to the right is T1 job two. There can be dependencies between arbitrary jobs.

In a solution, we require the start time of the source job to precede the start time of the target job with some time in the interval between the idle time minimum and maximum, for all dependencies specified by the instance data.

2.4 Chains

Some dependencies form chains. A chain is a sequence of dependencies that have to be fulfilled in a certain order. All chains are cyclic and need to be repeated exactly once every major frame. From the perspective of scheduling a single major frame, a chain is a sequence of dependencies where any of the dependencies can be the first in the sequence, and the last dependency in the sequence stretches from a task in the first major frame to a task in the next major frame.

As an example, consider an instance where there are three tasks, T1, T2, and T3, that are cyclically dependent and required to be executed in the order T1, T2, and T3. The way to encode this behaviour into instance data is as three dependencies, one from T1 to T2, one from T2 to T3, and one from T3 to T1, and make a chain of these three dependencies. Figure 2 illustrates the scheduling options for this chain: note that exactly one of the three dependencies (arrows) goes outside of the majorframe into the next one.

2.5 The Module Idle Time Requirement

Some modules, known as application modules (AMs), have an additional constraint. For each ordered pair (x, y) of tasks on such a module, there is a required minimum idle time q[x, y] from the end of x to the start of y if x precedes y in the found schedule. Note that this idle time is measured differently from the dependency idle times described in Section 2.3, where the idle time is specified as an interval, that is also with a maximum. It is known that all idle times on a given AM are smaller than the duration of the task with the shortest duration on that module: we will exploit this assumption in Section 4.2.3

Another formulation of this constraint is that for each unordered pair of

tasks (x, y) there are required minimum idle times w and z: If x precedes y

in the found schedule, then it does so by at least w time units, otherwise y

precedes x with at least z time units. This reformulation is possible as we

know that the tasks cannot overlap in time due to our constraints on the

modules. This formulation is illustrated in Figure 3. All non-AM modules

(11)

Figure 2: The task dependencies T1 precedes T2, T2 precedes T3, and T3 precedes T1 form a chain. From the perspective of a major frame, the only three possible scheduling options are displayed in the figure.

are known as communication modules (CMs). Note that this idle time is a minimum not an interval as in Section 2.3.

3 Background on Optimisation

The aspects of constraint programming (CP) and mixed integer program- ming (MIP) that are required to understand this report are presented, fol- lowed by a definition of the concept of problem decomposition.

3.1 Mixed Integer Programming

Mixed integer programming (MIP) is a technology for modelling and solving NP-hard combinatorial optimisation problems [12]. In this work, we are using Gurobi [8] as our MIP solver. Problems are formulated as a set of variables, a linear objective, a set of linear constraints, and a set of bound constraints.

MIP solvers support both integer and floating-point (often just known

as float) variables. Bound constraints allow the modeller to specify an up-

per and lower bound for the possible values of any variable. One impor-

tant case of bound constraints is the ability to create 0-1 bounded integer

variables, which are called binary variables. In MIP models, other than

bound constraints, the only constraint type available to modellers are linear

(12)

Figure 3: The unordered task pair (x, y) is under the constraint that either x precedes y by at least w time units, or y precedes x by at least z time units.

constraints, which are linear equalities and inequalities (=, <, and >) on variables and constants.

The reason for these choices of constraints and variable types for mod- els is that it allows MIP solvers to use cutting planes and linear relaxation algorithms to effectively solve large problems. The theory behind and im- plementation of these algorithms are beyond the scope of this report.

MIP solvers feature a concept known as the optimality gap, which is the largest possible difference between the currently best found solution and the actually optimal solution. As an example when maximising x, if x = 5 has been found so far, and the optimality gap is 2, then there can exist no solutions better than x = 7. MIP solvers commonly support parameters for stopping the solver when the optimality gap is sufficiently small.

3.2 Constraint Programming

Constraint programming (CP) is a technology also designed for solving NP- hard problems. It implicitly considers every possible value for each variable, and uses propagators to quickly discard values that cannot be a part of a solution [13]. When the propagators cannot remove any more values, a CP solver uses a branch and bound algorithm [13]. In this work, we are using the Google OR-Tools [7] CP solver. Constraint programming solver algorithms, propagators, and their implementation are beyond the scope of this report.

However, a basic understanding of how a CP solver operates is required to

understand the core differences between CP and MIP solvers and how their

differences affect our choices when modelling. These concepts are described

in more detail in [13].

(13)

3.2.1 Modelling

CP solvers support several types of variables; essentially any type can be implemented. Different solvers support different variable types [6, 7], but common ones are integers, floating-point numbers, and Booleans. More ex- otic variable types like sets and tasks have been implemented [6, 7]. CP solvers also rely on so-called global constraints with very effective propaga- tors: these are expressing common requirements of solutions, for example distinctness of the variables of a list or a group of tasks not overlapping in time.

A CP problem instance is specified as a set of variables, each with a set of possible values, possibly a (not necessarily linear) objective and a set of (not necessarily linear) constraints on the variables. As an example, we can specify a problem to have the variables x and y, the constraints on the variables being y > x and 55 = x + y. The set of possible values for a variable is called its domain and can be any finite set of values. A variable with a domain of only a single value is called fixed. Going with our example, we can choose the initial domains of x ∈ {1, 12, 15, 1337, 9001} and y ∈ {w | 1 < w < 100}.

3.2.2 Solving

Here we give a short introduction to how CP solvers work. Because of this, common optimisations used by most solvers are not described in this section.

When solving a problem, a CP solver alternates between two phases, search and inference. During inference, propagators prune values from the domains of some variables. Typically, one propagator is created for each constraint of the problem. In our running example, y > x and 55 = x + y would create two propagators, one being responsible for pruning values from the domains of x and y that cannot be in a solution under the constraint y > x. In the same way, another propagator is responsible for pruning values unsupported under 55 = x + y. If a propagator detects that there are no possible values left in a variable domain, then the problem is proven to be infeasible. This is known as a domain wipeout. In our example, assuming our propagators prune all impossible values initial propagation of the 55 = x + y constraint would remove 1337 and 9001 from the domain of x, leaving x with the new domain {1, 12, 15}; under the same constraint, the domain of y would shrink to {54, 43, 40} as those are the only values for y where there exists some value of x such that 55 = x + y can be true. Our other propagator, for the constraint y > x, will not be able to remove any values, as there exist no values in the domains of x or y that are unsupported under y > x.

The second phase of CP solving is search, which is triggered whenever

none of the propagators can prune any more values, and there still are

(14)

multiple values left in the domain of at least one variable in the set of variables to branch on. During search, some variable is selected and sub- problems are created based on its current domain: each of the sub-problems contains a disjoint subset of the current domain of the selected variable.

In our running example, the set of values to branch on will be {y, x}.

The brancher uses a strategy for selecting which of the variables to partition, in our case x or y. This is called a variable selection strategy and can be specified when modelling. In our example, let us say that the strategy is largest-maximum-value, making the selection be y. The next step is to use some strategy to partition the domain of y. In our case, let us say that our strategy is to investigate the smallest values first: our brancher creates two new sub-problems, one where y = 40 and x ∈ {1, 12, 15} and one where y ∈ {54, 43} and x ∈ {1, 12, 15}. Then solving continues with inference on the first sub-problem. During inference, the propagator for 55 = x + y will fix our last variable to x = 15, and with all variables in our set of variables to branch on fixed and no propagator triggering a domain wipe-out, we have our first solution. The solver will return that solution (x = 15, y = 40). After that solving continues with inference on the next sub-problem (y ∈ {54, 43}, x ∈ {1, 12, 15}) if the model parameters specify that more solutions are interesting, and otherwise search terminates.

How to branch on variables, and which variables to branch on can be up to the problem modeller, and is in many cases critical to performance. A solution is considered to be found when all variables in the set of variables to branch on have been fixed, and all constraint propagators cannot remove any more values. If a variable is in the set of variables to branch on, then in any solution output by the CP solver it will be fixed.

Because a propagator is limited to only prune values that cannot be in a solution under its constraint, there is no guarantee that a solution exists for the conjunction of all the constraints. In most cases, this leads to models where the branching is on a subset of variables such that a solution is guaranteed to only contain fixed variables.

As an example of this effect, consider a problem with an array of 3 vari- ables x i all with the domain {1, 2}, and our problem requires all x i to have different values. However, instead of modelling this using an AllDifferent constraint [11], assume it is modelled as x 1 6= x 2 , x 2 6= x 3 , and x 1 6= x 3 . This problem is trivially unsatisfiable as for x 1 , x 2 , and x 3 to all be different, there need to be at least 3 different possible values for the x i variables.

For this model, 3 propagators are created, one for each of our constraints,

x 1 6= x 2 , x 2 6= x 3 , and x 1 6= x 3 . When running inference, all of these prop-

agators would execute, trying to remove any values that are not supported

under their constraint. Have a closer look at the behaviour of the x 1 6= x 2

propagator as an example: it cannot deduce that x 1 cannot be 1, because

x 2 might be 2, and it cannot prune the other value for the same reason, and

similarly for x 2 . This is true for all the 3 propagators, as none of them have

(15)

the information required to show that this problem is unsatisfiable. Because of this, unless there is a brancher on at least one of the x i variables, a CP solver would return x 1 ∈ {1, 2}, x 2 ∈ {1, 2}, x 3 ∈ {1, 2}.

This example also illustrates that, in most cases, it is a good idea to enforce the constraints of a problem using as few CP constraints as possible.

In this case, a CP solver given the AllDifferent constraint instead would have been able to show that the problem is unsatisfiable without search.

3.2.3 The Element Constraint

One constraint that comes up a few times when modelling our problem is the Element constraint [14]. This constraint is defined as Element (index , array, value) and enforces array[index ] = value.

This can be used for example if we want to model a constraint like

“two unknown stones are required to have a total weight of 10, the stone weights being available in the array stones”. We can do it using the Element constraint like this:

Element (whichstone1 , stones, stone1 ) Element (whichstone2 , stones, stone2 ) stone1 + stone2 = 10

However, in the rest of the report, we will instead write:

stones[whichstone1 ] + stones[whichstone2 ] = 10

and note that the particular formulation implicitly uses the Element con- straint. Note that array can be a list of variables or constants.

3.2.4 The Cumulative Constraint

Another constraint that comes up when modelling our problem is:

Cumulative(starts, durations, usage, capacity)

enforcing that for tasks with start times starts, durations durations, and resource usage usage, at every moment, the sum of the resource usage of all active tasks is at most capacity [1]. Note that starts, durations, and usage can all be arrays of variables. Only capacity is required to be a constant.

As an example, if we have a number of tasks with durations dur and start times str , and a problem requires at most two of these tasks to be executing at the same time, then we can use the Cumulative constraint to enforce that constraint like this:

Cumulative(str , dur , ones, 2)

where ones is a list of as many values 1 as there are tasks.

(16)

3.2.5 The Disjunctive Constraint

One constraint used by CP solvers is defined as:

Disjunctive(starts, durations)

which enforces that no task i with start time starts[i] and duration durations[i]

can overlap in time with any other task. Note that starts is an array of vari- ables and durations is an array of constants [5]. It is also worth noting that this constraint is a special case of the Cumulative constraint (Section 3.2.4) where all usage[i ] variables are 1, and capacity is 1. However, Disjunctive is more specialised and can therefore use more effective propagators (al- gorithms with lower run-times, lower memory usage, or that prune more values).

3.3 Problem Decomposition

Decomposing a problem into multiple sub-problems and using communica- tion between the solution methods to these sub-problems in order to solve the full problem has been shown to be effective for solving several NP-hard problems [9]. In our case, discussed in the following section, one of the sub- problems (called Alpha) will here be solved using constraint programming (CP) and was previously solved in [2] using mixed integer programming (MIP), and the other sub-problem (called Beta) will be solved using MIP, like in [2].

4 Design

The decomposition we present in Section 4.3 was originally described in [2], with some slight differenceds introduced in order to be able to accommodate CP. Section 4.1 clarifies the meaning of some notation used in this report.

Section 4.2 describes the constraint formulations used in this decomposition.

The MIP models presented in this report are heavily inspired by [2, 10].

Sections 4.4 and 4.5 describe the Alpha and Beta models that make up the decomposition.

4.1 Notation

We specify the exact meaning of some less common notation used in this report.

4.1.1 Generator Expressions

A generator expression is a notation used for generating lists and is defined as:

[expression | value 1 ∈ collection 1 , value 2 ∈ collection 2 , . . . , value n ∈ collection n ]

(17)

This generates a list by evaluating expression for all combinations of values in all collections, starting with the first value of each collection and iterating each of the collections in order. For example:

[x · y | x ∈ [1, 2, 3], y ∈ [1, 4]] = [1, 2, 3, 4, 8, 12]

Note the order in which the list is generated.

4.1.2 List Operators

List concatenation is written as list 1 ++ list 2 , with the meaning that list 2

is appended to list 1 . For example:

[4, 8, 3] ++ [1, 2, 6] = [4, 8, 3, 1, 2, 6]

We will also use the notation .. as a matrix slicing operator. Consider the matrix:

1 2 3 4 5 6 7 8 9

 = h

If we want to use the centre row of this matrix as a list, then we can do so using a generator expression (Section 4.1.1), but we can also use the shorthand .. for that row of the matrix:

[h[2, x] | x ∈ [1, 2, 3]] = [4, 5, 6] = h[2, ..]

Note that indexing here starts from 1, not from 0.

4.2 The Constraint Formulations

As some constraints appear in several models, we will explain them in detail so that they can be referenced in later sections of the report. Because the constraint predicates available to CP solvers form a superset of the ones available to MIP solvers, some constraints are posted in the same way in both kinds of solvers, but that does not mean that they have comparable performance as the underlying mechanisms for enforcing those constraints are vastly different.

There are some variables that are used in both CP and MIP models; for

example, both introduce task start times as variables, which will always be

referred to as elements of an array TST . The task durations are provided by

the instance data, and will always be referred to as elements of an array TD .

Some formulations use big-M [15] constants, which will always be written

as M . In this work, we use the duration of a major frame as M : this is a

concession made due to time limitations and MIP formulations not being

the focus of this work, even though smaller big-M values often lead to faster

solving. For reports focusing on effective MIP formulations for this problem,

please refer to [2, 4, 10].

(18)

4.2.1 Parameters and Variables

As a summary and for quick reference, we provide two tables describing the parameters and variables. Table 1 lists the parameters and derived parameters used to post the constraints, and their semantics. Table 2 lists all the variables that are used in at least one model.

Name Semantics

AMs set of all AM-type modules CMs set of all CM-type modules

modules set of all modules: AMs ∪ CMs = modules MT [i] set of tasks assigned to module i

tasks set of all tasks: tasks = S

i∈modules

MT [i]

first [i] fictional first task on module i last [i] fictional last task on module i

intervals[i] set of starting intervals for task i, of the form 1..n i deps set of all dependencies

chainset set of all chains

MF duration of the major frame (see Section 2.2) M a sufficiently large value; here M = MF TD [i] duration of task i

k[x][i, j] required idle time from task i to j, where i, j ∈ MT [x]

minidle[i] minimum idle time between source and target of dependency i maxidle[i] maximum idle time between source and target of dependency i s[i] source task of dependency i

t[i] target task of dependency i SJ [i] source task job of dependency i TJ [i] target task job of dependency i TP [i] period of the module of task i chains[i] dependencies in chain i

starts[i][w] start of starting interval w for task i ends[i][w] end of starting interval w for task i

Table 1: Instance data parameters and derived parameters.

4.2.2 The Non-Overlapping Constraint

Because modules (see Section 2.2) can only execute one task at each mo- ment in time, there is a need for a constraint that ensures that no two task executions overlap if they are on the same module.

For CP solvers, there is a constraint called Disjunctive(starts, durations)

(19)

Name Domain Semantics Model

TST [i] S

j∈intervals[i]

starts[i][j]..ends[i][j] start time of task i CP, MIP

precedence[x][i, j] {0, 1} 1 iff task i directly precedes task j, where i, j ∈ MT [x] MIP

border [i] {0, 1} 1 iff dependency i crosses major-frame bounds CP, MIP

whichinterval [i] 1..|intervals[i]| starting interval of task i CP

starthere[i][j] {0, 1} 1 iff task i is in starting interval j MIP

idle[i] minidle[i]..maxidle[i] idle time between tasks s[i] and t[i] for dependency i CP, MIP Table 2: Semantics of introduced variables.

(see Section 3.2.5), which is designed for this purpose. We post

∀x ∈ modules :

Disjunctive([TST [i] | i ∈ MT [x]], [TD [i] | i ∈ MT [x]]) (1) to enforce the non overlapping constraint.

For MIP solvers, this constraint is traditionally formulated by introduc- ing a matrix precedence[x][i, j] of 0-1 variables for each module x, where precedence[x][i, j] = 1 means that task i is directly preceding task j (i.e., that task i is preceding task j and that there are no tasks between tasks i and j on that module). The matrix is extended to contain two fictional tasks, one of which by definition is the first task and the other the last task (note that these fictional tasks only exist in the precedence matrix). Note that for the entire model, precedence[x][i, j] is a list of 2D matrices, each of size (|MT [x]| + 2) · (|MT [x]| + 2) for module x.

The precedence matrix is subject to constraints requiring that all non- fictional tasks are directly preceded by exactly one task and directly followed by exactly one task, that one task is preceding the last fictional task, and one task is following the first fictional task. This is formulated as follows:

∀x ∈ modules, w ∈ MT [x] : X precedence[x][w, ..] = 1, X

precedence[x][.., w] = 1 (2)

∀x ∈ modules :

X precedence[x][first [x], ..] = 1, X

precedence[x][.., first [x]] = 0 X precedence[x][.., last [x]] = 1, X

precedence[x][last [x], ..] = 0

(3)

There is an additional constraint for each unordered task pair (i, j) that forces i and j not to overlap if i is directly preceding j, which is formulated as follows for the CM-type modules:

∀x ∈ CMs, i ∈ MT [x], j ∈ MT [x] :

TST [i] + TD [i] ≤ TST [j] + ((1 − precedence[x][i, j]) · M ) (4)

(20)

However a different formulation is used for AM-type modules, as it combines this constraint with the module constraint, as shown in Section 4.2.3 below.

Other formulations of the non-overlapping constraint for MIP models of this problem can be found in [4], as well as an evaluation of their relative performance using this formulation as a baseline.

4.2.3 The Module Constraint

Because MIP solvers require an explicit modelling of the task ordering to enforce the non-overlapping constraint by using the precedence matrix, MIP models can also enforce the module idle time requirement (see Section 2.5) by using the same precedence matrix (see Section 4.2.2 above). Therefore, even if this is a separate constraint, MIP models contain it as a part of the non-overlapping constraint. It is formulated like this:

∀x ∈ AMs, i ∈ MT [x], j ∈ MT [x] :

TST [i] + TD [i] + k[x][i, j] ≤ TST [j] + ((1 − precedence[x][i, j]) · M ) (5) where k[x][i, j] is the required idle time from i to j if i is preceding j, where i and j are tasks on application module x. This constraint is posted for all pairs of tasks on an application module (AM) and enforces both that tasks are non-overlapping and that the module constraint is respected. Note that the only difference between this formulation and (4) is that the formulation above adds the constant k[x][i, j] on the left side of the inequality. Note that this modelling can result in incorrect results if k[a, c] is greater than some task duration TD [b]. Indeed, consider tasks a, b, and c: if they are sequenced in the order a, b, c, then the resulting constraints on their start times will be:

TST [a] + TD [a] + k[x][a, b] ≤ TST [b]

TST [b] + TD [b] + k[x][b, c] ≤ TST [c]

As k[x][a, c] is not present in these constraints, the requirement that if a is preceding c then it does so by at least k[a, c] can be violated. However, the instance data satisfies that k[a, c] needs to be smaller than TD [b] for all tasks b on the same module as a and c, as mentioned in Section 2.5, so this case cannot happen in our model.

For CP models, there need not be an explicit modelling of an order for tasks, and therefore we instead post:

∀x ∈ AMs, i ∈ MT [x], j ∈ MT [x] :

Disjunctive([TST [i], TST [j]], [TD [i] + k[x][i, j], TD [j] + k[x][j, i]]) (6)

where k[x][i, j] is the required idle time (as in the MIP model). Note that

this constraint only operates on pairs of tasks, as the k[x][i, j] constants are

(21)

Figure 4: The unordered task pair (i, j) is under the module constraint, and therefore can their task executions, extended with the required idle times k[x][i, j] and k[x][i, j], not overlap.

specific to each pair (i, j) of tasks. Figure 4 shows a representation of this constraint for a task pair.

We had some concerns that this constraint formulation might cause per- formance issues for CP solvers, as each Disjunctive constraint is posted on a set of only two tasks. However, as this constraint only applies to AMs, which typically have smaller numbers of tasks than other modules, the sig- nificance of this formulation might be small in terms of overall runtime. Due to memory issues (see Section 5.1), the significance of this constraint has yet to be evaluated.

4.2.4 The Starting Interval Constraint

Task start times are defined by the instance data as belonging to the union of multiple disjoint intervals, of which only one actual value is to be used.

In some CP solvers, it is possible to specify the domain of a variable to be the union of multiple disjoint intervals; however, this does not seem to be an option in OR-tools, where variable domains are single intervals. Therefore this constraint is required even in some CP models. To restrict the start times in this way, for each task i, we introduce a variable whichinterval [i]

into the CP model with the same number of possible values as the number of possible starting intervals, representing which of the possible starting intervals is actually used. We also introduce an array starts[i][j] of the start times of each of the intervals, and another array ends[i][j] of the end times of each of the intervals, where i is a task and j an interval identifier. Note that starts[i][j] and ends[i][j] are lists of lists, as each task can have a different number of starting time intervals. We post the constraint:

∀i ∈ tasks :

starts[i][whichinterval [i]] ≤ TST [i]

TST [i] + TD [i] ≤ ends[i][whichinterval [i]]

(7)

This formulation is implicitly leveraging a constraint commonly known as

Element (see Section 3.2.3).

(22)

The MIP formulation uses a similar idea, but because the MIP mod- elling language does not have an Element constraint we, for each task i, introduce an array of 0-1 variables starthere[i][j] indexed by the possible starting intervals j, where 1 indicates that interval being used, and enforce that exactly one of those 0-1 variables is 1 by using:

∀i ∈ tasks :

X starthere[i][..] = 1 (8)

We enforce that the task start times for all tasks i are actually within the selected interval by using the following big-M formulation for each possible start interval j:

∀i ∈ tasks, j ∈ intervals[i] :

starts[i][j] ≤ TST [i] + (1 − starthere[i][j]) · M

TST [i] + TD [i] ≤ ends[i][j] + (1 − starthere[i][j]) · M (9)

where (as in the CP model) ends[i][j] and starts[i][j] are the lists of end and start times for some interval j of task i, respectively. Recall that we use M = MF here, where MF is the duration of a major frame.

4.2.5 The Dependency Constraint

For each dependency we use the same formulation in both CP and MIP solvers; we introduce a variable idle[i] representing the actual idle time be- tween the task s[i] and task t[i] of dependency i. We enforce that idle[i] is at most the maximum idle time and at least the minimum idle time using a bound constraint in MIP and a domain declaration in CP:

∀i ∈ deps :

minidle[i] ≤ idle[i] ≤ maxidle[i] (10) Then we post the dependency constraint as:

∀i ∈ deps :

TST [s[i]] + TP [s[i]] · SJ [i] + MF · border [i] + idle[i] ≤ TST [t[i]] + TP [t[i]] · TJ [i]

(11) where TP is a list indexed by tasks containing the period of the module they are allocated to, MF is the length of the major frame, SJ [i] is the source job of dependency i, and TJ [i] is the target job of dependency i, border [i]

is a 0-1 variable where the value 1 indicates that dependency i is crossing

major frame boundaries, as in that case there is a need to offset the entire

calculation by one major frame. As which tasks are on which module, and

(23)

the period associated with each module, is known from the instance data, TP [i] is a list of constants derived from the instance data, and exists only for the purpose of posting this constraint in a more concise way.

4.2.6 The Task Chain Constraint

One important thing to recognise about chains is that, because they are repeated exactly once per major frame, exactly one of the tasks in a given chain needs to cross major-frame bounds. Therefore we post the constraint that for each chain of dependencies, exactly one of the border [i] variables associated with the dependencies i in that chain must be 1, which is formu- lated as:

∀r ∈ chainset : X

i∈chains[r]

border [i] = 1 (12)

where chains[r] is the set of dependencies in a chain. This formulation is used for both CP and MIP solvers.

4.3 Model Decomposition

Our hybrid CP/MIP decomposition is based on the work described in [2], which presents a method for separating a similar problem into two MIP components. This method exploits a number of known facts about the problem instances. First of all, it is known that about 50% of the tasks on some modules have fixed start times. Secondly, it is known that the constraints of our problem are quite loose in the sense that, in most cases, they will allow a task to be placed in multiple possible start times. Thirdly, the difficulty of solving this problem lies not in the constraints, as much as it lies in the massive amount of tasks to schedule on the modules [2]. For our problem, instances that are considered useful have about 10 4 tasks and the current goal is to be able to solve instances of up to 10 5 tasks.

4.3.1 The Plan

The way we exploit the data characteristics is by recognising that if we have

two tasks with fixed start times on the same module, then the time from

the first one’s end-time until the second one’s start time, which we will call

a gap, can have its own non-overlapping constraint if we know which tasks

should be scheduled in that gap. Therefore, we can split the problem into

two components, an Alpha model, which is designed to find a good way to

divide the tasks into gaps, and a Beta model, which is designed to solve the

problem given an assignment of tasks to gaps. An example module with

gaps is shown in Figure 5.

(24)

Figure 5: A module with 3 gaps, created by two tasks with fixed start times (illustrated as tasks with lock symbols).

4.3.2 Design Motivation

Because the non-overlapping constraint for MIP solvers is implemented using (N + 2) 2 -sized matrices of variables for each module x, called the precedence[x] matrices in Section 4.2.2, where N is the number of tasks of module x that cannot overlap, enforcing a general non-overlapping con- straint on all tasks on a module is very costly. First dividing tasks over gaps and then enforcing the non-overlapping constraint per gap changes the number of variables that need to be introduced from (N + 2) 2 to (a 1 + 2) 2 + (a 2 + 2) 2 + · · · + (a k + 2) 2 variables, where k is the number of gaps and a j is the number of tasks in gap j, which sum is usually smaller than (N + 2) 2 .

This relaxation of the problem (where no task start time domain has values in multiple gaps) vastly improves computation times, and the MIP model implementing it in the decomposition is called the Beta model. How- ever, some mechanism is needed to find a relaxation of the problem that is also a solution to the original problem, i.e., to find a gap assignment for each task such that there exists a solution within the resulting start time domains.

This mechanism is originally [2] achieved by another MIP model, called the Alpha model, that implements all constraints except for the non-overlapping constraint. For this model, the actual task start times in a solution are not interesting, but in which gaps tasks end up is interesting. This information is used to create relaxations for the Beta model. The Alpha model is work- ing on a relaxation of the original problem, without the non-overlapping constraint, and therefore runs vastly faster than the full MIP model. Our aim here is to reformulate the MIP Alpha model using CP.

4.3.3 Design Challenges

One problem with the idea in Section 4.3.2 is that we have no concrete notion of goodness for gap assignment, at least not without solving the entire problem, which would defeat the point of the decomposition. In [2]

the Alpha model becomes an optimisation problem, optimising for some heuristic measures that seem to lead to good gap assignments, and hence not running to global optimality.

Another problem is that some strategy for dealing with what happens if

an Alpha assignment is shown to be infeasible by the Beta model is needed.

(25)

Figure 6: Data flow of the decomposition.

The technical report [2] presents something we call the blamelist, which is a list of tasks known to cause infeasible gap assignments. The Beta model is formulated to optimise for as many gaps as possible not to be overlapping, and, when an optimal solution is found, to have some gap with overlapping tasks in it: all tasks in that gap are added to the blamelist. The tasks on the blamelist are subject to a non-overlapping constraint in the Alpha model.

The introduction of the blamelist makes it desirable for the Alpha model to return similar gap assignments on multiple runs, as the blamelist identi- fies tasks that have been causing unsatisfiability previously, but those tasks are likely only an issue due to all other gap assignments. In [2] the solution presented is what we will call the stability heuristic: it is an optimisation objective function used in the Alpha model for all but the first run, which rewards tasks being put close to their previous task start times. This opti- misation objective is:

maximise X

(i,k)∈s

α[..][i, k]

where α[m][k, i] is a 0-1 variable introduced for each task i and gap k on

module m, with α[m][i, k] = 1 meaning that task i is in gap k, and s is the set

of (i,k) pairs for which α[m][i, k] was 1 in the previous MIP Alpha run. The

optimisation is not run to optimality: instead, the MIP Alpha run is here

stopped by the MIP solver (Gurobi here) when (|u − s|/(10 −10 + |s|)) < 0.10

becomes false, where u is the current upper bound for the best solution and

s is the currently best found solution [2]; this is known as the relative MIP

gap being 0.10. The reason the relative MIP gap is here set to 0.10 (instead

of the default 0.0001) is to stop the MIP Alpha run early, as it is not critical

(26)

Name Semantics

blamelist [x] b ∩ MT [x], where b is the set of tasks on the blamelist gaps[x] set of gaps on module x

gapstarts[x][g] start times for gap g on module x gapsends[x][g] end times for gap g on module x gaplength[x][g] gapsends[x][g] − gapstarts[x][g]

gaptasks[x][g] set of tasks in gap g, which is on module x

gp[x][g][i, j] 1 iff task i directly precedes task j, where i, j ∈ gaptasks[x][g] for gap g on module x gapfirst [x][g] fictional first task for gap g on module x

gaplast [x][g] fictional last task for gap g on module x

Table 3: Instance data parameters and derived parameters introduced for the decomposition. Note that gp, gapfirst , and gaplast are per-gap versions of precedence, first , and last respectively, as discussed in Section 4.2.2.

to the decomposition to achieve perfect stability between Alpha runs: it is deemed sufficient to achieve some stability using optimisation in combination with a relative MIP gap of a much as 0.10. Using a higher relative MIP gap accelerates solution processes (in most cases) by not requiring the solver to find an optimal solution. Because our Alpha model is not a MIP model and CP solvers do not feature a counterpart concept, we are unable to use a relative gap in order to create stability in this way.

Achieving some notion of stability for the solution output by the Alpha model is likely critical to the decomposition performance. However, as CP solvers do not use linear relaxation, there is no way to calculate a relative MIP gap. If an optimisation function were used for a CP Alpha model, then it is possible to stop the solver before reaching optimality, as soon as feasibility is established. However there is no easy way of knowing how close to an optimal solution the solver is, making that approach to stability difficult as it requires us to find a reliable way of determining for how long to run the CP Alpha model without either wasting too much runtime on unnecessary further optimisation or insufficiently optimising.

Due to time limitations, no stability-introducing functionality was im- plemented into the CP Alpha model, discussed next. The data flow of this decomposition is depicted in Figure 6.

4.3.4 Additional Parameters and Variables

With the introduction of this decomposition we derive new parameters and

introduce new variables. The new parameters are presented in Table 3 and

the new variables in Table 4.

(27)

Name Domain Semantics Model

whichgap[i] gaps[m] when i ∈ MT [m] gap of task i Alpha

overlapon[g][x] {0, 1} 1 iff no tasks overlap in gap g on module x Beta Table 4: Additional variables introduced by the decomposition.

4.4 The CP Alpha Model

The CP Alpha model has the same objective as the MIP Alpha model de- scribed in [2] but achieves it using the OR-tools [7] CP solver rather than a MIP solver. It contains the module constraint (Section 4.2.3), starting in- terval constraint (Section 4.2.4), dependency constraint (Section 4.2.5), and task chain constraint (Section 4.2.6). It also enforces the non-overlapping constraint (Section 4.2.2) for modules that cannot be split into multiple gaps. Specifically we use formulations in equations numbered: 1, 6, 7, 10, 11, and 12.

4.4.1 Blamelist Support

The CP Alpha model uses a blame list in the same way as in [2]. It does this by posting the constraint:

∀x ∈ CMs :

Disjunctive([TST [i] | i ∈ blamelist [x]]) (13) where blamelist [x] is the set of tasks on the blamelist and on module x.

4.4.2 Whichgap and Related Constraints

The Alpha model introduces an integer variable whichgap[i] for each task i on a module that can be split into gaps (namely each CM), where whichgap[i]

represents which of the gaps task i is assigned to. That task start times are within a specified gap is enforced by the constraints:

∀x ∈ CMs, i ∈ MT [x] :

gapstarts[x][whichgap[i]] ≤ TST [i]

TST [i] + TD [i] ≤ gapsends[x][whichgap[i]]

(14)

For all tasks on a module i, where gapstarts and gapends are the lists of all earliest start times and latest end times of a gap respectively. This is implemented using the Element constraint (see Section 3.2.3).

4.4.3 The Gap Capacity Constraint

In [2], the MIP Alpha model has an additional constraint enforcing that the

sum of the durations of tasks assigned to a gap does not exceed the length

(28)

of that gap. This can be expressed using a predicate known as BinPacking [13]. However, as that constraint is not available in OR-tools, we use the Cumulative (see Section 3.2.4) predicate instead. Note that our problem constraint tasks and the Cumulative predicate tasks are unrelated concepts.

The constraint is formulated in our CP Alpha model using the Cumulative predicate as follows:

∀m ∈ CMs :

Cumulative(s[m], ones[m], u[m], MF )

∧ s[m] = [whichgap[t] | t ∈ MT [m]] ++ [i | i ∈ 1..|gaps[m]|]

∧ ones[m] = [1 | t ∈ MT [m]] ++ [1 | g ∈ gaps[m]]

∧ u[m] = [TD[t] | t ∈ MT [m]] ++ [MF − gaplength[m][g] | g ∈ gaps[m]]

(15) where variable whichgap[t] denotes the gap of task t, parameter gaps[m]

is the set of gaps on module m, parameter gaplength[m][g] is the duration of gap g on module m, parameter MT [m] is the set of tasks on module m, parameter TD [t] is the duration of task t, and parameter MF is the duration of the major frame. Let us explain why this is correct. With all the cumulative-task-durations being 1, the cumulative-task-resource-usage only affects the cumulative-task-start-times, meaning that all cumulative- task-start-times can be seen as unrelated sums that are required to be lower than the resource-capacity MF . The resulting constraint can be expressed as:

∀m ∈ CMs, g ∈ gaps[m] : X

t∈gaptasks[m][g]

TD [t] + MF − gaplength[m][g] ≤ MF (16) where parameter gaptasks[m][g] is the set of tasks in gap g on module m.

The term MF − gaplength[m][g] comes from the second generator expres- sion defining u[m] (resource usage for a task). Note that a constraint task has only a single possible start time as the corresponding s[m] value is a parameter (in the second generator expression defining s[m]). We subtract MF from both sides and add gaplength[m][g] to both sides, resulting in:

∀m ∈ CMs, g ∈ gaps[m] : X

t∈gaptasks[m][g]

TD [t] ≤ gaplength[m][g] (17)

which is the BinPacking constraint we aimed to formulate.

The reason the constraint is posted using Cumulative rather than as the

conjunction (17) of those linear inequalities is that the Cumulative predi-

cate has a dedicated propagator that is likely much more efficient than using

multiple linear inequality propagators, this is because a single Cumulative

(29)

propagator for a module has more domain information and can therefore hopefully prune more values than using multiple linear inequality propaga- tors for this constraint.

Example In order to make it more clear why this formulation works, con- sider an example with a single sub module. On this module, there are two fixed tasks, resulting in three gaps (similar to Figure 5). The duration of the major frame (MF ) is 30, the fixed tasks have start times 10 and 20, their du- rations are 2 and 3 respectively. There are also two unfixed tasks. With that information we can derive the parameter values gapstarts[1] = [1, 12, 23], gapsends[1] = [10, 20, 30], and gaplength[1] = [9, 8, 7]. Now consider our for- mulation (16), only focusing on what can be derived from the information presented.

For s[1] we get s[1] = [x 1 , x 2 , 1, 2, 3], were x 1 and x 2 are whatever vari- ables are produced by the left argument of the ++ operator. The variable ones[1] equals [1, 1, 1, 1, 1], and lastly, u[1] = [y 1 , y 2 , (30−9), (30−8), (30−7)], where y 1 and y 2 again are generated by the left argument of the ++ op- erator. Now consider the resources available for the cumulative-constraint- task-start-times, without the contribution from our two unfixed tasks (and the resulting x i and y i variables). For the cumulative-task with index 3, it is our cumulative-constraint-resource-usage (namely 30), minus the resource usage of all tasks where s[1][t] equals 1, namely 21, which means that the remaining resource usage for this start time is 9, exactly the same as the gaplength for the first gap in our problem (gaplength[1]), and this holds for 2 and 3 as well.

Then, let us consider x 1 , the variable denoting the start time of the cumulative-constraint-task with index 1, looking at the left generator ex- pression for s[1], we see that x 1 = whichgap[1]. Likewise, y 1 = TD [1], con- sidering the left generator expression for u[1]. Hence, whichgap[1] denotes if TD [1] should be contributed to cumulative-constraint-resource-usage for times 1, 2, or 3, which are equal to gaplength[1], gaplength[2], and gaplength[3]

respectively.

4.4.4 The Brancher

Our CP Alpha model uses a multi-phase search strategy, first branching on the border [i] variables introduced for the dependency constraint (Section 4.2.5), and then on the whichinterval [i] variables introduced for the start- ing interval constraint (Section 4.2.4). This is followed by branching on the whichgap[x] variables introduced because it is an Alpha model (Section 4.4.2), and lastly a brancher on the task start times (TST [i]) for the tasks on the blamelist.

The reasoning behind this branching strategy is that the border [i], whichinterval [i],

and whichgap[i] variables all have small domains and likely high impact on

(30)

the size of the search space relative to the TST [i]. Therefore, fixing those variables is likely to constrain the search space to a point where a solution likely exists within the selected gap assignment.

It was theorised in the early stages of this project that the CP Alpha model’s branching strategy would be able to enforce some sort of stability similar to that of the previous MIP Alpha model. However, due to restric- tions of the OR-tools set of available branching strategies and time reasons, no such branching strategy was implemented.

4.4.5 Additional Failure Condition

With this branching strategy, the solutions to the CP Alpha model are not guaranteed to fix the values of all the TST [i] variables. Because of that, this branching strategy results in incomplete search. The reason for this is that early testing revealed that branching on the TST [i] variables is very costly for CP. The suspected reason for this is that the TST [i] variable domains are very large (of size greater than 10 6 in many cases) and that there are (in most problem instances) a lot of them compared to the other variables.

Each branching decision on a TST [i] variable is also expected to have low propagation impact, as it can only affect other tasks indirectly.

This means that the MIP Beta model (of Section 4.5) might get an infeasible gap assignment. The original MIP-MIP decomposition does not have this problem because the previous Alpha model is used under complete search. This issue is an edge case that is not likely to come up if the quality of Alpha solutions increases, but for Alpha models that generate valid but very poor Alpha solutions, the Beta model might show that the problem is infeasible even without the non-overlapping constraint. In this case, we have no solution and no tasks to add to the blamelist. In this work, the approach used is to blame a not yet blamed task at random. With this fix the model still has the same convergence guarantees as in the original decomposition, and, in practice, Alpha models will likely not trigger this very often.

This is a trade-off from using incomplete search, which has potential to greatly improve Alpha runtimes. However, if this side effect is not desired, then adding a brancher on the TST [i] will make the CP Alpha model do complete search and not have this feature.

4.5 The MIP Beta Model

The Beta model is a mixed integer programming model and posts all con- straints described in Section 4.2 except for the non-overlapping constraint (i.e, the constraints described in Sections 4.2.3, 4.2.4, 4.2.5, and 4.2.6). The design of this model is heavily inspired by [2, 10, 4]. Specifically we use the formulations (5), (8), (9), (10), (11), and (12).

It takes an Alpha solution in the form of an assignment of tasks to

(31)

gaps and restricts their start times to be within the bounds of those gaps.

Instead of posting a single non-overlapping constraint across all start times of a module, it posts one non-overlapping constraint per gap:

∀m ∈ CMs, g ∈ gaps[m], w ∈ gaptasks[m][g] : X gp[m][g][w, ..] = 1, X

gp[m][g][.., w] = 1 (18)

∀m ∈ CMs, g ∈ gaps[m] :

X gp[m][g][gapfirst [m][g], ..] = 1 X gp[m][g][.., gapfirst [m][g]] = 0 X gp[m][g][.., gaplast [m][g]] = 1 X gp[m][g][gaplast [m][g], ..] = 0

(19)

The Beta model also introduces a variable overlapon[x][g] for each of these non-overlapping constraints and is 1 if and only if no tasks overlap in gap g on module x. It maximises the sum of all overlapon[x][g] variables, and when it has reached optimality it has either found a solution with all overlapon[x][g] = 1, or with some overlapon[x][g] = 0, in which case all tasks in the gap associated with that overlapon[x][g] are added to the blamelist.

The way the overlapon[i] variables are connected to the non-overlapping con- straints is by replacing the standard non-overlapping formulation (3) with:

∀x ∈ CMs, g ∈ gaps[x], i ∈ gaptasks[x][g], j ∈ gaptasks[x][g] : TST [i] + TD [i] ≤ TST [j] + ((2 − gp[x][g][i, j] − overlapon[x][g]) · M )

(20) for all pairs (i, j) of tasks in gap g, where gp is a per-gap version of the precedence matrix described in Section 4.2.2.

The Beta formulation is not the focus of this work and potential im- provements as well as further details have been presented in [4].

5 Experiments and Results

In order to evaluate the performance of the models created and to give some better understanding of our problem, some experiments were conducted.

These experiments and their results are described in this section. The prob-

lem instances used were created by researchers at the University of Link¨ oping

(LiU) and are smaller-scale versions of instances presented in [10], adapted

for our version of the problem. Smaller instances are used as memory issues

made testing on large instances impossible: see Section 5.1. All experiments

were conducted using OR-tools [7] via its Python 2.7 binding.

(32)

5.1 Memory Usage Analysis

A first experiment illustrates that at least some of the memory issues en- countered in OR-tools are not based on instance size.

5.1.1 Setup

In the CP Alpha model decomposition there is a loop where each task in a module with gaps has its gap-related constraints posted and the whichgap variables created. Into that loop, a line is inserted, which stops the program until the user presses a key. By using this, in combination with the Linux tool htop, 1 memory usage is measured for every loop iteration.

5.1.2 Results

The results of this experiment vary depending on which problem instance is tested, however not in the way that we would expect, with more tasks, or with instances with larger amounts of gaps, requiring more main memory.

As we can see in Table 5 and Figure 7, for some instances a single iteration of this loop allocates a very high amount of memory; however, for other instances, the memory usage increase is so small it cannot be measured with this tool. With the variety of instances tested, there seems to be no correlation between the number of gaps or the number of tasks and the amount of memory allocated, which is unexpected considering that the constraints are posted using arrays with size proportional to the number of gaps on the module.

While there are limitations to this way of measuring memory usage, as htop reports system-wide main memory usage and not per-process usage, the data gathered is quite clear: for some instances, memory usage is extremely high, and because it grows so quickly, it is difficult to measure with other tools as they commonly require a process to finish. This would be difficult to set up considering that this loop is expected to run for at least 600 iterations in order to create an Alpha model, and at 0.5 GB each, that would require 300 GB of main memory, which is beyond the capabilities of our available hardware.

Considering the memory usage seems independent of instance size, the likely cause of this high memory usage is some bug in the OR-tools CP solver.

Because of this, making useful experiments on the decomposition is very difficult, especially considering that we do not have a clear understandable cause of this high memory usage, beyond that it is probably related to the Element constraint. Because of this, we were unable to construct any meaningful experiments using the decomposition described in Section 4.

1

https://hisham.hm/htop/, visited on 2018-05-14

(33)

Instance Tasks Gaps Iteration 0 Iteration 1 Iteration 2

official1 836 241 1.470 1.970 2.470

official2 683 234 0.600 0.940 1.420

Instance1 20180 641 0.839 1.120 1.420

Instance5 4872 1197 0.866 1.150 1.450

Micro 2114 640 0.900 0.900 0.900

Multi1 1088 256 0.810 0.814 0.825

Single1 896 256 0.858 0.860 0.870

Table 5: Results of memory usage test: the column “Iteration i” gives the memory usage, in GB, after i iterations of the loop have been performed.

Figure 7: The data in Table 5 in a plot. The y axis is the memory usage in GB, and the x axis is the number of iterations.

We attempted to replicate this behaviour without using the instance data files, as the data files cannot be shared to third parties. However we could not replicate the issue without the data and could therefore not provide a meaningful error report to the Google OR-tools team.

5.2 Branching Strategy Evaluation

CP solver performance is usually dependent on a good choice of variable and value selection strategies. In order to get some understanding of which strategies are effective, a clean CP model for the full problem is tested across a selection of branching strategies. Due to the memory restrictions described in Section 5.1, only a few small instances can be tested in this experiment.

Because of the small size of the instances tested, these results should not be

taken as a strong indication of the properties of larger instances.

(34)

5.2.1 The CP Model and Search Strategies

The CP model has all the constraints described in Section 4.2, and was initially made as a prototype to verify the correctness of later models. In this experiment, this model was tested using a variety of search strategies.

One of the search strategies tested is branching not only on the TST [i]

variables but also on the border [i] variables introduced by the dependency constraint described in Section 4.2.5 and the whichinterval [i] variables in- troduced by the starting interval constraint introduced in Section 4.2.4. All the border [i] and whichinterval [i] variables have relatively small domains, and seem likely to have high propagation impact on the domains of other variables when fixed, as each value represents a potentially high-impact deci- sion, such as which start interval a task uses. Therefore, even if searching on the TST [i] variables is sufficient, it might be beneficial to search on border [i]

and whichinterval [i] first, before searching on TST [i] variables.

In order to test this, two search strategies were created. One is called the multi-phase brancher, labelled as Multi in the result tables. This search strategy is to first select an unfixed border [i] at random, and then to select its maximum domain value. Because each border [i] is a 0-1 variable, this does in practice mean that the brancher will always explore the possibility that a border [i] variable is 1 first. This choice was made as if a border [i]

variable were part of a chain (see Section 4.2.6): setting it to 1 will have a greater impact as it forces all other border [i] variables in that chain to have the value 0. Once all border [i] variables have been fixed, the brancher will select the whichinterval [i] variable with the largest number of domain values, and split the domain in the middle, exploring the lower half first.

Once all whichinterval [i] variables have been fixed, it will use some strategy to fix the TST [i] variables.

The second search strategy is to directly start searching on TST [i], la- belled as Single in the result tables. For TST [i] variables, a wider range of different heuristics were tested, as early results indicated that these heuris- tics had a greater impact on solver runtime. For variable selection (selecting which of the TST [i] variables to partition) these strategies were tested:

• MIN SIZE, the variable with the smallest amount of domain values.

• MAX SIZE, the variable with the largest amount of domain values.

• RANDOM, a variable decided at random.

For value selection (selecting how to partition a TST [i] variable domain and which new sub-problem to explore first) these strategies were tested:

• ASSIGN RANDOM VALUE, try a value at random.

• ASSIGN MAX VALUE, try the largest value.

(35)

• ASSIGN MIN VALUE, try the smallest value.

• ASSIGN CENTER VALUE, try the centre value first.

• SPLIT LOWER HALF, split the variable domain around the centre, choosing the lower part first.

• SPLIT UPPER HALF, split the variable domain around the centre, choosing the upper part first.

The OR-tools source code 2 defines the centre of a domain as half the sum of its smallest and largest values. What tiebreaker is used for variable selection strategies, as well as if the centre value itself is considered to be in the upper or lower half is neither documented anywhere (to our knowledge), nor easily found in the source code.

5.2.2 Results

All combinations of these strategies were tested across a set of data files, using both the Single and the Multi branching strategy. The data collected is both solver runtime in milliseconds (ms) and the number of failures, which is the number of times the CP solver has ended up in a sub-problem with no solution due to its search strategy, as well as the number of branches, which is the number of times a variable selection is done. The OR-tools CP solver (to our knowledge) only supports serial (non-parallel) solving. The CPU used for this test is an AMD E2-7110. 3 The instances tested and their properties are described in Table 6.

The full results of this experiment can be found in Appendix A. The result of these tests is that many heuristics have very similar performance across multiple instances, which in combination with the low numbers of failures and branches seems to indicate that these instances are trivial to solve for CP solvers using some assignment-based variable selection strategy.

Across all instances tested, each could be solved by at least 4 strategy combi- nations in under 5 CPU minutes. There also does not seem to be a significant difference between the multi-phase and single-phase search strategies.

However, we must stress that larger instances could not be tested due to unexpectedly high memory usage and that these instances are small com- pared to those solved in previous work [3, 2]. Therefore, the results of this experiment should not be taken as a strong indication to the properties of larger problem instances.

2

https://github.com/google/or-tools/blob/master/ortools/constraint -

solver/constraint solver.h, lines 356 to 379 as of commit-id:

0777e4d12ff9b45397c3aa6bbe14fc72b19bf453

3

4 core, 1.8 GHz clock speed, 2 MB L2 cache, https://products.amd.com/en-

ca/search/APU/AMD-E-Series-Processors/AMD-E2-Series-APU-for-Laptops/E2-7110-

with-Radeon%E2%84%A2-R2-Graphics/139

(36)

Instance Tasks Dependencies Has Solution

Official 2 836 752 no

Official 1 683 832 yes

Micro 2114 1216 yes

Single1 896 512 yes

Pico2 385 320 yes

Table 6: Properties of instances tested in Section 5.2

6 Discussion

We cover various possible improvements to the decomposition, as well as make other possibly valuable observations.

6.1 CP Beta Model

When combining an Alpha/Beta decomposition with the usage of CP and MIP solvers, there are four possible combinations to explore: a MIP Alpha model and a MIP Beta model, which is what is described in [2]; a CP Alpha model and a MIP Beta model, which is presented in this report; a CP Alpha model and a CP Beta model, and a MIP Alpha model and a CP Beta model.

The reason CP Beta models have yet to be explored is that we find it unlikely to improve the decomposition considering that CP models seem unlikely to benefit significantly from the non-overlapping constraint being split up into one constraint per gap.

MIP Beta models exploit linear relaxation that likely allows them to identify which task start time values are of significance, and they can there- fore explore the for CP very large space of possible start times in a much more effective manner than CP solvers. The Beta sub-problem was clearly built with the strengths and weaknesses of MIP in mind, and therefore we find it unlikely that any other technology will outperform MIP for that par- ticular sub-problem. Because of this, it seems highly unlikely that CP Beta models will outperform existing MIP Beta models.

6.2 Redesign of the Decomposition

In our opinion, the fundamental idea of decomposing our problem into an

Alpha model and a Beta model is sound. However, the exact mechanisms of

how the Alpha and Beta models are communicating can likely be improved

to accommodate a CP Alpha model more effectively.

References

Related documents

I dag uppgår denna del av befolkningen till knappt 4 200 personer och år 2030 beräknas det finnas drygt 4 800 personer i Gällivare kommun som är 65 år eller äldre i

In case of PRIMARY AND SECONDARY notifications, the eNodeB broadcasts one Paging message followed by one SIB1 message containing information about SIB10 and SIB11 messages that

In personnel scheduling, a variable represents a staff member at a certain time and these variables are assigned work tasks or shifts.. Examples of constraints are that a limited

The main contributions of this thesis are: (1) empirical evidence of both the suitability of applying constraint programming to solve the test oracle problem and the effectiveness

A novel integrated combinatorial model is proposed (C2) that for the first time matches the majority of the subtasks of global register allocation and instruction scheduling handled

There is plenty of future work to be done, ranging from implementing more invariants, constraints, and neighbourhoods to improving the algorithms for incrementally maintaining

Since all the relevant information as to which constraints should be turned into invariants is already present in the intermediate model, this can be done by posting the constraint

In this project, the GDI is used as a source of data where the Request Handler finds the shortest route between two POIs, which allows it to store the route as a candidate on one