Escolar Documentos
Profissional Documentos
Cultura Documentos
A tutorial
c
Dr. C. Richard Wu and Mr. Tomasz Drabas
2010
Introduction
1. Brief description of the tutorials that will be held
2. Brief description of ILOG OPL Studio program
(a) Open the application
(b) Basic overview of panels, what are they used for
(c) Description of 2 files used to build models in OPL (.dat, .mod)
in .mod file first we declare data, then variables and decision
variables, and, at the end, the objective function and conditions
in .dat file the order of data declared MUST be the same, as in
.mod file
(d) How to build a model in ILOG OPL Studio (where and what to add
to make the whole model working)
2.1
Problem description
The problem seeks for the shortest path, from origin to destination. It consists
of inter-connected nodes (with costs assigned to each arc) refer to the Figure 1
on page 2. In this example nodes are equivalents of cities, and cost is the time
in minutes between each node.
2.2
Problem formulation
We are to minimize the time to get from origin (node #1) to destination (node
#10) through the connection of flights (refer to Figure 1 ). Hence, our aim is to:
M inimize
In the above equation, when we decide to choose the flight from city e.g.
#1 to #2, we assign 1 to our decision variable; if we do not choose this path
1
2
70
25
67
50
69
63
56
19
67
72
31
87
10
97
52
51
45
72
17
69
18
61
29
79
73
54
15
85
69
Figure 1: Network with flight times between city pairs, source: Massoud:2004,
page 11
we would assign 0 to that. So, we can write that down as follows, i.e. binary
decision variables:
1 if arc (i, j) is chosen
xi,j =
(1)
0 otherwise
In our problem we have 3 sets of constraints:
1. source node: the flight originates from node #1, and we can use only 1 arc
from that node. Thus, we have:
x1,2 + x1,3 + x1,4 = 1
2. transshipment nodes: all other nodes (except origin and destination) are
transshipment nodes, so everything that comes in must go out. In other
words, the net flow through the node must equal 0. See the example for
node #2 (refer to the Figure 1):
x1,2 + x3,2 + x4,2 x2,3 x2,4 x2,5 x2,6 x2,7 = 0
3. destination node: the flight must end in the destination node; in our case it
is node #10. Thus, we have:
x5,10 + x6,10 + x7,10 + x9,10 = 1
In summary, we can rewrite the above problem as follows (a.k.a. the formulation of the problem):
Objective function
min
X X
ci,j xi,j
(2)
for j 6= 1
(3)
iM jM
Subject to
X
x1,j = 1
jM
xj,i
jM
(4)
kM
xi,m = 1
for m
(5)
iM
where:
sets:
M
set of nodes
indices:
i,j,k
indices of nodes
parameters:
ci,j
m
=
=
decision variable:
xi,j
2.3
2.3.1
First, we must declare data and their types. We have m nodes (in our case
m = 10). So, in file shrtstPath.mod we will put:
int m=...;
range M=1..m;
The ...; after int m=, in OPL syntax, tells the program to look for the
data in the .dat file (in our situation, in the shrtstPath.dat). Alternatively, we
could write int m=10; and the program would not need to search for this
data in the data file. The range command produces an array, starting from
1 up to m. After that we declare the flow matrix (we do not have it in the
problem formulation), by having:
int flow[M][M]=...;
The above command tells the program, to look for the 10-by-10 (m-by-m)
matrix in the .dat file. Why do we need it? Because without it our model
would not know whether there is a unidirectional connection between node
3
We make our model to create another 10-by-10 matrix with costs (representing flight time) between two nodes. Having all the data declared, we need to
assert our decision variablerecall equation (1). In OPL we simply put:
dvar boolean x[M][M];
The word boolean describes a binary variable, so having only two values: 0
and 1exactly what we are looking for.
In ILOG OPL Studio, one can declare other data types: Integers to evoke
variables that can be only of integer values (like in our declaration of m; notice,
that our f low and c matrices have data of type int as well), Stringsused to
declare text variables (which we will learn how to declare during Tutorial 2),
and Floats, that are used to declare variables with real numbers.
2.3.2
Building model
Now, we can transform our model into OPL language. Recall equation (2). In
OPL we will have:
minimize
sum( i in M, j in M )
( x[i][j] * c[i][j] );
P
Notice, that we do not need to use double signs because we have already
summed up across i and j. Now go back to equations (3), (4) and (5), and
compare them with the following code:
subject to{
cfFirstNode:
sum( j in M) x[1][j] * flow[1][j] == 1;
forall (i in 2..(m-1))
cfNetworkFlow:
sum( j in M ) x[i][j] * flow[i][j]
- sum ( k in M ) x[k][i] * flow[k][i] == 0;
cfLastNode:
sum( i in M) x[i][m] * flow[i][10] == 1;
}
Isnt it straightforward? As you can see we use information from the f low
matrix to introduce information about the connections between particular nodes
into the model. The last thing we need to do here is to display the results. In
OPL we make that as follows:
execute DISPLAY_RESULTS
{
writeln("The model has chosen following routes:");
for (var i in M)
{
for (var j in M)
{
if (x[i][j] == 1)
{
writeln("Route x",i,j," has been chosen! ");
}
}
}
}
We use double loops for (...) because our decision variable xi,j has two
dimensions. Then, we filter out (using if(...) command) only those routes
that were chosen as a shortest paththe program writes the results (using
writeln(...);) on the screen. Notice, that in the writeln(...); the text
information that does not change ("Route x" and " has been chosen!")
we put in the quotation marks, while variables that change (i,j) are outside
the quotation marks, precedented and followed by commas.
2.3.3
Now, lets take a brief look at our shrtstPath.dat file. As mentioned before, the
order of data declaration we did earlier in the .mod file MUST be conserved
in .dat file. Therefore, first we need to declare, how many nodes we have in
our model (m = 10;), followed by the connection matrix (flow), and matrix
of connection costs (c). Therefore, we have:
m = 10;
flow
[0 1
[0 0
[0 1
[0 1
[0 0
[0 0
[0 0
[0 0
[0 0
[0 0
=
1
1
0
1
0
0
0
0
0
0
[
1
1
1
0
0
0
0
0
0
0
0
1
1
1
0
1
0
0
0
0
0
1
1
1
1
0
0
0
0
0
0
1
0
0
1
1
0
1
1
0
0
0
0
0
1
1
1
0
1
0
0
0
0
1
1
1
1
1
0
0
0]
0]
0]
0]
1]
1]
1]
0]
1]
0]];
c = [
[0 70
[0 0
[0 25
[0 19
[0 0
[0 0
[0 0
[0 0
[0 0
[0 0
63
25
0
29
0
0
0
0
0
0
56
19
29
0
0
0
0
0
0
0
0
73
69
67
0
18
0
0
0
0
0
50
61
45
18
0
0
0
0
0
0
79
0
0
67
72
0
17
31
0
0
0
0
0
69
52
17
0
15
0
0
0
0
85
54
51
31
15
0
0
0]
0]
0]
0]
87]
97]
72]
0]
69]
0]];
Results
When you hit the run button, you will get the results. How to read them?
Again, straightforward (just like we wanted) we should first fly to node #4
(starting from #1). After that we fly to node #6, and then go directly to node #10
from there. Too simple and you dont believe it?try some other ways, add
the time and see, if you can travel from node 1 to 10 in less than 198 minutes,
as our model indicated.
Multi-commodity problem
3.1
Problem description
3.2
Problem formulation
As given in the problem description, we are to minimize the total cost of transporting those two commodities through our network. Therefore, we can write
the following formulation of the problem (refer to Figure 2):
40
35
50
25
30
20
30
30
30
10
3
7
8
4
M inimize
50
50
50
50
50
min
X X X
ci,j xi,j,k
(6)
iM jM kK
s.t.
xt,i,k
tM
xi,t,k = Bi,k ,
i M, k K
(7)
tM
xi,j,k Ui,j ,
i M, j M
(8)
kK
where:
sets:
M =
K =
indices:
=
i,j,t
=
k
set of nodes
set of commodities
indices of nodes
index of commodity
parameters:
ci,j
Bi,k
Ui,j
=
=
=
decision variable:
xi,j,k = decision variable tells us how much commodity k
should be sent through arc i, j
3.3
3.3.1
Declaring data
All the inputs are straightforward just compare them with descriptions of
variables from above. How about our objective function?
dvar int+ x[M][M][K];
What does int+ mean? It means that this decision variable can have only
positive integer values. If we had had int the set of possible values would
have ranged from to . Any ideas why we constrain our decision variable
for positive values only?
3.3.2
Building model
As in the previous example, we have to display the results, i.e. how many
units of each commodity send through each arc. We use 3 loops for (for each
subindex i, j and k) to display only those arcs, that actually take their part in
the shipment:
execute DISPLAY_RESULTS
{
writeln("The model has chosen following routes:");
for (var i in M)
{
for (var j in M)
{
for (var k in K)
{
if (x[i][j][k] == 0)
{
}
else
{
writeln("Route x",i,j," has been chosen
to send ",x[i][j][k]," commodities
of ",k," type!");
}
}
}
}
}
3.3.3
Data file
U = [
[0 0 500
[0 0 500
[0 0 0 0
[0 0 0 0
[0 0 0 0
[0 0 0 0
[0 0 0 0
];
50 0 0 0]
50 0 0 0]
500 500 500]
50 50 50]
0 0 0]
0 0 0]
0 0 0]
B = [
[-40 -35]
[-50 -25]
[0 0]
[0 0]
[30 20]
[30 30]
[30 10]
];
c = [
[0
[0
[0
[0
[0
[0
[0
];
0
0
0
0
0
0
0
5
7
0
0
0
0
0
8
4
0
0
0
0
0
0
0
1
3
0
0
0
0
0
5
4
0
0
0
0]
0]
8]
4]
0]
0]
0]
When you take a look at U you can see that for arc 1, 3 there are 500 units
allowed to be transported. As a matter of fact, it can be any other large number
e.g. 1,000. Note, however, that, as per our capacity constraint for node #4,
every arc connecting to and from node #4 is constrained at 50 (as we were told).
The second matrix that needs a small explanation is B (standing for demand). The negative values indicate that e.g. node #1 provides 40 units of
commodity 1 and 35 units of commodity 2. You can see that nodes #3 and
#4 have 0s; it comes from our assumption, that everything that comes into the
transshipment nodes must go out, so the balance needs to be 0. The last 3 nodes
receive goods, so their balances need to be positive.
3.3.4
Results
The model attained minimum cost at 1250. The flow of commodities through
the network is presented in the Figure 3
This manual was prepared in LATEX
10
40
35
40
35
30
20
5
30
20
50
25
0
10
30
20
30
20
30
30
30
10
3
7
20
5
8
30
10
11