Set Expressions
Set expressions
Set expressions play an important role in the construction of index domains of indexed identifiers, as well as in constructing the domain of execution of particular indexed statements. The AIMMS language offers a powerful set of set expressions, allowing you to express complex set constructs in a clear and concise manner.
Constant set expressions
A set expression is evaluated to yield the value of a set. As with all expressions in AIMMS, set expressions come in two forms, constant and symbolic. Constant set expressions refer to explicit set elements directly, and are mainly intended for set initialization. The tabular format of set initialization is treated in Tabular Expressions.
Symbolic set expressions
Symbolic set expressions are formulas that can be executed to result in a set. The contents of this set can vary throughout the execution of your model depending on the values of the other model identifiers referenced inside the symbolic formulas. Symbolic set expressions are typically used for specifying index domains. In this section various forms of set expressions will be treated.
Syntax
set-primary:
set-expression:
Set references
The simplest form of set expression is the reference to a set. The reference can be scalar or indexed, and evaluates to the current contents of that set.
Enumerated Sets
Enumerated sets
An enumerated set is a set defined by an explicit enumeration of its elements. Such an enumeration includes literal elements, set element expressions, and (constant or symbolic) element ranges. An enumerated set can be either a simple or a relation. If you use an integer element range, an integer set will result.
Constant enumerated sets
Enumerated sets come in two flavors: constant and symbolic. Constant
enumerated sets are preceded by the keyword DATA
, and must only
contain literal set elements. These set elements do not have to be
contained in single quotes unless they contain characters other than the
alpha-numeric characters, the underscore, the plus or the minus sign.
Example
The following simple set and relation assignments illustrate constant enumerated set expressions.
Cities := DATA { Amsterdam, Rotterdam, 'The Hague', London, Paris, Berlin, Madrid } ;
DutchRoutes := DATA { (Amsterdam, Rotterdam ), (Amsterdam, 'The Hague'),
(Rotterdam, Amsterdam ), (Rotterdam, 'The Hague') } ;
Symbolic enumerated sets
Any enumerated set not preceded by the keyword DATA
is considered
symbolic. Symbolic enumerated sets can also contain element parameters.
In order to distinguish between literal set elements and element
parameters, all literal elements inside symbolic enumerated sets must be
quoted.
Examples
The following two set assignments illustrate the use of enumerated sets
that depend on the value of the element parameters SmallestCity
,
LargestCity
and AirportCity
.
ExtremeCities := { SmallestCity, LargestCity } ;
Routes := { (LargestCity, SmallestCity), (AirportCity, LargestCity ) } ;
The following two set assignments contrast the semantics between constant and symbolic enumerated sets.
SillyExtremes := DATA { SmallestCity, LargestCity } ;
! contents equals { 'SmallestCity', 'LargestCity' }
ExtremeCities := { SmallestCity, LargestCity, 'Amsterdam' };
! contents equals e.g. { 'The Hague', 'London', 'Amsterdam' }
The syntax of enumerated set expressions is as follows.
Syntax
enumerated-set:
element-tuple:
tuple-component:
All elements in an enumerated set must have the same dimension.
Element range
By using the ..
operator, you can specify an element range. An
element range is a sequence of consecutively numbered elements. The
following set assignments illustrate both constant and symbolic element
ranges. Their difference is explained below.
NodeSet := DATA { node1 .. node100 } ;
FirstNode := 1;
LastNode := 100;
IntegerNodes := { FirstNode .. LastNode } ;
The syntax of element ranges is as follows.
Syntax
element-range:
range-bound:
Prefix and postfix strings
A range bound must consists of an integer number, and can be preceded or followed by a common prefix or postfix string, respectively. The prefix and postfix strings used in the lower and upper range bounds must coincide.
Constant range
If you use an element range in a static enumerated set expression
(i.e. preceded by the keyword DATA
), the range can only refer to
explicitly numbered elements, which need not be quoted. By padding the
numbered elements with zeroes, you indicate that AIMMS should create all
elements with the same element length.
Constant range versus ElementRange
As the begin and end elements of a constant element range are literal
elements, you cannot use a constant element range to create sets with
dynamically changing border elements. If you want to accomplish this,
you should use the ElementRange
function, which is explained in
detail in Set Functions. Its use in the following
example is self-explanatory. The following set assignments illustrate a
constant element range and its equivalent formulation using the
ElementRange
function.
NodeSet := DATA { node1 .. node100 } ;
PaddedNodes := DATA { node001 .. node100 } ;
NodeSet := ElementRange( 1, 100, prefix: "node", fill: 0 );
PaddedNodes := ElementRange( 1, 100, prefix: "node", fill: 1 );
Symbolic integer range
Element ranges in a symbolic enumerated set can be used to create integer ranges. Now, both bounds can be numerical expressions. Such a construct will result in the dynamic creation of a number of integer elements based on the value of the numerical expressions at the range bounds. Such integer element ranges can only be assigned to integer sets (see Integer Sets). An example of a dynamic integer range follows.
IntegerNodes := { FirstNode .. LastNode } ;
In this example IntegerNodes
must be an integer set.
Nonconsecutive range
If the elements in the range are not consecutive but lie at regular
intervals from one another, you can indicate this by adding a BY
modifier with the proper interval length. For static enumerated sets the
interval length must be a constant, for dynamic enumerated sets it can
be any numerical expression. The following set assignments illustrate a
constant and symbolic element range with nonconsecutive elements.
EvenNodes := DATA { node2 .. node100 by 2 } ;
StepSize := 2;
EvenIntegerNodes := { FirstNode .. LastNode by StepSize } ;
Element tuples
When specifying element tuples in an enumerated set expression, it is
possible to create multiple tuples in a concise manner using cross
products. You can specify multiple elements for a particular tuple
component in the cross product either by grouping single elements using
the [
and ]
operators or by using an element range, as shown
below.
DutchRoutes := DATA { ( Amsterdam, [Rotterdam, 'The Hague'] ),
( Rotterdam, [Amsterdam, 'The Hague'] ) } ;
! creates { ( 'Amsterdam', 'Rotterdam' ), ( 'Amsterdam', 'The Hague' ),
! ( 'Rotterdam', 'Amsterdam' ), ( 'Rotterdam', 'The Hague' ) }
Network := DATA { ( node1 .. node100, node1 .. node100 ) } ;
The assignment to the set Network
will create a set with 10,000
elements.
Constructed Sets
Constructed sets
A constructed set expression is one in which the selection of elements is constructed through filtering on the basis of a particular condition. When a constructed set expression contains an index, AIMMS will consider the resulting tuples for every element in the binding set.
Example
The following set assignments illustrate some constructed set
expressions, assuming that i
and j
are indices into the set
Cities
.
LargeCities := { i | Population(i) > 500000 } ;
Routes := { (i,j) | Distance(i,j) } ;
RoutesFromLargestCity := { (LargestCity, j) in Routes } ;
In the latter assignment route tuples are constructed from
LargestCity
(an element-valued parameter) to every city j
, where
additionally each created tuple is required to lie in the set
Routes
.
Syntax
constructed-set:
binding-domain:
binding-tuple:
binding-element:
Binding domain
The tuple selection in a constructed set expression behaves exactly the same as the tuple selection on the left-hand side of an assignment to an indexed parameter. This means that all tuple components can be either an explicit quoted set element, a general set element expression, or a binding index. The tuple can be subject to a logical condition, further restricting the number of elements constructed.
Set Operators
Four set operators
There are four binary set operators in AIMMS: Cartesian product, intersection, union, and difference. Their notation and precedence are given in this table. Expressions containing these set operators are read from left to right and the operands can be any set expression. There are no unary set operators.
Operator |
Notation |
Precedence |
---|---|---|
intersection |
|
3 (high) |
difference |
|
2 |
union |
|
2 |
Cartesian product |
|
1 (low) |
Example
The following set assignments to integer sets and Cartesian products of integer sets illustrate the use of all available set operators.
S := {1,2,3,4} * {3,4,5,6} ; ! Intersection of integer sets: {3,4}.
S := {1,2} + {3,4} ; ! Union of simple sets:
S := {1,3,4} + {2} + {1,2} ; ! {1,2,3,4}
S := {1,2,3,4} - {2,4,5,7} ; ! Difference of integer sets: {1,3}.
T := {1,2} cross {1,2} ; ! The cross of two integer sets:
! {(1,1),(1,2),(2,1),(2,2)}.
The precedence and associativity of the operators is demonstrated by the assignments
T := A cross B - C ; ! Same as A cross (B - C).
T := A - B * C + D ; ! Same as (A - (B * C)) + D.
T := A - B * C + D * E ; ! Same as (A - (B * C)) + (D * E).
The operands of union, difference, and intersection must have the same dimensions.
T := {(1,2),(1,3)} * {(1,3)} ; ! Same as {(1,3)}.
T := {(1,2),(1,3)} + {(i,j) | a(i,j) > 1} ; ! Union of enumerated
! and constructed set of
! the same dimension.
T := {(1,2),(1,3)} + {(1,2,3)} ; ! ERROR: dimensions differ.
Set Functions
Set functions
A special type of set expression is a call to one of the following set-valued functions
A user-defined function.
The ElementRange
and SubRange
functions are discussed in this
section, while the functions ConstraintVariables
and
VariableConstraints
are discussed in MathematicalProgram Declaration and Attributes. The syntax of
and use of tags in function calls is discussed in
Internal Functions.
The function ElementRange
The ElementRange
function allows you to dynamically create or
change the contents of a set of non-integer elements based on the value
of integer-valued scalars expressions.
Arguments
The ElementRange
function has two mandatory integer arguments.
first, the integer value for which the first element must be created, and
last, the integer value for which the last element must be created.
In addition, it allows the following four optional arguments.
incr, the integer-valued interval length between two consecutive elements (default value 1),
prefix, the prefix string for every element (by default, the empty string),
postfix, the postfix string (by default, the empty string), and
fill, a logical indicator (0 or 1) whether the numbers must be padded with zeroes (default value 1).
If you use any of the optional arguments you must use their formal argument names as tags.
Example
Consider the sets S
and T
initialized by the constant set
expressions
NodeSet := DATA { node1 .. node100 } ;
PaddedNodes := DATA { node001 .. node100 } ;
EvenNodes := DATA { node2 .. node100 by 2 } ;
These sets can also be created in a dynamic manner by the following
applications of the ElementRange
function.
NodeSet := ElementRange( 1, 100, prefix: "node", fill: 0 );
PaddedNodes := ElementRange( 1, 100, prefix: "node", fill: 1 );
EvenNodes := ElementRange( 2, 100, prefix: "node", fill: 0, incr: 2 );
The SubRange
function
The SubRange
function has three arguments:
a simple set,
the first element, and
the last element.
The result of the function is the subset ranging from the first to the last element. If the first element is positioned after the last element, the empty set will result.
Example
Assume that the set Cities
is organized such that all foreign cities
are consecutive, and that FirstForeignCity
and LastForeignCity
are element-valued parameters into the set Cities
. Then the
following assignment will create the subset ForeignCities
of
Cities
ForeignCities := SubRange( Cities, FirstForeignCity, LastForeignCity ) ;
Iterative Set Operators
Iterative operators
Iterative operators form an important class of operators that are especially designed for indexed expressions in AIMMS. There are set, element-valued, arithmetic, statistical, and logical iterative operators. The syntax is always similar.
Syntax
iterative-expression:
Explanation
The first argument of all iterative operators is a binding domain. It consists of a single index or tuple of indices, optionally qualified by a logical condition. The second argument and further arguments must be expressions. These expressions are evaluated for every index or tuple in the binding domain, and the result is input for the particular iterative operator at hand. Indices in the expressions that are not part of the binding domain of the iterative operators are referred to as outer indices, and must be bound elsewhere.
Set-related iterative operators
AIMMS possesses the following set-related iterative operators:
the
Sort
operator for sorting the elements in a domain,the
NBest
operator for obtaining the \(n\) best elements in a domain according to a certain criterion, andthe
Intersection
andUnion
operators for repeated intersection or union of indexed sets.
Reordering your data
Sorting the elements of a set is a useful tool for controlling the flow of execution and for presenting reordered data in the graphical user interface. There are two mechanism available to you for sorting set elements
the
OrderBy
attribute of a set, andthe
Sort
operator.
Sorting semantics
The second and further operands of the Sort
operator must be
numerical, element-valued or string expressions. The result of the
Sort
operator will consist of precisely those elements that satisfy
the domain condition, sorted according to the single or multiple
ordering criteria specified by the second and further operands.
The OrderBy attribute discusses the expressions that can be used for
specifying an ordering principle.
Receiving set
Note that the set to which the result of the Sort
operator is
assigned must have the OrderBy
attribute set to User
(see also
Simple Sets) for the operation to be useful. Without this
setting AIMMS will store the elements of the result set of the Sort
operator, but will discard the underlying ordering.
Example
The following assignments will result in the same set orderings as in
the example of the OrderBy
attribute in The OrderBy attribute.
LexicographicSupplyCities := Sort( i in SupplyCities, i ) ;
ReverseLexicographicSupplyCities := Sort( i in SupplyCities, -i );
SupplyCitiesByIncreasingTransport :=
Sort( i in SupplyCities, Sum( j, Transport(i,j) );
SupplyCitiesByDecreasingTransportThenLexicographic :=
Sort( i in SupplyCities, - Sum( j, Transport(i,j) ), i );
Sorting root sets
AIMMS will even allow you to sort the elements of a root set. Because the entire execution system of AIMMS is built around a fixed ordering of the root sets, sorting root sets may influence the overall execution in a negative manner. Set Element Ordering explains the efficiency considerations regarding root set ordering in more detail.
Obtaining the \(n\) best elements
You can use the NBest
operator, when you need the \(n\) best
elements in a set according to a single ordering criterion. The syntax
of the NBest
is similar to that of the Sort
operator. The first
expression after the binding domain is the criterion with respect to
which you want elements in the binding domain to be ordered. The second
expression refers to the number of elements \(n\) in which you are
interested.
Example
The following assignment will, for every city i
, select the three
cities to which the largest transports emanating from i
take place.
The result is stored in the indexed set LargestTransportCities(i)
.
LargestTransportCities(i) := NBest( j, Transport(i,j), 3 );
Repeated intersection and union
With the Intersection
and Union
operators you can perform
repeated set intersection or union respectively. A typical application
is to take the repeated intersection or union of all instances of an
indexed set. However, any set valued expression can be used on the
second argument.
Example
Consider the following indexed set declarations.
Set IndSet1 {
IndexDomain : s1;
SubsetOf : S;
}
Set IndSet2 {
IndexDomain : s1;
SubsetOf : S;
}
With these declarations, the following assignments illustrate valid uses
of the Union
and Intersection
operators.
SubS := Union( s1, IndSet1(s1) );
SubS := Intersection( s1, IndSet1(s1) + IndSet2(s1) );
Set Element Expressions as Singleton Sets
Element expressions …
Element expressions can be used in a set expression as well. In the context of a set expression, AIMMS will interpret an element expression as the singleton set containing only the element represented by the element expression. Set element expressions are discussed in full detail in Set Element Expressions.
…versus enumerated sets
Using an element expression as a set expression can equivalently be expressed as a symbolic enumerated set containing the element expression as its sole element. Whenever there is no need to group multiple elements, AIMMS allows you to omit the surrounding braces.
Example
The following set assignment illustrate some simple set element expressions used as a singleton set expression.
! Remove LargestCity from the set of Cities
Cities -= LargestCity ;
! Remove first element from the set of Cities
Cities -= Element(Cities,1) ;
! Remove LargestCity and SmallestCity from Cities
Cities -= LargestCity + SmallestCity ;
! The set of Cities minus the CapitalCity
NonCapitalCities := Cities - CapitalCity ;