Basic formal parameters
forall statements.
The simplest formal parameter has the form
p in S
where p is the formal parameter and S is the set from which p takes its values.
The set S can be:
an integer range, as in
int n=6; int s = sum(i in 1..n) i*i;a string set, as in
{string} Products ={"car","truck"}; float cost[Products] =[12000,10000]; float maxCost = max(p in Products) cost[p];or a tuple set, as in
{string} Cities = { "Paris", "London", "Berlin" }; tuple Connection { string orig; string dest; } {Connection} connections = { <"Paris","Berlin">,<"Paris","London">}; float cost[connections] = [ 1000, 2000 ]; float maxCost= max(r in connections) cost[r];
If you need to filter the range of the formal parameters using conditions, the formal parameter then takes the form
p in S : filtering condition
and assigns to p all elements of S according to the filter applied.
For instance, in the excerpt
int n=8;
dvar int a[1..n][1..n];
subject to
{
forall(i in 1..8)
forall(j in 1..8: i < j)
a[i][j] >= 0;
}
the constraint a[i][j] >= 0 is modeled for
all i and j such that 1 ≤ i <
j ≤ 8.
OPL does not support aggregates in filter expressions. For example:
For an expression such as:
{int} notFirst = {i | i in 1..10 : card({j | <i,j> in pairs}) == 0};the type check displays the error: "Aggregate set is currently not supported for filter expressions."
For an expression such as:
{int} notFirst = {i | i in 1..10 : sum(<i,j>in pairs) i == 0};the type check displays the error: "Aggregate sum is currently not supported for filter expressions."
Several parameters can often be combined together to produce more compact statements. For instance, the declaration
int s = sum(i,j in 1..n: i < j) i*j;
is equivalent to
int s = sum(i in 1..n) sum(j in 1..n: i < j) i*j;
which is less readable.
The declaration
int s = sum(i in 1..n, j in 1..m) i*j;
is equivalent to
int s = sum(i in 1..n) sum(j in 1..m) i*j;
These parameters can, of course, be subject to filtering conditions. The excerpt
forall(i,j in 1..n : i < j)
a[i][j] >= 0;
is equivalent to
forall(i in 1..n, j in 1..n : i<j)
a[i][j] >= 0;
Here is an even more compact form:
forall(ordered i,j in 1..n)
a[i][j] >= 0;
Indeed, in many applications one is interested, given a set S, in stating filters or conditions over all pairs (i, j) of elements of S satisfying i < j in the ordering associated with S. In this excerpt
{T} S = ...;
forall(ordered s, t in S)...;
forall(s in S, t in S: ord(S,s) < ord(S,t)) ...
the first forall line is equivalent to the second
one and illustrates the functionality ordered, often
useful in practical applications. T can be one of the types int, float, string,
or a tuple type.
This ordering does not refer to the ordering associated with type T but to the order of the items within the set.