Обозначение AMPL для упорядоченных пар естественным образом распространяется на тройки, четверки или упорядоченные наборы (кортежи) любой длины. Все кортежи в наборе должны иметь одинаковое измерение. Например, набор не может содержать как пары, так и тройки, и определение того, содержит ли набор пары или тройки, не может быть выполнено в соответствии с некоторым значением в данных. Модель транспортировки нескольких товаров предлагает несколько примеров того, как мы можем использовать упорядоченные тройки и, соответственно, более длинные кортежи.
param cost {ORIG, DEST, PROD} >= 0; var Trans {ORIG, DEST, PROD} >= 0; minimize Total_Cost: sum {i in ORIG, j in DEST, p in PROD} cost[i,j,p] * Trans[i,j,p];
Вышеуказанные выражения индексации перечисляют три набора. Индексное выражение, которое перечисляет k наборов, аналогично будет обозначать набор из k-кортежей. Если вместо этого выражения мы определим LINKS, тогда объявления будут выглядеть так:
set LINKS within {ORIG,DEST}; param cost {LINKS, PROD} >= 0; var Trans {LINKS, PROD} >= 0; minimize Total_Cost: sum{(i,j) in LINKS, p in PROD} cost[i,j,p] * Trans[i,j,p];
Здесь мы видим, как набор троек может быть представлен в виде комбинации из набора пар LINKS и набора отдельных элементов PROD. Поскольку cost и Trans индексируются по {LINKS, PROD}, их первые два элемента должны быть из пары LINKS, а третий индекс - из элемента набора PROD. Наборы более длинных кортежей могут быть построены аналогичным образом.
set ROUTES within {ORIG,DEST,PROD}; param cost{ROUTES} >= 0; var Trans{ROUTES} >= 0; minimize Total_Cost: sum{(i,j,p) in ROUTES}cost[i,j,p] * Trans[i,j,p]; subject to Supply{i in ORIG, p in PROD}: sum{(i,j,p) in ROUTES} Trans[i,j,p] = supply[i,p]; subject to Demand{j in DEST, p in PROD}: sum{(i,j,p) in ROUTES} Trans[i,j,p] = demand[j,p]; subject to Multi{i in ORIG, j in DEST}: sum{(i,j,p) in ROUTES} Trans[i,j,p] <= limit[i,j];
можно ограничить объем всех продуктов, отправляемых из каждого источника, до некоторой величины с помощью следующего ограничения:
subject to Supply_All {i in ORIG}: sum{j in DEST, p in PROD: (i,j,p) in ROUTES} Trans[i,j,p] <= supply_all[i];
или более кратко:
subject to Supply_All{i in ORIG}: sum{(i,j,p) in ROUTES}Trans[i,j,p] <= supply_all[i];
В первом случае AMPL явно генерирует набор {j in DEST, p in PROD} и проверяет членство (i,j,p) в ROUTES, тогда как во втором случае AMPL может использовать более эффективный подход к поиску всех (i,j,p) из ROUTES, которые соответствуют ранее заданному i.
Составные наборы в AMPL не могут быть объявлены как упорядоченные или циклические, следовательно, также не могут быть аргументами функций, таких как first и next и других описанных ранее, которые работают только с упорядоченными наборами.