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:

image/svg+xmlDATA { element-tuple , }

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:

image/svg+xml{ binding-domain }

binding-domain:

binding-tuple:

image/svg+xml( binding-element , ) binding-element

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.

Table 1 Set operators

Operator

Notation

Precedence

intersection

*

3 (high)

difference

-

2

union

+

2

Cartesian product

CROSS

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

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, and

  • the Intersection and Union 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, and

  • the 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 ;