Data Assignment

Introduction

After declaring sets and parameters, the next step is to assign values to them. We do this in the data section of our program (see Program Structure).

A data section must begin with a data; statement. Otherwise, the assignment statements will be interpreted as declaration statements, and the execution will fail with an error.

Set Data Assignment

A set is a model entity that holds a collection of items. This collection can contain strings, numbers or both.

1D Sets

Sets are 1 dimensional (1D) by default. A 1 dimensional set is a collection of items in which each of its items is a single value (string or number). The set Cities declared using the statement set Cities; is a 1D set, and we can assign data to it like this:

set Cities = "New York" "London" "Rio de Janeiro" ; The AMPL processor ignores white spaces and line breaks, but for human readability, it is a good practice to arrange the data in a way that makes sense. If you prefer, you could also arrange the above list of items vertically: set Cities "New York"
"London"
"Rio de Janeiro"
= ;

Set of Numbers

There are many cases in which we want to define a set of numbers ranging from a to b. But it would be very inconvenient if we had to explicitly list all the numbers we want to our set.

Suppose we want a set containing the integers from 1 to n, where n is a parameter. The easy way to do it is to declare the set like this: set S = 1..n;, and then, in the data section, assign a value to parameter n, like this: param n = 10;.

1D Collection of 1D Sets

A 1D collection of 1D sets is a collection in which each of its items is a 1D set associated with a single index. The collection Attractions declared using the statement set Attractions{Cities}; is a 1D collection of 1D sets. We need one assignment statement for each set within that collection. The assignment statement for each entry will look like the previous one, except that we specify which set within the collection we are assigning data to:

set Attractions ["New York"] = "Statue of Liberty" "Central Park" ;

2D+ Collection of 1D Sets

In general, a n-dimensional collection of 1D sets is a collection in which each of its items is a 1D set that we can only refer to using n indices. The collection Products declared using the statement set Products{Stores, Departments}; is a 2D collection of 1D sets. Suppose that we have already declared and assign data to the Stores and Departments sets with the statements:

set Stores = "StoreA" "StoreB"; set Departments = "Electronics" "Books" "Clothing";

Like in the previous case, we need one assignment statement for each set within the Products collection. In each statement, we have an index part specifying which set within the collection we are assigning data to:

set Products ["StoreA", "Electronics"] = "Laptop1" "Laptop2" "Phone1" ;

2D+ Sets

In general, a n-dimensional set is a collection of items in which each of its items is a tuple of values (strings and/or numbers). A tuple can be a pair, a triplet, a quartet, etc. The set DirectFlights declared using the statement set DirectFlights dimen 2; is a 2D set, which means each of its items is a pair of values. We can assign data to it like this:

set DirectFlights = ("Toronto", "San Francisco") ("Shanghai", "Tokyo") ;

The data assignment for higher dimension sets is basically the same, with each tuple being specified between parenthesis.

Collection of 2D+ Sets

Assigning data to a n-dimensional collection of m-dimensional sets is not so different from assigning data to a 2D+ collection of 1D sets.

Suppose that the DirectFlights of the previous example was the name not of a set, but of a collection of sets, declared like this: set DirectFlights{Airlines, FlightType} dimen 2;. Additionally, suppose that we have already declared and assigned data to the Airlines and FlightType sets with the statements:

set Airlines = "Delta" "Air China" "KLM"; set FlightType = "National" "International";

We need one assignment statement for each set within the DirectFlights collection. In each statement, we have an index part (in yellow) specifying which set within the collection we are assigning data to:

set DirectFlights ["Delta", "International"] ("Toronto", "San Francisco")
("New York", "Rio de Janeiro")
("Austin", "Amsterdam")
= ;

Parameter Data Assignment

A parameter is a model entity that holds a single value, which can be a number or a string.

By default, parameters can only hold numbers. Use the symbolic attribute in the parameter declaration to allow it to hold strings: param P symbolic;

Single Parameter

Assigning data to a single parameter is very straightforward:

param Capacity = 25 ;

1D Collection of Parameters

A 1D collection of parameters is an indexed list of values. In order to assign data to it, we need to list each index with its corresponding value. For instance, given a parameter collection declared with param Population{Cities};, and given that we have already assigned values to the Cities set (see above), one way to assign data to the Population collection is this:

param Population "New York"
"London"
"Rio de Janeiro"
8.42
8.98
6.75
= ;

In the assignment statement above, the actual values in the parameter collection appear in orange, each of which being placed just after its index in yellow.

When we have multiple 1D parameter collections indexed over the same set, instead of writing multiple assignment statements like the above (which would work just fine), we can conveniently make all data assignments in a single assignemnt statement. For instance, say we have a parameter collection param Area{Cities};. We could assign values to both collections Population and Area in a single statement, like this:

param : "New York"
"London"
"Rio de Janeiro"
Population 8.42
8.98
6.75
Area 784
1572
1255
= ;

Moreover, the above statement could be slightly modified so that it assigns data to our Cities set as well:

param : Cities : "New York"
"London"
"Rio de Janeiro"
Population 8.42
8.98
6.75
Area 784
1572
1255
= ;

In this last case, we are using a single assignment statement to set the values for the Cities set and the parameter collections Population and Area.

2D Collection of Parameters

A 2D collection of parameters is a collection of parameters in which each parameter is associated with a pair of indices. We can treat 2D parameter collections as simple tables and assign data to them in a table-like fashion. In the declaration of a 2D parameter collection, it is useful to think that we are defining, in that order, the labels of the rows and columns of the collection:

param RainProbability { Cities , Months } ;

Suppose that we have already declared and initialized the set Months with the first three months. This is how we assign data to our RainProbability parameter collection:

param RainProbability : "New York"
"London"
"Rio de Janeiro"
"Jan" 0.22
0.30
0.55
"Feb" 0.24
0.26
0.48
"Mar" 0.29
0.25
0.45
= ;

The RainProbability collection is 2D because it is indexed over two 1D sets, Cities and Months. But we can also have a 2D collection indexed over a single 2D set, and the assignment statement structure is basically the same. For instance, this is how we assign data to the Distances collection declared with param Distances{DirectFlights}; (see DirectFlights 2D declaration above):

param Distances : "Toronto"
"Shanghai"
"San Francisco" 3644
.
"Tokyo" .
1767
= ;

Notice that we don't have direct flights from "Toronto" to "Tokyo" nor from "Shanghai" to "San Francisco". The .'s in the above statement instruct the AMPL processor to ignore those entries. If we did have direct flights between those cities, the .'s would instruct the processor to replace the .'s with the default value.

3D+ Collection of Parameters

We can think of a 3D collection of parameters as a collection of tables. The data assignment of a collection of tables is done in multiple chunks, each chunk assigning the data of a table within the collection.

Let's say we want to assign data to the following parameter collection:

param DeliveryPrices{Departments, DeliveryTypes, DeliveryTimes};

Suppose that we have already declared and initialized the Departments, DeliveryTypes and DeliveryTypes sets like this:

set Departments = "Electronics" "Books" "Clothing"; set DeliveryTypes = "National" "International"; set DeliveryTimes = 7 14 30; # Max delivery delay (days)

This is how we assign data to the DeliveryPrices collection:

param DeliveryPrices ["Electronics",*,*] : "National"
"International"
["Books",*,*] : "National"
"International"
["Clothing",*,*] : "National"
"International"
= 7 22.00
60.00
7 5.00
12.50
7 6.00
13.50
14 10.00
48.00
14 2.00
10.80
14 3.00
11.80
30 5.00
25.00
30 0.00
5.00
30 1.00
6.00
;

The statement has three chunks, each chunk assigning data to a table within the collection. The part of the statement that is between brackets specify the subcollection of DeliveryPrices that we are going to assign data to. For instance, ["Electronic",*,*] means that we are about to assign data to all parameters whose index follows this indexation pattern. The *'s are wildcards indicating that these are the indices that we are going to provide in the row/column labels of our statement (yellow parts). The row labels replace the first wildcard, and the column labels replace the second one.

Data for parameter collections with higher dimensions can be assigned in the same way. The difference will be that the "tables" will be referenced with more indices. For instance, if our delivery prices varied between "Gold" and "Platinum" customers, each chunk would begin with an indexation pattern with 4 indices, like this: ["Electronic", "Gold", *, *].

Default Values

We can define default values for sets and parameters.

For sets, this is done in the declaration of the set (or set collection), not in the data section. For instance, we can declare a set I that contains the numbers 1 to 10, by default: set I = 1..10;. If no data is provided to the set in the data section of our program, that data is assigned to the set.

For parameters, this can be done either in the declaration of the parameter or in the data section. For instance, the DeliveryPrices parameter collection above could be declared like this:

param DeliveryPrices{Departments, DeliveryTypes, DeliveryTimes} default 10;

Alternatively, in the data assignment statement for this collection, we could set a default value like this:

param DeliveryPrices default 10 = ...

In both cases, all the parameters in the collection would have the value 10 by default. When assigning data to this collection, we can either preserve the default value for a given entry or overwrite it with new data. In order to preserve the default value, we put a . where the value for that entry would go. See above how we have used .'s in the assignment statement for the Distances collection.

Variable Data Assignment

The assignment statements for variables and collection of variables are exactly the same as those for parameters, except for the assignment keyword, which is var for variables.