Constraint Programming Techniques
Constraint Programming Techniques
Contents
1 Constraint Programming 3
4 Constraints 7
5 Data Initialization 9
7 Set operators 11
8 Sensitivity analysis 11
9 Logical constraints 13
10 Scheduling 14
12 Notations 17
1
Ho Chi Minh City International University Constraint Programming
Industrial Systems Engineering Department Lecturer: Phan Nguyen Ky Phuc
17 Precedence Constraint 23
19 Sequencing variables 25
20 State function 26
20.1 Syntax and examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
21 Cumulative functions 28
21.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
21.2 Cumulative expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
21.3 Constraints on cumul function expression . . . . . . . . . . . . . . . . . . . . 29
21.4 Combine several cumul function expression . . . . . . . . . . . . . . . . . . . 29
25 Example of dependent setup time for for jobshop with parallel machine 37
27 Setting CP parameters 41
1 Constraint Programming
• No gap measure
Example
1 u s i n g CP;
2 i n t nbPerm = . . . ;
3 r a n g e r = 1 . . nbPerm ;
4 int dist [ r ] [ r ] = . . . ;
5 int flow [ r ] [ r ] = . . . ;
6 execute {
7 cp . param . t i m e L i m i t =30;
8 }
9 dvar i n t perm [ 1 . . nbPerm ] i n r ;
10 dexpr i n t c o s t [ i i n r ] [ j i n r ] = d i s t [ i ] [ j ] ∗ f l o w [ perm [ i ] ] [ perm [ j ] ] ;
11 minimize sum ( i i n r , j i n r ) c o s t [ i ] [ j ] ;
12 s u b j e c t to {
13 a l l D i f f e r e n t ( perm ) ;
14 };
1 minimize . . . ;
2 s u b j e c t to {
3 m == max( i i n 1 . . 1 0 ) x [ i ] ;
4 ....
5 }
• Declare variables
• Objective function
• Constraints
An attribute in tuple can be declared with keyword key this keyword can be used directly
to access to to tuple.
For example
1 u s i n g CP;
2
6 dvar i n t e r v a l i t v [ i i n Acts ] s i z e i . d u r a t i o n ;
7 dvar s e q u e n c e s e q i n i t v t y p e s a l l ( i i n Acts ) i . type ;
8
9 execute {
10 s e t t i n g s . bigmapthreshold = 100000;
11 }
12
13 s u b j e c t to {
14 noOverlap ( s e q ) ;
15 b e f o r e ( seq , i t v [<"Two" >] , i t v [<"One" >]) ;
16 }
17
21 execute {
22 w r i t e l n ( seq ) ;
23 for (a in Solution ) {
24 w r i t e l n ( a . a c t . name ) ;
25 }
26 }
or
1 { tupleName } setName = . . . ;
For Example
1 s e t o f ( Node ) NodeSet = . . . ;
2 {Node} NodeSet = . . . ;
3 { i n t } SetA = . . . ;
4 { s t r i n g } SetB = . . . ;
4 Constraints
1 c o n s t r a i n t c t S u p p l y [ rangeX ] [ rangeY ] ;
5 Data Initialization
OPL offers a variety of ways of initializing data. One particularly useful feature is the
possibility of associating indices with values to avoid various kinds of errors.
*.mod file
1 { s t r i n g } Products = . . . ;
2 { s t r i n g } Components = . . . ;
3 f l o a t Demand [ Products ] [ Components ] = . . . ;
4 f l o a t P r o f i t [ Products ] = . . . ;
5 f l o a t Stock [ Components ] = . . . ;
6 dvar f l o a t+ P r o d u c t i o n [ Products ] ;
When using index:value pairs, the delimiters #[ and ]# must be used instead of [ and ]. The
*[Link]
1 { s t r i n g } Products = . . . ;
2 { s t r i n g } Resources = . . . ;
3 t u p l e productData {
4 f l o a t demand ;
5 float insideCost ;
6 f l o a t outsideCost ;
7 f l o a t consumption [ R e s o u r c e s ] ;
8 }
9 productData Product [ Products ] = . . . ;
10 f l o a t Capacity [ R e s o u r c e s ] = . . . ;
11 dvar f l o a t+ I n s i d e [ Products ] ;
12 dvar f l o a t+ O u t s i d e [ Products ] ;
The *[Link]
1 Products = { " k l u s k i " , " c a p e l l i n i " , " f e t t u c i n e " } ;
2 Resources = { " f l o u r " , " eggs " };
3 Product = #[
4 k l u s k i : < 1 0 0 , 0 . 6 , 0 . 8 , [ 0 . 5 , 0 . 2 ] >,
5 c a p e l l i n i : < 2 0 0 , 0 . 8 , 0 . 9 , [ 0 . 4 , 0 . 4 ] >,
6 f e t t u c i n e : < 300 , 0 . 3 , 0 . 4 , [ 0 . 3 , 0.6 ] >
7 ]#;
8 Capacity = [ 2 0 , 40 ] ;
The instruction
1 ProductData p r o d u c t [ Products ] = . . . ;
declares an array with number of arrays equal to Product array and each element has type
of ProductData
Or
1 i n t MaxValue = max( r i n ArrayX ) Cap [ r ] ;
2 dvar i n t Y[ arrayY ] i n 0 . . MaxValue ;
7 Set operators
1 | Expression " in " Expression
2 | E x p r e s s i o n " not i n " E x p r e s s i o n
3 | Expression " i n t e r " Expression
4 | E x p r e s s i o n " union " E x p r e s s i o n
5 | Expression " d i f f " Expression
6 | Expression " symdiff " Expression
8 Sensitivity analysis
Example
1 u s i n g CPLEX;
2 i n t nbPro =5;
3 i n t nbRes =4;
4 r a n g e Pro = 1 . . nbPro ;
5 r a n g e Res = 1 . . nbRes ;
6 i n t A[ Res ] [ Pro ] = [ [ 1 , 2 , 2 , 1 , 3 ] , [ 0 , 1 , 3 , 4 , 5 ] , [ 2 , 2 , 2 , 1 , 0 ] , [ 4 , 5 , 6 , 2 , 3 ] ] ;
7 i n t Cap [ Res ] = [ 1 0 0 0 , 2 0 0 0 , 1 0 0 0 , 3 0 0 0 ] ;
8 i n t Ben [ Pro ] = [ 2 , 3 , 3 , 2 , 4 ] ;
9 dvar f l o a t+ X[ Pro ] ;
10 c o n s t r a i n t ctRes [ Res ] ;
11 maximize sum ( p i n Pro )X[ p ] ∗ Ben [ p ] ;
12 s u b j e c t to {
13 f o r a l l ( r i n Res ) {
14 ctRes [ r ] : // Resource c o n s t r a i n t
9 Logical constraints
• ||: Logic OR
• !: Logic NOT
• ! =: Different form
• ==: Equivalent
1 (X == 0 ) | | (Y >= 2 0 ) ;
2 (X== 0 ) && ( Z != 2 0 ) ;
3 (X>= 2 0 ) | | (V >= 2 0 ) => R>= 2 0 ;
10 Scheduling
Most scheduling applications consist of interval decision variables that have start and
end time.
Interval variable a has domain dom(a) is a subset of {⊥} ∪ {[s, e)|s, e ∈ Z, s ≤ e}
If interval variable a is fixed, then:
• For a fixed interval that is absent, x(a) = 0 and the start, end and length are undefined.
To access to the different attributes of an interval variable, it can be used : startOf, endOf,
lengthOf, and sizeOf
For example:
s(a) if x(a)
startOf (a, dval) =
dval otherwise
Other functions:
• startOf(a,dval)
• endOf(a,dval)
• lengthOf(a,dval)
• sizeOf(a,dval)
• presenceOf(a)
Let a and b be the optional interval variable, the presenceOf constraint is useful when
• a is present then b must be present is equivalent to presenceOf (a) => presenceOf (b).
• if a and b are optional, and just one of them is allowed in the solution
To evaluate the piecewise linear function on a given bound of an interval, it can be used :
startEval, endEval, lengthEval, and sizeEval,
In the case of optional intervals an integer value dval must be specified which represents the
value of the expression when the interval is absent. If this value is omitted, it is supposed
to be 0.
For example:
F (s(a)) if x(a)
startEval(a, F, dval) =
dval otherwise
Other functions:
• startEval(a,dval)
• endEval(a,dval)
• lengthEval(a,dval)
• sizeEval(a,dval)
12 Notations
The main notations used throughout the scheduling section are defined here. Vectors are
denoted by capital letters, for example Y . The size of a vector Y is denoted |Y |.
If n = |Y |, the vector is denoted Y = (y1 , · · · , yn ).
• S: vector of (n + 1) elements
• T : vector of (n + 1) elements
Stepwise function
A stepwise function is a special case of the piecewise linear function, where all slopes are
equal to 0 and the domain of F are integer. A stepwise function F (t) is defined by a tuple
F = stepwise(V, T ) where:
Examples
The following piecewise and stepwise function are depicted in the diagram
• A stepwise function with value 0 before 0, 100 on [0, 20), value 60 on [20, 30), and
value 100 later on:
1 s t e p F u n c t i o n F2 = s t e p w i s e { 0−>0; 100−>20; 60−>30; 100 } ;
2
Sometimes the intensity of "work" is not the same during the whole interval.
For example
• A worker who does not work during weekends (his work intensity during weekends is
0 %)
• On Friday he works only for half a day (his intensity during Friday is 50%).
• For this worker, 7 man-days of work will span for longer than just 7 days.
In this example 7 man-days represents what we call the size of the interval; that is, what
the length of the interval would be if the intensity function was always at 100 %.
To model such situations, you can specify a range for the size of an interval variable
and an integer stepwise intensity function F.
For a fixed present interval the following relation will be enforced at any solution between
the start, end, size sz of the interval and the integer granularity G (by default, the intensity
function is expressed as a percentage so the granularity G is 100):
Z e(a)
F (t)
sz(a) ≤ d(t) < sz(a) + 1
s(a) G
If no intensity is specified, it is supposed to be the constant full intensity function = 100%
so in that case sz(a) = l(a). Note that the size is not defined for absent intervals
The following figure depicts an interval variable of size 14 with its intensity function. A valid
solution is represented where the interval starts at 10 and ends at 27. Indeed in this case:
Z e(a)
F (t) 1420
sz(a) ≤ d(t) = = 14.2
s(a) G 100
• The size
• The intensity F
Example
1 dvar i n t e r v a l a [ o p t i o n a l [ ( I s O p t i o n a l ) ] ]
2 [ i n StartMin . . EndMax ]
3 [ s i z e SZ | i n SZMin . . SZMax ]
4 [ intensity F]
5 // Example j : job , s : s t a t i o n , m: machine
6 r a n g e Time = 0 . . 2 0 0 ;
7 dvar i n t e r v a l X[< j , s ,m> i n TaskSet ] o p t i o n a l i n Time s i z e ProTime[< j , s > ] ;
8
The rest is used for developed on other language such as C++ or Java
Syntax :
• The second range may be omitted in case the size and length of the interval variable
are necessarily equal.
• When the values are fixed, the ranges min · · · max are replaced by a single value.
• For instance, the following display represents a fixed interval variable of size 5 that is
present, starts at 10 and ends at 35:
1 A1 [ 1 : 10 −− ( 5 ) 25 −−> 3 5 ]
CP Optimizer provides constraints for modelling restrictions that an interval cannot start,
cannot end or cannot overlap a set of fixed dates.
17 Precedence Constraint
Span constraint:
span(a, {b1 , · · · , bn }) states that interval a starts together with the first present interval from
{b1 , · · · , bn } and ends together with the last one.
Alternative constraint:
alternative (a, {1, · · · , bn }) states that if interval a is presented then exactly one of intervals
{b1 , · · · , bn } is present and a starts and ends together with this chosen one.
Alternative constraint:
This can also be specified by a non-negative integer cardinality c, alternative(a, {b1 , .., bn }, c).
In this case, c interval variables that will be selected among the set b1 , · · · , bn and those c
selected intervals will have to start and end together with interval variable a.
Synchronize constraint:
synchronize(a, {b1 , .., bn }) makes intervals b1 , · · · , bn start and end together with interval a
(if a is present).
1 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
2 ∗ OPL 1 2 . 1 0 . 0 . 0 Model
3 ∗ Author : LAPTOP
4 ∗ C r e a t i o n Date : Nov 2 , 2022 a t 9 : 4 8 : 4 2 PM
5 ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
6 u s i n g CP;
7 i n t numJ=7;
8 i n t numM=3;
9 r a n g e rang eJ = 1 . . numJ ;
10 r a n g e rangeM = 1 . .numM;
11 r a n g e rangeTime = 0 . . 2 0 ;
12 t u p l e JM{
13 i n t job ;
14 i n t machine ;
15 };
16 {JM} JMSet={<1,1>,<1,3>,<2,1>,<2,2>,<2,3>,
17 <3,1>,<3,2>,<3,3>,<4,2>,<4,3>,<5,1>,<6,1>,<7,1>,<7,2>};
18 i n t r [ range J ] = [ 5 , 0 , 2 , 3 , 2 , 4 , 5 ] ;
19 i n t d [ rang eJ ] = [ 1 2 , 1 0 , 2 0 , 1 5 , 1 8 , 1 9 , 1 4 ] ;
20 i n t p [ rang eJ ] = [ 3 , 1 0 , 9 , 4 , 6 , 5 , 3 ] ;
21 i n t w [ r angeJ ] = [ 2 , 3 , 3 , 2 , 1 , 2 , 3 ] ;
22 dvar b o o l e a n Z [ ra ngeJ ] ;
23 dvar i n t e r v a l X[< j ,m> i n JMSet ] o p t i o n a l i n rangeTime s i z e p [ j ] ;
24
19 Sequencing variables
20 State function
A state function is a set of non-overlapping intervals over which the function maintains a
particular non- negative integer state.
In between those intervals, the state of the function is not defined, typically because of an
ongoing transition between two states
A state function example:
The notions of start and end alignment which is particularly useful for modeling parallel
batches.
• alwaysEqual(f, s, e, v[, aligns , aligne ]): whenever a is present, f must be defined ev-
erywhere between the start and the end of a and be constant and equal to non-negative
value v.
– If algns is true, it means that a must start at the beginning of the interval where
f is in state s.
– If algne is true, it means that a must end at the end of the interval where f in
state s.
• alwaysIn(f, a, vmin , vmax ) means that when a is present, between the start and the end
of a, function f , if defined, must belong to the range [vmin, vmax] where 0 ≤ V min ≤
V max.
• alwaysNoState(f,s,e);
• alwaysNoState(f,a);
• alwaysIn(f,u,v,hmin , hmax );
• alwaysIn(f,a,hmin , hmax );
21 Cumulative functions
21.1 Introduction
• An activity usually increases the cumulated resource usage function at its start time
and decreases it when it releases the resource at its end time (pulse function).
Let u, v ∈ Zand h, hmin , hmax ∈ Z + and a be an interval variable, the following elementary
cumul function expressions are illustrated in the following figure:
• pulse(u,v,h)
• step(u,h)
• pulse(a,h)
• pulse(a,hmin , hmax )
• stepAtStart(a,h)
• stepAtStart(a,hmin , hmax )
• stepAtEnd(a,h)
• stepAtEnd(a,hmin , hmax )
• alwaysIn(f, u, v, hmin , hmax ) means that the values of f must be in the range [hmin , hmax ]
on the interval [u, v).
• alwaysIn(f, a, hmin , hmax ) means that if a is present, the values of f must be in the
range [hmin , hmax ] between s(a) and e(a).
• f ≤ hmax means that f cannot take values greater than hmax . It is equivalent to
alwaysIn(f, −∞, +∞, 0, hmax )
• f ≥ hmin means that f cannot take values lower than hmin . It is equivalent to
alwaysIn(f, −∞, +∞, hmin , +∞)
1 /∗ ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
2 ∗ OPL 1 2 . 9 . 0 . 0 Model
3 ∗ Author : kyphuc
4 ∗ C r e a t i o n Date : Jun 5 , 2020 a t 7 : 1 4 : 1 0 PM
5 ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/
6 u s i n g CP;
7 i n t nbJob =3;
8 i n t nbMachine =4;
9 r a n g e Job = 1 . . nbJob ;
10 r a n g e Machine = 1 . . nbMachine ;
11 t u p l e Node {
12 i n t machine ;
13 i n t job ;
14 };
15 tuple SolidArc {
16 i n t job ;
17 i n t pre ;
18 i n t suc ;
19 };
20 /∗
21 Job 1 : 1−2−3
22 Job 2 : 2−1−4−3
23 Job 3 : 1−2−4
24 ∗/
25 {Node} NodeSet ={<1,1>,<2,1>,<3,1>,
26 <2,2>,<1,2>,<4,2>,<3,2>,
27 <1 ,3 > , <2 ,3 > , <4 ,3 >};
28 { S o l i d A r c } S o l i d A r c S e t ={ <1 ,1 ,2 > , <1 ,2 ,3 > ,
29 <2 ,2 ,1 > , <2 ,1 ,4 > , <2 ,4 ,3 > ,
30 <3 ,1 ,2 > , <3 ,2 ,4 >};
31 i n t ProTime [ NodeSet ] = [ 1 0 , 8 , 4 ,
32 8 ,3 ,5 ,6 ,
33 4 ,7 ,3];
34 r a n g e Time = 0 . . 3 0 ;
35 dvar i n t e r v a l X[ i i n NodeSet ] i n Time s i z e ProTime [ i ] ;
36 dvar s e q u e n c e seqM [m i n Machine ] i n a l l (<m, j > i n NodeSet ) X[<m, j > ] ;
37 dvar s e q u e n c e s e q J [ j i n Job ] i n a l l (<m, j > i n NodeSet )X[<m, j > ] ;
38 dvar i n t+ Cmax ;
39
40 execute {
41 cp . param . TimeLimit =4∗60; // s e t u p t h e time l i m i t
42 }
43
44 minimize Cmax ;
45 s u b j e c t to {
46
47 f o r a l l ( m i n Machine ) {
48 noOverlap ( seqM [m] ) ;
49 }
50 f o r a l l ( j i n Job ) {
51 noOverlap ( s e q J [ j ] ) ;
52 }
53 f o r a l l ( n i n NodeSet ) {
54 Cmax >= endOf (X[ n ] ) ;
55 }
56 f o r a l l (< j , p , s> i n S o l i d A r c S e t ) {
57 b e f o r e ( s e q J [ j ] ,X[<p , j >] ,X[< s , j >]) ;
58 }
59
60 }
61 e x e c u t e RESULT{
62 f o r (m i n Machine )
63 {
64 w r i t e l n ( seqM [m] ) ;
65 }
66 }
Note:
In this example, range of Time is set from 0 to 30 when the optimal Cmax = 28. If time
range is set smaller than 28, it cannot find the feasible solution.
10 t u p l e Node{
11 int station ;
12 i n t job ;
13 }
14 tuple SolidArc {
15 i n t job ;
16 i n t pre ;
17 i n t suc ;
18 }
19 /∗
20 Job 1 : 1−2−3
21 Job 2 : 2−1−4−3
22 Job 3 : 1−2−4
23 ∗/
24 {Node} NodeSet ={<1,1>,<2,1>,<3,1>,
25 <2,2>,<1,2>,<4,2>,<3,2>,
26 <1 ,3 > , <2 ,3 > , <4 ,3 >};
27 { S o l i d A r c } S o l i d A r c S e t ={ <1 ,1 ,2 > , <1 ,2 ,3 > ,
28 <2 ,2 ,1 > , <2 ,1 ,4 > , <2 ,4 ,3 > ,
29 <3 ,1 ,2 > , <3 ,2 ,4 >};
30 r a n g e Job = 1 . . nbJob ;
31 r a n g e Sta = 1 . . nbSta ;
32 i n t ProTime [ NodeSet ] = [ 1 0 , 8 , 4 , 8 , 3 , 5 , 6 , 4 , 7 , 3 ] ;
33 i n t nbMach [ Sta ] = [ 2 , 2 , 2 , 2 ] ;
34 dvar i n t e r v a l X[ r i n NodeSet ] i n 0 . . 3 0 s i z e ProTime [ r ] ;
35 dvar s e q u e n c e seqS [ s i n Sta ] i n a l l (<s , j > i n NodeSet )X[< s , j > ] ;
36 dvar s e q u e n c e s e q J [ j i n Job ] i n a l l (<s , j > i n NodeSet )X[< s , j > ] ;
37 cumulFunction f [ s i n Sta ]=sum(<s , j > i n NodeSet ) p u l s e (X[< s , j > ] , 1 ) ;
38 dvar i n t+ Cmax ;
39 e x e c u t e SETTING{
40 cp . param . TimeLimit =3∗60;
41 }
42 minimize Cmax ;
43 s u b j e c t to {
44 Cmax==max( n i n NodeSet ) endOf (X[ n ] ) ;
45 f o r a l l ( s i n Sta ) {
46 f [ s]<=nbMach [ s ] ;
47 }
48
49 f o r a l l (< j , p , s> i n S o l i d A r c S e t ) {
50 b e f o r e ( s e q J [ j ] ,X[<p , j >] ,X[< s , j >]) ;
51 }
52
53 f o r a l l ( j i n Job ) {
54 noOverlap ( s e q J [ j ] ) ;
55 }
56 }
Note:
In this job shop each station has more than one machine. As a result of this, it requires a
cumul function to represent how many machines are occupied in a station at a specific time
t
keyword: types
The keyword types is used to associate a non-negative integer (called the type of the interval
variable) with each interval variable in a sequence.
Model files (.mod)
1 dvar i n t e r v a l a [ i i n . . . ] ...; // I n t e r v a l v a r i a b l e s
2 i n t T[ i in . . . ] = . . . ; // I n t e g e r non−n e g a t i v e t y p e s
3 dvar s e q u e n c e s i n a l l ( i i n . . . ) a [ i ] t y p e s a l l ( i i n . . . ) T [ i ] ;
Types usage
Types are often used when the setup time needs to be considered
The integer type is used in the form of a noOverlap constraint that uses a transition distance.
The transition distance is modeled as a tuple set < t1 , t2 , dmin > that specifies a minimal
distance between pairs of types (t1 , t2 ).
It states that if a2 of type t2 is scheduled after a1 of type t1 in the sequence, a distance of
at least dmin must separate the end of a1 from the start of a2 (provided that a1 and a2 are
present).This constraint can be written as
1 t u p l e t r i p l e t { i n t t 1 ; i n t t 2 ; i n t dmin ; } ;
2 { triplet } tdistance = . . . ;
3
4 constraints {
5 noOverlap ( seq , t d i s t a n c e ) ;
6 }
16 tuple SolidArc {
17 i n t job ;
18 i n t pre ;
19 i n t suc ;
20 };
21
22 t u p l e Setup {
23 i n t type1 ;
24 i n t type2 ;
25 i n t time ;
26 };
27 /∗
28 Job 1 : 1−2−3
29 Job 2 : 2−1−4−3
30 Job 3 : 1−2−4
31 ∗/
32 { Setup } S e t u p S e t ={ <1 ,5 ,3 > , <5 ,1 ,3 > , <5 ,8 ,2 > , <8 ,5 ,1 > , <1 ,8 ,3 > , <8 ,1 ,5 > ,
33 <2 ,4 ,3 > , <4 ,2 ,1 > , <2 ,9 ,5 > , <9 ,2 ,5 > , <4 ,9 ,3 > , <9 ,4 ,1 > ,
34 <3 ,7 ,2 > , <7 ,3 ,1 > ,
35 <6 ,10 ,1 > , <10 ,6 ,1 >};
36 {NodeType} NodeTypeSet ={ <1 ,1 ,1 > , <2 ,1 ,2 > , <3 ,1 ,3 > ,
37 <2 ,2 ,4 > , <1 ,2 ,5 > , <4 ,2 ,6 > , <3 ,2 ,7 > ,
38 <1 ,3 ,8 > , <2 ,3 ,9 > , <4 ,3 ,10 >};
39 {Node} NodeSet={<m, j >|<m, j , t> i n NodeTypeSet } ;
40 { S o l i d A r c } S o l i d A r c S e t ={ <1 ,1 ,2 > , <1 ,2 ,3 > ,
41 <2 ,2 ,1 > , <2 ,1 ,4 > , <2 ,4 ,3 > ,
42 <3 ,1 ,2 > , <3 ,2 ,4 >};
43 i n t ProTime [ NodeSet ] = [ 1 0 , 8 , 4 ,
44 8 ,3 ,5 ,6 ,
45 4 ,7 ,3];
46 r a n g e Time = 0 . . 2 0 0 0 ;
47 dvar i n t e r v a l X[ i i n NodeSet ] i n Time s i z e ProTime [ i ] ;
48 dvar s e q u e n c e seqM [m i n Machine ] i n a l l (<m, j > i n NodeSet ) X[<m, j >] t y p e s a l l (<
m, j , t> i n NodeTypeSet ) t ;
49 dvar s e q u e n c e s e q J [ j i n Job ] i n a l l (<m, j > i n NodeSet )X[<m, j > ] ;
50 dvar i n t+ Cmax ;
51
52 execute {
53 cp . param . TimeLimit =4∗60; // s e t u p t h e time l i m i t
54 }
55
56 minimize Cmax ;
57 s u b j e c t to {
58 f o r a l l ( m i n Machine ) {
59 noOverlap ( seqM [m] , S e t u p S e t ) ;
60 }
61 f o r a l l ( j i n Job ) {
62 noOverlap ( s e q J [ j ] ) ;
63 }
64 f o r a l l ( n i n NodeSet ) {
65 Cmax >= endOf (X[ n ] ) ;
66 }
67 f o r a l l (< j , p , s> i n S o l i d A r c S e t ) {
68 b e f o r e ( s e q J [ j ] ,X[<p , j >] ,X[< s , j >]) ;
69 }
70 }
71 e x e c u t e RESULT{
72 f o r (m i n Machine )
73 {
74 w r i t e l n ( seqM [m] ) ;
75 }
76 }
Note:
The statement
1 dvar s e q u e n c e seqM [m i n Machine ] i n a l l (<m, j > i n NodeSet ) X[<m, j >] t y p e s a l l (<
m, j , t> i n NodeTypeSet ) t ;
will take the Type attribute values in < m, j, t > NodeTypeSet In the above example each
task must have a type number to identify the dependent setup time between 2 tasks.
38 t u p l e Setup {
39 i n t type1 ;
40 i n t type2 ;
41 i n t time ;
42 };
43 { Setup } S e t u p S e t ={ <1 ,5 ,3 > , <5 ,1 ,3 > , <5 ,8 ,2 > , <8 ,5 ,1 > , <1 ,8 ,3 > , <8 ,1 ,5 > ,
44 <2 ,4 ,3 > , <4 ,2 ,1 > , <2 ,9 ,5 > , <9 ,2 ,5 > , <4 ,9 ,3 > , <9 ,4 ,1 > ,
64 i n t ProTime [ NodeSet ] = [ 1 0 , 8 , 4 ,
65 8 ,3 ,5 ,6 ,
66 4 ,7 ,3];
67 i n t MachOnSta [ Sta ] = [ 2 , 2 , 2 , 2 ] ;
68 r a n g e Time = 0 . . 2 0 0 ;
69 dvar i n t e r v a l X[< j , s ,m> i n TaskSet ] o p t i o n a l i n 0 . . 1 0 0 s i z e ProTime[< j , s > ] ;
70 dvar s e q u e n c e seqM [m i n Mach ] i n a l l (< j , s ,m> i n TaskSet )X[< j , s ,m>] t y p e s a l l (<
j , s ,m, t> i n TaskTypeSet ) t ;
71 dvar s e q u e n c e s e q J [ j i n Job ] i n a l l (< j , s ,m> i n TaskSet )X[< j , s ,m> ] ;
72 dvar i n t+ Cmax ;
73
74 execute {
75 cp . param . TimeLimit =4∗60; // s e t u p t h e time l i m i t
76 }
77
78 minimize Cmax ;
79 s u b j e c t to {
80
81 f o r a l l ( m i n Mach ) {
82 noOverlap ( seqM [m] , S e t u p S e t ) ;
83 }
84 f o r a l l ( j i n Job ) {
85 noOverlap ( s e q J [ j ] ) ;
86 }
87 f o r a l l ( n i n TaskSet ) {
88 Cmax >= endOf (X[ n ] ) ;
89 }
90
99 }
100 e x e c u t e RESULT{
101 f o r (m i n Mach )
102 {
103 w r i t e l n ( seqM [m] ) ;
104 }
105 }
The [Link] rocess takes responsibility to save the feasible solution into proper file
27 Setting CP parameters
For example:
1 cp . param . D e f a u l t I n f e r e n c e L e v e l = "Low"
2
3 // Another example
4
5 var p = cp . param ;
6 p . logPeriod = 10000;
7 p . searchType = " D e p t h F i r s t " ;
8 p . timeLimit = 600;
28.1 Introduction
A search phase defines instantiation strategies to help the embedded CP Optimizer search
algorithm.
Most common use
For instance
The variables x will be instantiated before variables y; then, once x and y are instantiated,
variables z will be instantiated. In some particularly well-designed models, passing such an
order can have a dramatic impact on the solving time.
1 execute {
2 var f = cp . f a c t o r y ;
3 cp . s e t S e a r c h P h a s e s ( f . s e a r c h P h a s e ( x ) , f . s e a r c h P h a s e ( y ) , f . s e a r c h P h a s e ( z ) ) ;
4 }
Step 2:
1 cp . s e t S e a r c h P h a s e s ( phase1 , phase2 ) ;
A mono-criterion search phase can also contain a variable chooser and a value chooser and
belongs to one of 3 types
Type 1:
an array of variables to instantiate (or fix)
1 var phase1 = f . s e a r c h P h a s e ( x ) ;
Type 2:
• a variable chooser that defines how the next variable to instantiate is chosen, and
• a value chooser that defines how values are chosen when instantiating variables.
1 var phase1 = f . s e a r c h P h a s e ( f . s e l e c t L a r g e s t ( f . v a r I n d e x ( x ) ) ,
2 f . s e l e c t L a r g e s t ( f . e x p l i c i t V a l u e E v a l ( v a l u e s , varEval , 0 ) ) ) ;
Type 3:
• variable chooser that defines how the next variable to instantiate is chosen, and
• a value chooser that defines how values are chosen when instantiating variables.
1 var phase1 = f . s e a r c h P h a s e ( x ,
2 f . s e l e c t L a r g e s t ( f . varIndex ( x ) ) ,
3 f . s e l e c t L a r g e s t ( f . e x p l i c i t V a l u e E v a l ( v a l u e s , varEval , 0 ) ) ) ;
28.3 Explanation
Variable evaluators
To chose decision variables, the variables are evaluated by an [Link] predefined
evaluators exist in CP Optimizer.
For instance
[Link]() returns the current size of the domain of the variable that is
being evaluated
[Link](dvar int[]) that returns the index in the array vars of the evaluated
variable.
List of variable evaluators
• [Link]()
• [Link]()
• [Link]()
• [Link]()
• [Link]()
• [Link]()
• [Link]()
• [Link](dvar int[])
Variable selectors
In order to select a decision variable with an evaluator, an instance of a variable selector
needs to be created with the evaluator as an input. Here are two functions in the C++
API that can create such selectors:
List of variable choosers
• selectSmallest(eval): will select the variable in the search phase that has the smallest
domain
• selectLargest(eval): will select the variable in the search phase that has the smallest
domain
A search phase or an array of search phases defined with selectors can be given to an in-
stance of the optimizer by invoking the method setSearchPhases before calling solve or
startNewSearch:
1 cp . s e t S e a r c h P h a s e s ( phase1 ) ;
2 cp . s o l v e ( ) ;
• [Link]()
• [Link]()
• [Link]()
• [Link](int[])
Example
1 var f = cp . f a c t o r y ;
2 var s e l e c t V a r = f . s e l e c t S m a l l e s t ( f . domainSize ( ) ) ;
3 var s e l e c t V a l u e = f . selectRandomValue ( ) ;
4 var assignRoom = f . s e a r c h P h a s e ( room , s e l e c t V a r , s e l e c t V a l u e ) ;
5 var a s s i g n T e a c h e r = f . s e a r c h P h a s e ( t e a c h e r , s e l e c t V a r , s e l e c t V a l u e ) ;
6 var a s s i g n S t a r t = f . s e a r c h P h a s e ( S t a r t , s e l e c t V a r , s e l e c t V a l u e ) ;
7 cp . s e t S e a r c h P h a s e s ( a s s i g n T e a c h e r , a s s i g n S t a r t , assignRoom ) ;
Setting limits
1 execute {
2 cp . param . F a i l L i m i t = 5 0 0 ;
3 cp . param . TimeLimit = 2 0 ;
4 }
1 var p = cp . param ;
2 p . logPeriod = 10000;
3 p . searchType = " D e p t h F i r s t " ;
4 p . timeLimit = 600;
7 minimize s t a t i c L e x ( e1 , e2 ) ;
8 // t r y i n g t o minimize c o s t f i r s t
1 staticLexFull ( goals [ ] ,
2 weights [ ] ,
3 priorities [] ,
4 abstol [ ] ,
5 reltol []) ;
1 u s i n g CP;
2 i n t n=6;
3 i n t H a l f=n d i v 2 ;
4 range F i r s t H a l f = 1 . . Half ;
5 r a n g e L a s t H a l f = n−H a l f + 1 . . n ;
6 range S t a t e s = 0 . . 1 ;
7 r a n g e Bord = 0 . . ( n+1) ;
8 range I n t e r i o r = 1 . . n ;
9
10 r a n g e o b j = 0 . . ( n∗n ) ;
11
12 tuple neighbors {
13 i n t row ;
14 int col ;
15 }
16
17 { n e i g h b o r s } Neighbor =
18 {<(−1) ,( −1) >,<(−1) ,0>,<(−1) ,1 > , <0 ,( −1) >,<0,1>,<1,(−1) >,<1,0>,<1,1>};
19
25
26 maximize s t a t i c L e x ( k p i s ) ;
27
28 s u b j e c t to {
29 Obj == sum ( i , j i n Bord ) L i f e [ i ] [ j ] ;
30
31 f o r a l l ( i , j in I n t e r i o r ) {
32 2∗ L i f e [ i ] [ j ] − sum ( nb i n Neighbor ) L i f e [ i+nb . row ] [ j+nb . c o l ] <= 0 ;
33 3∗ L i f e [ i ] [ j ] + sum ( nb i n Neighbor ) L i f e [ i+nb . row ] [ j+nb . c o l ] <= 6 ;
34 f o r a l l ( o r d e r e d n1 , n2 , n3 i n Neighbor ) {
35 −L i f e [ i ] [ j ]+ L i f e [ i+n1 . row ] [ j+n1 . c o l ]+ L i f e [ i+n2 . row ] [ j+n2 . c o l ]+ L i f e [ i+
n3 . row ] [ j+n3 . c o l ]−sum ( nb i n Neighbor : nb!=n1 && nb!=n2 && nb!=n3 ) Life
[ i+nb . row ] [ j+nb . c o l ] <= 2 ;
36 }
37 }
38 f o r a l l ( j i n Bord ) {
39 L i f e [ 0 ] [ j ] == 0 ;
40 L i f e [ j ] [ 0 ] == 0 ;
41 L i f e [ j ] [ n+1] == 0 ;
42 L i f e [ n + 1 ] [ j ] == 0 ;
43 }
44 f o r a l l ( i i n Bord : i <n ) {
45 L i f e [ i ] [ 1 ] + L i f e [ i + 1 ] [ 1 ] + L i f e [ i + 2 ] [ 1 ] <= 2 ;
46 L i f e [ 1 ] [ i ]+ L i f e [ 1 ] [ i +1]+ L i f e [ 1 ] [ i +2] <= 2 ;
47 L i f e [ i ] [ n]+ L i f e [ i + 1 ] [ n]+ L i f e [ i + 2 ] [ n ] <= 2 ;
48 L i f e [ n ] [ i ]+ L i f e [ n ] [ i +1]+ L i f e [ n ] [ i +2] <= 2 ;
49 }
50 sum ( i i n F i r s t H a l f , j i n Bord ) L i f e [ i ] [ j ] >=
51 sum ( i i n L a s t H a l f , j i n Bord ) L i f e [ i ] [ j ] ;
52 sum ( i i n Bord , j i n F i r s t H a l f ) L i f e [ i ] [ j ] >=
53 sum ( i i n Bord , j i n L a s t H a l f ) L i f e [ i ] [ j ] ;
54 }
55
56
57 execute {
58 f o r ( var j i n Bord1 ) w r i t e l n ( k p i s [ j ] ) ;
59 }
1 u s i n g CP;
2 i n t n=9;
3 i n t H a l f=n d i v 2 ;
4 range F i r s t H a l f = 1 . . Half ;
5 r a n g e L a s t H a l f = n−H a l f + 1 . . n ;
6 range S t a t e s = 0 . . 1 ;
7 r a n g e Bord = 0 . . ( n+1) ;
8 range I n t e r i o r = 1 . . n ;
9
10 r a n g e o b j = 0 . . ( n∗n ) ;
11
12 tuple neighbors {
13 i n t row ;
14 int col ;
15 }
16
17 r a n g e Bord1 = 0 . . 3 ;
18 i n t t i m e s [ i i n Bord1 ] = 5+ i ;
19 f l o a t gaps [ i i n Bord1 ] = 0 . 0 1 ;
20
21 execute {
22 c p l e x . lex_TimeLimits = t i m e s ;
23 c p l e x . lex_GapLimits = gaps ;
24 }
25
26 { n e i g h b o r s } Neighbor =
27 {<(−1) ,( −1) >,<(−1) ,0>,<(−1) ,1 > , <0 ,( −1) >,<0,1>,<1,(−1) >,<1,0>,<1,1>};
28
34 f l o a t w e i g t h s [ i i n Bord1 ] = i +1;
35 f l o a t a b s t o l [ i i n Bord1 ] = 0 . 0 0 0 1 ;
36 f l o a t r e l t o l [ i i n Bord1 ] = 0 . 0 0 0 1 ;
37 i n t p r i o r i t i e s [ i i n Bord1 ] = i ;
38 maximize s t a t i c L e x F u l l ( k p i s , w e i g t h s , p r i o r i t i e s , a b s t o l , r e l t o l ) ;
39
40 s u b j e c t to {
41 Obj == sum ( i , j i n Bord ) L i f e [ i ] [ j ] ;
42
43 f o r a l l ( i , j in I n t e r i o r ) {
44 2∗ L i f e [ i ] [ j ] − sum ( nb i n Neighbor ) L i f e [ i+nb . row ] [ j+nb . c o l ] <= 0 ;
45 3∗ L i f e [ i ] [ j ] + sum ( nb i n Neighbor ) L i f e [ i+nb . row ] [ j+nb . c o l ] <= 6 ;
46 f o r a l l ( o r d e r e d n1 , n2 , n3 i n Neighbor ) {
47 −L i f e [ i ] [ j ]+ L i f e [ i+n1 . row ] [ j+n1 . c o l ]+ L i f e [ i+n2 . row ] [ j+n2 . c o l ]+ L i f e [ i+
n3 . row ] [ j+n3 . c o l ]−sum ( nb i n Neighbor : nb!=n1 && nb!=n2 && nb!=n3 ) Life
[ i+nb . row ] [ j+nb . c o l ] <= 2 ;
48 }
49 }
50 f o r a l l ( j i n Bord ) {
51 L i f e [ 0 ] [ j ] == 0 ;
52 L i f e [ j ] [ 0 ] == 0 ;
53 L i f e [ j ] [ n+1] == 0 ;
54 L i f e [ n + 1 ] [ j ] == 0 ;
55 }
56 f o r a l l ( i i n Bord : i <n ) {
57 L i f e [ i ] [ 1 ] + L i f e [ i + 1 ] [ 1 ] + L i f e [ i + 2 ] [ 1 ] <= 2 ;
58 L i f e [ 1 ] [ i ]+ L i f e [ 1 ] [ i +1]+ L i f e [ 1 ] [ i +2] <= 2 ;
59 L i f e [ i ] [ n]+ L i f e [ i + 1 ] [ n]+ L i f e [ i + 2 ] [ n ] <= 2 ;
60 L i f e [ n ] [ i ]+ L i f e [ n ] [ i +1]+ L i f e [ n ] [ i +2] <= 2 ;
61 }
62 sum ( i i n F i r s t H a l f , j i n Bord ) L i f e [ i ] [ j ] >=
63 sum ( i i n L a s t H a l f , j i n Bord ) L i f e [ i ] [ j ] ;
64 sum ( i i n Bord , j i n F i r s t H a l f ) L i f e [ i ] [ j ] >=
65 sum ( i i n Bord , j i n L a s t H a l f ) L i f e [ i ] [ j ] ;
66 }
67
68
69 e x e c u t e SCRIPT {
70 var m u l t i = c p l e x . g e t M u l t i O b j N s o l v e s ( ) ;
71 writeln ( " cplex . getMultiObjNsolves " + multi ) ;
72 f o r ( var i = 0 ; i < m u l t i ; i ++) {
73 w r i t e l n ( i + " MultiObjTime " + c p l e x . g e t M u l t i O b j I n f o ( " MultiObjTime " , i ) ) ;
74 w r i t e l n ( i + " MultiObjObjValue " + c p l e x . g e t M u l t i O b j I n f o ( " MultiObjObjValue "
, i));
75 w r i t e l n ( i + " MultiObjBestObjValue " + c p l e x . g e t M u l t i O b j I n f o ( "
MultiObjBestObjValue " , i ) ) ;
76 writeln ( i + " MultiObjPriority " + cplex . getMultiObjInfo ( " MultiObjPriority "
, i));
77 w r i t e l n ( " \n" ) ;
78 }
79 }
80
81
82 execute {
83 f o r ( var j i n Bord1 ) w r i t e l n ( k p i s [ j ] ) ;
84 }
Neighborhood operations are used to constrain life variables within a grid. Each cell's life value (`Life[i][j]`) is constrained in relation to the sum of its neighboring cells' values. Two constraints are applied: one ensuring that the cell value plus twice its sum of neighbors should not exceed zero, and another ensuring three times the cell value plus the sum of neighbors does not exceed six. These constraints control the interdependence of life states, reflecting the local interactions typical in spatial constraints models .
The range of time in job shop scheduling examples is handled by setting specific boundaries for time variables. In the model, time is defined within a range, for instance, from 0 to 30 or 0 to 2000, as seen in the examples. This range dictates the time frame for scheduling all jobs and operations, ensuring that no activity can be scheduled outside these boundaries, enforcing temporal discipline in scheduling .
The non-overlapping nature of job sequences on machines and within jobs is ensured by applying the `noOverlap` constraint on both `seqM` and `seqJ`. For each machine and job, the constraint prevents intervals from overlapping by checking the sequence of operations, thus enforcing that each job's operations are completed in the defined order without temporal conflicts .
The optimization strategy used in the grid-like structure involves maximizing a weighted sum of key performance indicators (`kpis`). The model uses `staticLexFull` to optimize for this objective, balancing between absolute and relative tolerances (`abstol` and `reltol`) as well as priorities. This method ensures that the optimization process accounts for both the scale of variables and their priorities, leading to more balanced and effective solutions .
`Cmax` is calculated as the maximum end time of all scheduled jobs. In the model, it is constrained by ensuring that for all jobs in each node of the `NodeSet`, the end time of the interval `X[n]` must be less than or equal to `Cmax`. This ensures that `Cmax` is the maximum of these end times and is minimized in the objective function .
Solid arcs represent the precedence constraints in scheduling models by defining the order in which operations should occur, noted as predecessor-successor relationships in the `SolidArcSet`. These arcs dictate that certain operations must be scheduled before others, reducing the solution space by eliminating sequences that violate these precedence constraints. Therefore, they are critical for ensuring logical and feasible scheduling, preventing cycles, and facilitating efficient resource allocation .
The model uses the `noOverlap` constraint to ensure that no jobs overlap on a single machine. This is achieved by defining sequences for each machine (`seqM`) and for each job (`seqJ`). The `noOverlap` constraint is applied to these sequences, preventing any two intervals from overlapping, hence ensuring that each machine processes only one job at a time without exceeding available time slots .
Setup times influence the job shop scheduling problem by affecting the sequencing of operations on each machine type. The setup time between different operations must be considered to avoid overlaps and ensure the efficient use of resources. This is handled by defining `SetupSet` with tuples indicating the setup time required for transitions between different operation types, which is then used in the `noOverlap` constraint to avoid operations overlapping on the same machine .
Cumulative functions in the job shop scheduling model are significant as they allow the modeling of resource limitations across multiple jobs or machines. They consider both the start and end times of tasks and track resource usage over time. This ensures that the cumulative resource consumption never exceeds the available capacity of shared resources, such as machine availability or manpower, which is crucial for computational resource efficiency and for adhering to resource constraints in scheduling .
The `pulse` function is used in cumul function expressions to model the resource consumption by an activity over its duration, starting when the activity starts and stopping when it ends. The `stepAtEnd` function adds an increment to the cumul function value at the end of the specified interval. These functions support modeling dynamic resource utilization over time, vital for solving scheduling and resource allocation problems .