Line: 1 to 1  

< Ready to Review  done  Lauren> Sets in AMPL
DescriptionSets are one of the most fundamental concepts in AMPL. They are used to index variables, constraints, parameters and sometimes other sets. Most expressions involve an operation being performed over a set. Sets allow for large mathematical programmes to be expressed concisely.
Declaring a SetSets are declared using theset keyword followed by a label, possibly some attributes and either a set literal or set expression. The most common attribute is set by the within keyword. This specifies that the set will only contain elements from the following set definition: set ARCS within NODES cross NODES; # Elements of ARCS must have both elements in NODES
If you need a multidimensional set, but don't have the 1dimensional sets to construct it yet you can use the set ROUTES dimen 2;There are some other set attributes, but we will not use them here. Set literals can be defined as a list of elements: {'HOST', 'DEVICE', 'SWITCH', 'HUB', 'LINK', 'SUPERLINK'}or a sequence of numbers: param start; param end > start; param step; set NUMBERS := start .. end by step;If the by step is missing, the step is assumed to be 1: set NUMBERS := 1..5; # NUMBERS = {1, 2, 3, 4, 5}Note Automatic set generation can only be done in the model environment, in the data environment you must define the set explicitly: set NUMBERS := 1 2 3 4 5; # NUMBERS = {1, 2, 3, 4 5}
Set ExpressionsSet expressions take the following form (which can be extended to higher dimensional sets):
Generic Set Expression { <e> in <S>, [<f> in <T>, <g> in <U>, …] : <logical expression involving e [f, g, …]>} Set expressions may also involve one or more set operators:
You will see examples of set expressions throughout the rest of this page.
Defining a SetSets are usually defined in a data file:
set NODES := Youngstown Pittsburgh Cincinnati 'Kansas City' Chicago Albany Houston Tempe Gary ; although they may be defined during declaration using either an explicit set literal or using a set expression:
set KIND := {'HOST', 'DEVICE', 'SWITCH', 'HUB', 'LINK', 'SUPERLINK'}; set COMPONENT := {C in CLASSES : (kind[C] = 'HOST' ) or (kind[C] = 'DEVICE') or (kind[C] = 'HUB' ) or (kind[C] = 'SWITCH')}; set FABRIC := NODE union LINK; and sets may also be defined dynamically:
set SEARCH within VERTICES; let SEARCH := {v in VERTICES: (v, w) in EDGES};
Defining 2Dimensional SetsThere are three different ways to define 2dimensional sets. The "best" way to use depends on the set.
set ARCS: Cincinnati 'Kansas City' Chicago Albany Houston Tempe Gary := Youngstown + + + +    Pittsburgh + + +    + Cincinnati    + +   'Kansas City'     + +  Chicago      + + ;
set ARCS := (Youngstown, *) Cincinnati ‘Kansas City’ Chicago Albany (Pittsburgh, *) Cincinnati ‘Kansas City’ Chicago Gary (Cincinnati, *) Albany Houston ...
Ordered Sets
You can create sets where the elements are ordered using the
set MONTHS ordered;
AMPL will put the elements in this set in the order they appear in the data file (or
ord(e, ORD_SET) # The position of e in ORD_SET first(ORD_SET) # The first element in ORD_SET last(ORD_SET) # The last element in ORD_SET prev(e, ORD_SET) # The element before e in ORD_SET next(e, ORD_SET) # The element after e in ORD_SET member(i, ORDSET) # The element at position i in ORD_SET
Set Example
Consider the following AMPL statement from the The American Steel Planning Problem. We use
# The set of timestaged arcs set TIME_ARCS within TIME_NODES cross TIME_NODES := { (m, t) in TIME_NODES, (n, u) in TIME_NODES : ( ( (m, n) in ARCS) and (t = u) ) or # The transportation arcs ( (m = n) and (ord(t, MONTHS) + 1 = ord(u, MONTHS)) )}; # The storage arcs There are many concepts within this one statement, let's look at them one at a time.
Set Operations
There are many operations we can perform on sets (see Set Expressions). We have seen that Some set operations may be looped over indexing sets. For example, to generate all the transportation arcs in the timestaged network you could use the following statement: set TRANSPORT_ARCS := union {t in MONTHS} (union {(m, n) ARCS} {(m, t, n, t)});or you could loop over MONTHS and ARCS simultaneously:
set TRANSPORT_ARCS := union {t in MONTHS, (m, n) in ARCS} {(m, t, n, t)};
Set Membership and Subsets
We have seen how to loop over a set using the set ARCS within NODES cross NODES;means each arc is created between two nodes.
Ordered Set Operators
The final condition on ( (m = n) and (ord(t, MONTHS) + 1 = ord(u, MONTHS)) )};creates the "storage" arcs. We could use next(t, MONTHS) = u or t = prev(u, MONTHS) except for a problem when t is June or u is April , respectively. When you use prev or next you must be careful of the first and last members of the set respectively. However, you can use first or last to check if you are using these elements.
Restricted SetsWhen using display or printf statements we saw that we could restrict the members of a set being printed, e.g., display {(m, n) in ARCS : Supply[m] > 0}; # Display all arcs from supply nodes
We can do this when creating sets, e. g.,
var UnderProduction {(n, t) in TIME_NODES : Supply[n, t] > 0} >= 0, integer;
We could make sure this variable is only added to the constraints for the supply nodes (e.g.,
subject to ConserveFlow {(n, t) in TIME_NODES}: sum {(m, s) in TIME_NODES: (m, s, n, t) in TIME_ARCS} Shipment[m, s, n, t] + Supply[n, t]  if Supply[n, t] > 0 then UnderProduction[n, t] = ...
Multidimensional Sets
We have already seen different ways of declaring 2dimensional sets. We have now encountered higher dimensional sets, e.g.,
set TIME_ARCS within TIME_NODES cross TIME_NODES; List
set TIME_ARCS := (Youngstown, April, Albany, April) (Youngstown, April, Youngstown, May) ... ; Table
set TIME_ARCS : = (*, May, *, May) Cincinnati 'Kansas City' Albany ... := Youngstown + + + ... Pittsburgh + +  ... ... ; Array
set TIME_ARCS := (*, May, *, May) (Youngstown, Cincinnati) ... ... ; or
set TIME_ARCS := (Youngstown, May, *, May) Cincinnati 'Kansas City' ... ... ;
Efficient Generation of Sets
When creating models, generating sets by looping over all possibilities and removing those that don't fit some conditions (e.g., like the # The set of timestaged arcs set TIME_ARCS within TIME_NODES cross TIME_NODES := { (m, t) in TIME_NODES, (n, u) in TIME_NODES : ( ( (m, n) in ARCS) and (t = u) ) or # The transportation arcs ( (m = n) and (ord(t, MONTHS) + 1 = ord(u, MONTHS)) )}; # The storage arcs
to create
set TRANSPORT_ARCS := union {t in MONTHS, (m, n) in ARCS} {(m, t, n, t)}; set STORAGE_ARCS := union {t in MONTHS, (m, n) in ARCS : t <> last(MONTHS)} {(m, t, n, next(t, MONTHS)}; set TIME_ARCS within TIME_NODES cross TIME_NODES := TRANSPORT_ARCS union STORAGE_ARCS;
Rather than looping over all possibilities and only keeping those that are appropriate, the new statement only loops over smaller sets that can be used to build up the  MichaelOSullivan  27 Feb 2008  
Changed:  
< < 
 
> > 
