Набор чисел часто представляет собой последовательность, которая соответствует некоторой прогрессии в моделируемой ситуации. Например, серия недель или лет. Как и для строк, числа в наборе могут быть указаны как часть данных в файле *.dat, или в модели (файл *.mod) в виде списка между фигурными скобками. Например: {1,2,3,4,5,6}.
Такой тип набора последовательных чисел может быть описан более кратко с помощью обозначения 1..6. Дополнительный оператор by может быть использован для указания интервала между числами, отличного от 1.
Конструкция expr..expr [by expr]
Общая форма записи оператора создания множеств имеет следующий вид:
expr..expr [by expr]
где: expr – любое выражение.
Выражение: 1990..2020 by 5 представляет собой набор: {1990, 1995, 2000, 2005, 2010, 2015, 2020}
Выражения такого типа могут применяться везде, где использование набора является уместным. В частности, внутри фразы присваивания «=» при объявлении набора:
set YEARS = 1990..2020 by 5;
Краткое и значимое имя набора, может помочь сделать модель более читабельной. Не рекомендуется указывать числа в выражении «..» с помощью литералов, таких как 2020 и 5. Если только эти значения не являются фундаментальными для модели, и не будут меняться. Предпочтительной является следующий вид записи:
param start integer; # Начало интервала param end > start integer; # Конец интервала param interval > 0 integer; # Шаг интервала set YEARS = start..end by interval; # Объявление набора и определение его элементов
а данные записать как:
data; param start := 1990; param end := 2020; param interval := 5;
Тогда YEARS будет таким же, как в предыдущем примере (как и в случае, если бы end равнялся 2023).
Арифметические выражения в expr..expr [by expr]
Можно использовать любое арифметическое выражение для представления любого значения в выражении «..». Например:
set YEARS = start..end+1 by interval;
Элементы числовых наборов имеют те же свойства, что и любые другие числа и, следовательно, могут использоваться в арифметических выражениях:
subject to Balance {p in PROD, t in 1..T}: Make[p,t] + Inv[p,t-1] = Sell[p,t] + Inv[p,t];
Поскольку t пробегает весь набор 1..T, мы можем записать Inv[p,t-1], чтобы представить значение Inv в конце предыдущего периода. Если t пробегает по набору строк(не числовому набору), выражение t-1 будет отклонено как ошибка. Элементы числовых наборов могут быть дробными. AMPL пытается сохранить каждый элемент числового набора в качестве ближайшего представимого числа с плавающей запятой. Следующий пример показывает, как это работает:
option display_width 50; display -5/3..5/3 by 1/3; set -5/3 .. 5/3 by 1/3 := -1.6666666666666667 0.33333333333333326 -1.3333333333333335 0.6666666666666663 -1 0.9999999999999998 - 0.6666666666666667 1.3333333333333333 -0.3333333333333335 1.6666666666666663 -2.220446049250313e-16;
Можно ожидать, что «0» и «1» будут элементами этого набора, однако это не так, из-за ошибки округления в вычислениях с плавающей точкой.
Неразумно использовать дробные числа в наборах, если модель опирается на элементы набора, имеющие точные значения. Проблем с округлением не наблюдается для целых чисел. Целые числа представлены точно для величин до 2^53 (приблизительно 10^16) для стандартной арифметики IEEE и до 2^47 (приблизительно 10^14) для любого современного компьютера.