В дополнение к решению и связанным числовым значениям может быть полезно получить определенную символическую информацию о результатах решения. Например, в сценарии команд AMPL может потребоваться проверить, не было ли последнее решение неограниченным или неосуществимым. Или, после решения линейной программы симплексным методом, можно использовать оптимальное базисное разбиение, чтобы обеспечить хорошее начало для решения связанной проблемы. Интерфейс AMPL-solver позволяет решателям возвращать эти и другие виды информации о состоянии, которую можно просмотреть и использовать.
Результаты решения
Решатель завершает свою работу, потому что он нашел оптимальное решение или столкнулся с каким-либо другим завершающим условием. В дополнение к значениям переменных, решатель может предоставить AMPL информацию о результатах процесса оптимизации:
solve_result_num, solve_result, solve_result_table
model diet.mod; data diet2.dat; display solve_result_num, solve_result; solve_result_num = -1 solve_result = ’?’ solve; MINOS 5.5: infeasible problem. 9 iterations display solve_result_num, solve_result; solve_result_num = 200 solve_result = infeasible option solve_result_table; option solve_result_table ’\ 0 solved\ 100 solved?\ 200 infeasible\ 300 unbounded\ 400 limit\ 500 failure\ ’;
В начале сеанса AMPL solve_result_num равно -1, а solve_result равен '?'. Однако каждая команда solve сбрасывает эти параметры, так что они описывают состояние решателя в конце его выполнения, solve_result_num - числом, а solve_result - символьной строкой. Опция solve_result_table перечисляет возможные комбинации, которые можно интерпретировать следующим образом:
Значения solve_result:
Число |
Строка |
Интерпретация |
0- 99 | solved | Оптимальное решение найдено |
100-199 | solved? | Указано оптимальное решение, но возможна ошибка |
200-299 | infeasible | Ограничения не могут быть выполнены |
300-399 | unbounded | Цель не ограничена |
400-499 | limit | Процесс остановлен установленным пределом (например, количеством итераций) |
500-599 | failure | Процесс остановлен из-за ошибки в решателе |
Обычно информация о состоянии используется в сценариях, где ее можно проверить, чтобы различать случаи, которые должны обрабатываться различными способами. В качестве примера ниже приведен сценарий AMPL для модели диеты, которая считывает название питательного вещества (из стандартного ввода, используя имя файла), начальный верхний предел для этого питательного вещества в рационе и размер шага для уменьшения предела. Цикл продолжает работать до тех пор, пока предел не будет уменьшен до значения, при котором проблема становится невозможной, и в этот момент он печатает соответствующее сообщение и таблицу ранее найденных решений. Код выглядит так:
model diet.mod; data diet2.dat; param N symbolic in NUTR; param nstart > 0; param nstep > 0; read N, nstart, nstep <- ; # read data interactively set N_MAX default {}; param N_obj {N_MAX}; param N_dual {N_MAX}; option solver_msg 0; for {i in nstart .. 0 by -nstep} { let n_max[N] := i; solve; if solve_result = "infeasible" then { printf "--- infeasible at %d ---\n\n", i; break; } let N_MAX := N_MAX union {i}; let N_obj[i] := Total_Cost; let N_dual[i] := Diet[N].dual; } display N_obj, N_dual;
Результат работы скрипта:
commands diet.run; <1>ampl? NA <1>ampl? 60000 <1>ampl? 3000 --- infeasible at 48000 --- : N_obj N_dual := 51000 115.625 -0.0021977 54000 109.42 -0.00178981 57000 104.05 -0.00178981 60000 101.013 7.03757e-19 ;
Здесь ограничение на натрий (NA в данных) уменьшается с 60000 с шагом 3000, до тех пор, пока проблема не станет неосуществимой на границе 48000. Ключевым утверждением diet.run является тест на невозможность:
if solve_result = "infeasible" then { printf "--- infeasible at %d ---\n\n", i; break; }
Условие if может быть эквивалентно записано 200 <= solve_result_num <300. Иногда такая альтернатива может быть полезна для проведения тонких различий между различными условиями завершения решателя. Например, вот некоторые из значений, которые решатель CPLEX устанавливает для различных условий оптимальности:
Solve_ result_ num |
Интерпретация |
0 |
Сообщение: найдено оптимальное решение |
1 |
Цель имеет неограниченную оптимальную границу |
2 |
Оптимальное целочисленное решение |
3 |
Оптимальное целочисленное решение в пределах mipgap или absmipgap |
execute_result
Значением execute_result является solved во всех случаях, но пользователь может протестировать solve_result_num, если необходимо различить их. Интерпретации solve_result_num полностью зависят от решателя. Для ее понимания необходимо просмотреть документацию конкретного решателя, чтобы узнать, какие значения он возвращает и что они значат. Решающие интерфейсы AMPL настроены для отображения нескольких строк, таких как:
MINOS 5.5: infeasible problem. 9 iterations
подводящих итоги последнего прогона, который закончился.
solver_msg
Если запустить скрипт, который выполняет много решений, эти сообщения могут привести к большому выводу. Однако, можно подавить их появление, установив для параметра solver_msg значение "0". Встроенный символический параметр solve_message всегда содержит самое последнее возвращенное сообщение решателя, даже когда отображение сообщения отключено. Можно отобразить этот параметр, чтобы проверить его значение:
display solve_message; solve_message = ’MINOS 5.5: infeasible problem.\ 9 iterations’
Поскольку solve_message является символическим параметром, его значение является символьной строкой. Это наиболее полезно в сценариях, где можно использовать функции символьных строк, чтобы проверить сообщение на наличие признаков оптимальности и других результатов. В качестве примера можно написать тест в diet.run:
if match(solve_message, "infeasible") > 0 then…
Однако, поскольку тип сообщения варьируется от одного решателя к другому, для большинства ситуаций проверка решения проблемы будет проще и менее зависима от решателя.
Результаты решения могут быть возвращены, как описано выше, только в случае успешного вызова AMPL решателя. Вызов может завершиться неудачей, по причине того, что операционная система не сможет найти или выполнить нужный решатель, или из-за какой-либо ошибки низкого уровня. Которая помешает решателю выполнить попытку или завершить оптимизацию. Типичные ошибки включают в себя: неверно указанное имя решателя, неправильную установку или лицензирование решателя, недостаточные ресурсы для завершения процесса, или «прерывание» с клавиатуры. В этих случаях сообщение об ошибке, которое следует за solve, генерируется операционной системой, а не решателем, и пользователю, возможно, придется обратиться к системному администратору, чтобы отследить проблему. Например, сообщение can’t open at8871.nl обычно указывает на то, что AMPL не может записать временный файл. Это может быть попытка записи на заполненный диск или в каталог (папку), для которого у вас нет разрешения на запись. (Каталог для временных файлов указывается в опции TMPDIR).
solve_exitcode
Встроенный параметр solve_exitcode записывает успех или неудачу самого последнего вызова решателя. Его первоначальное значение -1, и сбрасывается в 0 всякий раз, когда произведен успешный вызов. В противном случае к некоторому системно-зависимому ненулевому значению:
reset; display solve_exitcode; solve_exitcode = -1 model diet.mod; data diet2.dat; option solver xplex; solve; Cannot invoke xplex: No such file or directory display solve_exitcode; solve_exitcode = 1024 display solve_result, solve_result_num; solve_result = ’?’ solve_result_num = -1
Здесь неудачный вызов произошел из-за указания ошибочного имени решателя "xplex", что отражается положительным значением solve_exitcode. Параметры состояния solve_result и solve_result_num, также сбрасываются до их начальных значений ’?’ и -1.
Если solve_exitcode превышает значение solve_exitcode_max, то AMPL прерывает любые выполняющиеся в данный момент составные операторы (include, commands, repeat, for, if). Значение по умолчанию solve_exitcode_max равно "0", поэтому AMPL обычно прерывает составные операторы всякий раз, когда не удается вызвать решатель. Сценарий, который задает для параметра solve_exitcode_max более высокое значение, может проверять значение решения convert_exitcode, но в целом его интерпретация не является одинаковой для всех операционных систем и решателей.
Статусы целей и задач решателя
Иногда удобно иметь возможность ссылаться на результат решения, полученный, когда задача была недавно оптимизирована. Для этого AMPL связывает с каждым встроенным параметром результата решения суффикс «status»:
Встроенный параметр |
Суфикс |
solve_result | .result |
solve_result_num | .result_num |
solve_message | .message |
solve_exitcode | .exitcode |
Добавленный к имени объекта суффикс указывает значение соответствующего встроенного параметра при самом последнем решении, в котором цель была оптимизирована.
В качестве примера, рассмотрим несколько целей, определенных для модели назначения:
minimize Total_Cost: sum {i in ORIG, j in DEST} cost[i,j] * Trans[i,j]; minimize Pref_of {i in ORIG}: sum {j in DEST} cost[i,j] * Trans[i,j];
После минимизации трех из этих целей мы можем просмотреть значения статуса решения для всех из них:
model transp4.mod; data assign.dat; solve; CPLEX 8.0.0: optimal solution; objective 28 24 dual simplex iterations (0 in phase I) Objective = Total_Cost objective Pref_of[’Coullard’]; solve; CPLEX 8.0.0: optimal solution; objective 1 3 simplex iterations (0 in phase I) objective Pref_of[’Hazen’]; solve; CPLEX 8.0.0: optimal solution; objective 1 5 simplex iterations (0 in phase I) display Total_Cost.result, Pref_of.result; Total_Cost.result = solved Pref_of.result [*] := Coullard solved Daskin ’?’ Hazen solved Hopp ’?’ Iravani ’?’ Linetsky ’?’ Mehrotra ’?’ Nelson ’?’ Smilowitz ’?’ Tamhane ’?’ White ’?’ ;
Для целей, которые еще не использовались, суффикс .result не изменяется (в данном случае его первоначальное значение равно ?). Эти же суффиксы могут применяться к именам «проблемы». При добавлении к имени проблемы они ссылаются на результаты самой последней выполненной оптимизации.
Состояния и переменные решателя
В дополнение к возврату общего статуса процесса оптимизации, как описано выше, AMPL позволяет решателю возвращать индивидуальный статус для каждой переменной. Эта функция предназначена главным образом для сообщения о базовом состоянии переменных после того, как линейная программа решена либо симплекс-методом, либо методом внутренней точки (барьера), за которым следует процедура «пересечения». Базовый статус также имеет отношение к решениям, возвращаемым некоторыми нелинейными решателями, особенно MINOS, которые используют расширение концепции базового решения.
В дополнение к переменным, объявленным операторами var в модели AMPL, решатели также определяют «слабые» или «искусственные» переменные, связанные с ограничениями. Статусы решателя для этих последних переменных определяются аналогичным образом, как описано далее в этом разделе. И переменные, и ограничения также имеют «статус AMPL», который отличает, данные текущей проблемы, от тех, которые были удалены из проблемы с помощью предварительного разрешения или с помощью таких команд, как drop.
send_statuses
Основное использование значений состояния решателя из оптимального базового решения - обеспечить хорошую отправную точку для следующего прогона оптимизации. Опция send_statuses, если оставить значение по умолчанию 1, предписывает AMPL включать статусы с информацией о переменных, отправляемых решателем после каждого решения. Эффект действия этой функции можно увидеть практически в любом анализе чувствительности, который решается после внесения небольшого изменения в задачу.
В качестве примера рассмотрим, что происходит, когда многопериодная задача производства, решается неоднократно после увеличения доступности рабочей силы на пять процентов. Если для опции send_statuses задано значение "0", решатель сообщает о 18 итерациях метода двойного симплекса при каждом запуске:
model steelT3.mod; data steelT3.dat; option send_statuses 0; solve; CPLEX 8.0.0: optimal solution; objective 514521.7143 18 dual simplex iterations (0 in phase I) let {t in 1..T} avail[t] := 1.05 * avail[t]; solve; CPLEX 8.0.0: optimal solution; objective 537104 19 dual simplex iterations (0 in phase I) let {t in 1..T} avail[t] := 1.05 * avail[t]; solve; CPLEX 8.0.0: optimal solution; objective 560800.4 19 dual simplex iterations (0 in phase I) let {t in 1..T} avail[t] := 1.05 * avail[t]; solve; CPLEX 8.0.0: optimal solution; objective 585116.22 17 dual simplex iterations (0 in phase I)
При использовании значения send_statuses по умолчанию равным 1, только первое решение составляет 18 итераций. Последующие прогоны состоят самое большее из нескольких итераций:
model steelT3.mod; data steelT3.dat; solve; CPLEX 8.0.0: optimal solution; objective 514521.7143 18 dual simplex iterations (0 in phase I) let {t in 1..T} avail[t] := 1.05 * avail[t]; solve; CPLEX 8.0.0: optimal solution; objective 537104 1 dual simplex iterations (0 in phase I) let {t in 1..T} avail[t] := 1.05 * avail[t]; solve; CPLEX 8.0.0: optimal solution; objective 560800.4 0 simplex iterations (0 in phase I) let {t in 1..T} avail[t] := 1.05 * avail[t]; solve; CPLEX 8.0.0: optimal solution; objective 585116.22 1 dual simplex iterations (0 in phase I)
Каждое последующее solve автоматически использует базовые состояния переменных из предыдущего решения, чтобы построить отправную точку, которая оказывается всего в нескольких итерациях от оптимальной. В случае третьего solve базис остается оптимальным. Таким образом, решатель немедленно подтверждает оптимальность и сообщает о 0 итерациях.
Следующее обсуждение объясняет, как можно просматривать, интерпретировать и изменять значения состояния переменных в среде AMPL. Пользователю не нужно знать что-либо из этого, чтобы использовать оптимальный базис в качестве отправных точек, как показано выше, но эти функции могут быть полезны в определенных сложных ситуациях.
.sstatus
AMPL ссылается на статус решателя переменной, добавляя .sstatus к ее имени. Таким образом, можно вывести статус переменных через команду display. В начале сеанса (или после сброса), когда проблема еще не решена, все переменные имеют статус none:
model diet.mod; data diet2a.dat; display Buy.sstatus; Buy.sstatus [*] := BEEF none CHK none FISH none HAM none MCH none MTL none SPG none TUR none ;
После вызова решателя симплексным методом, той же командой display отображаются состояния переменных в оптимальном базовом решении:
solve; MINOS 5.5: optimal solution found. 13 iterations, objective 118.0594032 display Buy.sstatus; Buy.sstatus [*] := BEEF bas CHK low FISH low HAM upp MCH upp MTL upp SPG bas TUR low ;
sstatus_table
Две из переменных, Buy[’BEEF’] и Buy[’SPG’], имеют статус bas, что означает, что их значения соответствуют оптимальному базису. Три имеют статус low и три upp, что указывает на то, что они не являются базовыми в нижней и верхней границах соответственно. Таблица распознанных значений состояния решателя хранится в опции sstatus_table:
option sstatus_table; option sstatus_table ’\
0 none статус не определен\ 1 bas basic\ базовый 2 sup superbasic\ супербазовый 3 low nonbasic <= (normally =) lower bound\ 4 upp nonbasic >= (normally =) upper bound\ 5 equ не базовый равный нижней или верхней границам\ 6 btw не базовый между границами\;
Числа и короткие строки, представляющие значения состояния, приведены в первых двух столбцах. (Числа в основном служат для связи между AMPL и решателями, хотя можно получить к ним доступ, используя суффикс .sstatus_num вместо .sstatus). Записи в третьем столбце являются комментариями. Для неосновных переменных, как определено во многих симплексных методических учебниках, применим только статус low. Другие неосновные состояния требуются для более общих симплексных методов с ограниченными переменными в крупномасштабных реализациях.
Статус sup используется такими решателями, как MINOS, для решения нелинейных задач. Это стандартная таблица AMPL sstatus_table; решатель может заменить свою собственную таблицу, и в этом случае его документация укажет интерпретацию записей таблицы.
Пользователь может изменить статус переменной с помощью команды let. Это иногда полезно, когда есть необходимость решить проблему после небольшого изменения. Например, в следующем разделе этой главы мы используем модель вырезания по шаблону, которая содержит объявления:
param nPAT integer >= 0; # number of patterns set PATTERNS = 1..nPAT; # set of patterns var Cut {PATTERNS} integer >= 0; # rolls cut using each pattern
Каждый проход через главный цикл выполняет шаги nPAT по одному, в результате чего создается новая переменная Cut[nPAT]. Она имеет начальный статус решателя «none», как и все новые переменные, но это гарантирует, что процедура генерации шаблона построена, чтобы принять значения базового решения, как только будет решена расширенная проблема резки. Таким образом, вместо этого мы даем ему статус «bas»:
let Cut[nPAT].sstatus := "bas";
Это изменение имеет тенденцию уменьшать число итераций в каждой повторной оптимизации задачи резки, по крайней мере, с некоторыми симплексными решателями. Однако установка нескольких состояний не гарантирует сокращение количества итераций. Его успех зависит от конкретной проблемы и решателя, а также от их взаимодействия с рядом осложняющих факторов:
- После того, как проблема и статусы были изменены, статусы, переданные решателю при следующем решении, могут неправильно определять базовое решение.
- После того, как проблема была изменена, фаза предварительного разрешения AMPL может посылать решателю другое подмножество переменных и ограничений (если параметр presolve не установлен в ноль). В результате состояния, переданные решателю, могут не соответствовать определенной ранее отправной точке для следующего решения и могут неправильно определять базовое решение.
reset_initial_guesses
Некоторые решатели, в частности MINOS, используют текущие значения, а также статусы переменных при построении начальной точки при следующем решении (если для параметра reset_initial_guesses не установлено значение 1). Каждый решатель имеет свой собственный способ корректировки состояний, которые он получает от AMPL, когда это необходимо, для создания исходного базового решения, которое он может использовать. Таким образом, некоторые эксперименты обычно необходимы, чтобы определить, является ли какая-либо конкретная стратегия для изменения статуса полезной.
Для моделей, которые имеют несколько объявлений var, общие синонимы AMPL для переменных предоставляют удобный способ получения общей сводки состояний.
Например, используя выражения: _var, _varname и _var.sstatus в операторе display, можно легко указать таблицу всех основных переменных для steelT3.mod вместе с их оптимальными значениями:
display {j in 1.._nvars: _var[j].sstatus = "bas"} (_varname[j], _var[j]); : _varname[j] _var[j] := 1 "Make[’bands’,1]" 5990 2 "Make[’bands’,2]" 6000 3 "Make[’bands’,3]" 1400 4 "Make[’bands’,4]" 2000 5 "Make[’coils’,1]" 1407 6 "Make[’coils’,2]" 1400 7 "Make[’coils’,3]" 3500 8 "Make[’coils’,4]" 4200 15 "Inv[’coils’,1]" 1100 21 "Sell[’bands’,3]" 1400 22 "Sell[’bands’,4]" 2000 23 "Sell[’coils’,1]" 307 ;
Аналогичный список всех переменных будет отображен командой:
display _varname, _var;
Состояния и ограничения решения
Реализация симплекс-метода обычно добавляют одну переменную для каждого ограничения, которое поступает от AMPL. Каждая добавленная переменная имеет коэффициент 1 или –1 в связанном ограничении, и коэффициенты "0" во всех других ограничениях. Если связанное ограничение представляет собой неравенство, сложение используется как переменная slack или surplus. Её границы выбраны так, что оно превращает неравенство в эквивалентное уравнение.
Эффективный крупномасштабный симплексный решатель получает два преимущества от добавления этих «логических» переменных к «структурным» переменным, которые он получает от AMPL: линейная программа преобразуется в более простую форму, в которой единственные неравенства границы переменных и подпрограммы инициализации (или «сбоя») решателя могут быть спроектированы так, чтобы они быстро находили начальные значения. При любых исходных значениях первая фаза симплекс-метода находит основу для возможного решения (если необходимо), а вторая фаза находит основу для оптимального решения. Две фазы различаются в сообщениях некоторых решателей:
model steelP.mod; data steelP.dat; solve; CPLEX 8.0.0: optimal solution; objective 1392175 27 dual simplex iterations (0 in phase I)
Таким образом, решатели обычно обрабатывают все логические переменные почти так же, как структурные, с очень незначительными корректировками для обработки случая, когда нижняя и верхняя границы равны нулю. Базовое решение определяется набором базовых статусов всех переменных, структурных и логических.
Чтобы согласовать логические переменные, AMPL разрешает решателю возвращать значения состояния, соответствующие ограничениям, а также переменным. Статус решателя для ограничения, записанный как имя ограничения с суффиксом .sstatus, интерпретируется как состояние логической переменной, связанной с этим ограничением. Например, в нашей модели диеты, где все ограничения являются неравенствами:
subject to Diet {i in NUTR}: n_min[i] <= sum {j in FOOD} amt[i,j] * Buy[j] <= n_max[i];
логические переменные - это провалы, которые имеют такое же разнообразие состояний, что и структурные переменные:
model diet.mod; data diet2a.dat; option show_stats 1; solve; 8 variables, all linear 6 constraints, all linear; 47 nonzeros 1 linear objective; 8 nonzeros. MINOS 5.5: optimal solution found. 13 iterations, objective 118.0594032 display Buy.sstatus; Buy.sstatus [*] := BEEF bas CHK low FISH low HAM upp MCH upp MTL upp SPG bas TUR low ; display Diet.sstatus; diet.sstatus [*] := A bas B1 bas B2 low C bas CAL bas NA upp ;
Всего имеется шесть основных переменных, число которых соответствует шести ограничениям (по одной для каждого элемента набора NUTR), как это всегда имеет место при базовом решении. Для транспортной модели, где ограничения равны:
subject to Supply {i in ORIG}: sum {j in DEST} Trans[i,j] = supply[i]; subject to Demand {j in DEST}: sum {i in ORIG} Trans[i,j] = demand[j];
логические переменные являются искусственными, которые получают статус «equ», когда они не являются базовыми. Вот как состояния для всех ограничений могут отображаться с использованием общих синонимов AMPL (аналогично переменным синонимам, показанным ранее):
model transp.mod; data transp.dat; solve; MINOS 5.5: optimal solution found. 13 iterations, objective 196200 display _conname, _con.slack, _con.sstatus; : _conname _con.slack _con.sstatus := 1 "Supply[’GARY’]" -4.54747e-13 equ 2 "Supply[’CLEV’]" 0 equ 3 "Supply[’PITT’]" -4.54747e-13 equ 4 "Demand[’FRA’]" -6.82121e-13 bas 5 "Demand[’DET’]" 0 equ 6 "Demand[’LAN’]" 0 equ 7 "Demand[’WIN’]" 0 equ 8 "Demand[’STL’]" 0 equ 9 "Demand[’FRE’]" 0 equ 10 "Demand[’LAF’]" 0 equ ;
Одна искусственная переменная с ограничением Demand[’FRA’] находится в оптимальном базисе, несмотря на то, что ее slack значение по существу равно нулю, как и все искусственные переменные в любом возможном решении.
AMPL статусы
.astatus
Только те переменные, цели и ограничения, которые AMPL фактически передает решателю, могут получить статус решателя при возвращении. Чтобы пользователь мог отличить их от компонентов, которые были удалены до решения, AMPL предоставляет отдельный «статус». Можно работать со статусами AMPL так же, как со статусами решателя, используя суффикс .astatus вместо .sstatus и ссылки на опцию astatus_table для суммирования распознанных значений:
option astatus_table; option astatus_table ’\ 0 in в нормальном состоянии (in problem)\ 1 drop удалено командой drop\ 2 pre устранено с помощью presolve\ 3 fix исправлено командой fix\ 4 sub определенная переменная, замещенная\ 5 unused не используется в текущей задаче\ ;
Вот пример наиболее распространенных случаев с использованием одной из моделей диеты:
model dietu.mod; data dietu.dat; drop Diet_Min[’CAL’]; fix Buy[’SPG’] := 5; fix Buy[’CHK’] := 3; solve; MINOS 5.5: optimal solution found. 3 iterations, objective 54.76 display Buy.astatus; Buy.astatus [*] := BEEF in CHK fix FISH in HAM in MCH in MTL in SPG fix TUR in ; display Diet_Min.astatus; Diet_Min.astatus [*] := A in B1 pre B2 pre C in CAL drop ;
Состояние AMPL in указывает компоненты, которые находятся в задаче, отправленной решателю, например, переменная Buy[’BEEF’] и ограничение Diet_Min[’A’]. Три других статуса указывают компоненты, исключенные из проблемы:
- Переменные Buy[’CHK’] и Buy[’SPG’] имеют статус «fix» AMPL, поскольку команда fix использовалась для указания значений этих переменных в решении.
- Ограничение Diet_Min[’CAL’] имеет статус AMPL «drop», поскольку оно было удалено командой drop.
- Ограничения Diet_Min[’B1’] и Diet_Min[’B2’] имеют статус AMPL «pre», потому что они были удалены из проблемы в результате упрощений, выполненных на этапе предварительного разрешения AMPL.
Здесь не показан статус AMPL «unused» для переменной, которая не указана ни в одной цели или ограничении, и «sub» для переменных и ограничений, устраняемых подстановкой.
Команда objective и problem, которые будут определены позже в этой главе, также влияют на исправление или удаление компонентов модели, которые не используются.
Для переменной или ограничения обычно интересен только один из статусов одновременно: статус решателя, если переменная или ограничение были включены в задачу, переданную решателю в последний раз, или статус AMPL в противном случае. Таким образом, AMPL предоставляет суффикс .status для обозначения одного статуса:
model dietu.mod; data dietu.dat; drop Diet_Min[’CAL’]; fix Buy[’SPG’] := 5; fix Buy[’CHK’] := 3; solve; MINOS 5.5: optimal solution found. 3 iterations, objective 54.76 display Buy.astatus; Buy.astatus [*] := BEEF in CHK fix FISH in HAM in MCH in MTL in SPG fix TUR in ; display Diet_Min.astatus; Diet_Min.astatus [*] := A in B1 pre B2 pre C in CAL drop ;
В общем случае name.status равен name.sstatus, если name.astatus является "in", и равен name.astatus во всех остальных случаях.