## 1.1

- What is AMPL?

## 1.2

- How does AMPL compare to other modeling languages and systems?

## 1.3

- How does AMPL compare to spreadsheet optimizers?

## 1.4

- How big a problem can AMPL solve?

## 1.5

- Can my program call AMPL as a subroutine?

## 1.6

- How can I learn more about AMPL?

## 2.1

- How can I edit my model or data file without leaving the AMPL command environment?

## 2.2

- How do I solve a series of different random problems with data drawn from the same distribution?

## 2.3

- When does AMPL evaluate the conditions specified in my model's
checkstatements?

## 2.4

- How do I write an "MPS file" for my problem?

## 2.5

- Why does AMPL write an MPS file that is different from what I expect?

## 2.6

- What are the transformations that AMPL applies to optimization problems?

## 2.7

- How can I prevent AMPL from transforming my problem?

## 3.1

- Why does AMPL reject my "
let" statement with a "... has a := value in the model" message?

## 3.2

- What does AMPL mean by "syntax error"? I double-checked the offending statement in the AMPL book, and my syntax is fine.

## 3.3

- How can I tell whether messages on my screen are coming from AMPL or from the solver?

## 3.4

- Why does AMPL appear to "hang" for a long time without accepting any input or producing any output?

## 3.5

- Why does AMPL unexpectedly abort in the middle of doing something? I get a short error message, but I can't find it explained in the AMPL book or in the solver documentation.

## 3.6

- What should I do if I suspect that there is insufficient memory for my AMPL session?

## 4.1

- Why doesn't AMPL interpret the expression
T..1as I expect?

## 4.2

- Why does "
setS:=50..70" give me a set of only 3 members?

## 4.3

- I have declared "
setS" and "paramb{S}". How do I write an AMPL expression for thearg minofb[i]-- that is, thesinSsuch thatb[s]equals the minimum ofb[i]over alliinS?

## 4.4

- How can I get AMPL to index over the "power set" consisting of all subsets of a set?

## 4.5

- How can I apply AMPL's ordered-set functions to pairs and higher-dimensional objects?

## 4.6

- Why do I get an "invalid subscript discarded" message when I display an AMPL parameter?

## 5.1

- When I set
optionsubstout1, why doesn't AMPL make the substitutions that I expect?

## 5.2

- Why does AMPL treat my linear program as nonlinear?

## 5.3

- When certain variables are fixed, the nonlinear expressions in my model all become linear. Why does AMPL still consider my model to be nonlinear in this case?

## 6.1

- How can I look at the explicit constraints that AMPL has generated from my model and data?

## 6.2

- How do I list all variables that have a certain property in the optimal solution?

## 6.3

- How do I get "ranges" and other sensitivity analyses?

## 6.4

- How do I get a "tableau column" from AMPL?

## 6.5

- Why can't I view an indexed collection of subsets by typing
display{kinSS}POW[k]?

## 6.6

- How can I get the
displaycommand to list a set's members in the same order that they were given in my data file?

## 6.7

- Where do I find the amount of computation (CPU) time taken by AMPL or by a solver?

## 7.1

- How do I relax the integrality of only some of a model's integer variables?

## 7.2

- Why does my solver's
relaxdirective sometimes give a higher objective value than AMPL'srelax_integralityoption?

## 7.3

- How can I "break" a run of an integer programming solver and get back the best integer solution found so far?

## 7.4

- How can I use the solver's "special ordered sets" feature?

## 8.1

- What is the student edition of AMPL?

## 8.2

- What is the professional edition of AMPL?

## 8.3

- Is there a graphical ("gui") version of AMPL?

## 8.4

- Can I get a version of AMPL that will run on my computer, under my computer's operating system?

## 8.5

- Where can I get more information about how AMPL works under specific operating systems?

## 8.6

- How can I determine the version number of the copy of AMPL that I'm currently running?

## 8.7

- How can I learn about updates to AMPL, and where can I get updated AMPL software?

## 9.1

- What solvers does AMPL support?

## 9.2

- Can I buy AMPL and the solvers separately?

## 9.3

- Where can I get more information about AMPL's interface to specific solvers?

## 9.4

- How can I interface my own solver to AMPL?

## 10.1

- Where can I get more information on AMPL?

## 10.2

- How can I get answers to more questions about AMPL?

- 1.1
- What is AMPL?

AMPL is a computer language for describing production, distribution, blending, scheduling and many other kinds of problems known generally as large-scale optimization or mathematical programming.

AMPL's familiar algebraic notation and interactive command environment are designed to help formulate models, communicate with a wide variety of solvers, and examine solutions.

AMPL's flexibility and convenience make it ideal for rapid prototyping and development of models, while its speed and generality provide the resources required by repeated production runs.

- 1.2
- How does AMPL compare to other modeling languages and systems?

AMPL is one of several optimization modeling systems that are designed around specialized algebraic modeling languages. These languages employ adaptations of familiar mathematical notation to describe optimization problems as

- the minimization or maximization of algebraic expressions in
numerical decision variables,
- subject to constraints expressed as equalities or inequalities between algebraic expressions in the decision variables.

Some of the other commercially distributed algebraic modeling languages are:

- GAMS, one of the first such languages, now widely used in
a number of industries.
- MGG, another early language with a long history of support.
- LINGO, a more powerful sibling of the LINDO language widely
used in elementary instruction.
- MPL, notable for its associated graphical interface and
database links.
- AIMMS, providing a graphical application development environment and a GAMS compatibility mode supplementing its own language.

AMPL provides strong support for validation, verification and reporting of optimal solutions, through numerous alternatives for presenting data and results. AMPL's extensive preprocessing routines can automatically carry out transformations that serve to reduce problem size, convert piecewise-linearities to linear terms, and substitute out selected variables.

AMPL is further distinguished by its continuing development to serve users' needs. Recent additions include looping and testing constructs for writing executable scripts in the AMPL command language, and facilities for defining and working with several interrelated subproblems. Numerous commands have also been added for producing diagnostic reports and custom-formatted tables.

There are also many optimization modeling systems based on representations other than algebraic modeling languages. Popular alternative forms include:

- block-schematic diagrams, which depict a linear constraint matrix
as a collection of structured submatrices (or blocks).
- activity specifications, which describe a model in terms of
activities (variables) and their effects (constraints) on inputs
and outputs.
- netforms, which use graph or network diagrams to depict models involving flows and allocations.

- 1.3
- How does AMPL compare to spreadsheet optimizers?

The Excel, 1-2-3 and Quattro spreadsheet packages come with solvers for linear, nonlinear, and integer programming; they accept enhanced add-in solvers as well. Their principal advantage lies in allowing all aspects of optimization -- including formulation, solution, and analysis of results -- to be performed within the spreadsheet environment. In particular, variables and constraints can be defined directly in terms of ranges of spreadsheet cells.

AMPL incorporates a far richer language than spreadsheet optimizers for describing optimization problems. As a result, AMPL is much more natural and reliable for developing and maintaining complex models. The difference is particularly pronounced when many model components have more than two dimensions (or more than two subscripts or indices, in AMPL terms).

By avoiding much of the spreadsheet overhead, AMPL also generates model instances faster than spreadsheet optimizers. AMPL's speed advantage is significant for a few thousand model components, and becomes relatively greater as problem size increases.

AMPL's interface design encourages developers to hook additional solvers to AMPL. Thus AMPL is available with a greater variety of solvers than spreadsheet optimizers.

AMPL models can use data stored in spreadsheet ranges, but only through the exchange of appropriately formatted text files. AMPL's new read command facilitates this exchange. AMPL Plus can also use the ODBC standard to read and write spreadsheet ranges that represent relational database tables.

- 1.4
- How big a problem can AMPL solve?

Certain low-cost versions of AMPL have built-in limits on problem size. The student edition bundled with the AMPL book is limited to 300 variables and a total of 300 objectives and constraints, for example, and several packages having higher limits are offered by AMPL vendors. The professional edition of AMPL has no intrinsic limit on problem size, however; it is limited only by the resources available to the computer that is running AMPL.

In practice, memory is most often the limiting resource. The amount of memory used by AMPL necessarily depends on the numbers of variables and constraints, and on the number and complexity of the terms in the constraints -- or in the case of linear programs, on the number of nonzero coefficients in the constraints. Memory use also depends on the size and complexity of the model's sets and parameters. AMPL's presolve phase may require additional memory to execute (though it may accomplish problem reductions that allow savings of memory later).

AMPL's memory use for a linear program can be estimated crudely as
1000000 + 260 (*m* + *n*) + 50 *nz* bytes, where
*m* is the number of constraints, *n* the number of
variables, and *nz* the number of nonzeroes. Allowing for memory
occupied by DOS, this suggests that the following sizes of problems
might be accommodated on a PC:

m = 1200, n = 4800, nz = 14400 on a 4MB machine, m = 3600, n = 14400, nz = 43200 on an 8MB machine, m = 8000, n = 24000, nz = 96000 on a 16MB machine.

Memory required for a solver must be added, if the solver is to be run while AMPL remains active. See also our advice elsewhere in this FAQ for further comments on what to do (including running the solver separately) if you suspect a problem with insufficient memory.

Especially difficult problems may cause your solver to encounter its
own resource limitations. Solvers that accept `binary` and
`integer` variables, in particular, can consume impractical
amounts of time and disk space as well as memory, even for problems of
apparently modest size. Nonlinear problems can also be very
time-consuming compared to linear programs in the same numbers of
variables and constraints.

As a practical matter, there is no substitute for experimentation to determine the resource requirements of your particular problem. The best approach is usually to try out your model on progressively larger collections of data, so that you can record the trend in resource requirements as problem size increases.

- 1.5
- Can my program call AMPL as a subroutine?

Currently AMPL is not configured as a subroutine library (like CPLEX or OSL) whose individual pieces can be called as needed from a user's program. A "batch" session of AMPL can be executed from a C program, however. This feature can be used as a high-level "call" to AMPL that is sufficient for some applications.

Under Unix, MS-DOS or Microsoft Windows, you would execute AMPL by use
of the `system` procedure, as in these examples:

system("ampl <cut.run"); system("ampl <cut.run >cut.out");

The argument to `system` can be anything one would type on a
command line. Most commonly, an input file (`cut.run` above)
contains a series of AMPL commands that read model and data input,
invoke solvers, and write results to files. This arrangement does not
provide for results to be passed back directly to your program;
following the call to `system`, your program must get the
results by reading a file that AMPL has written.

- 1.6
- How can I learn more about AMPL?

The AMPL book is the most comprehensive source of information on AMPL. It is written in the form of a textbook with an appendix for reference, in contrast to the more common format of a reference manual with some tutorial material at the front. Virtually all language features are illustrated by continuing, meaningful examples, and additional exercises are provided. A student edition of the AMPL software and the MINOS and CPLEX solvers is included.

See also the AMPL update pages for features added since the book was published.

- 2.1
- How can I edit my model or data file without leaving the AMPL command environment?

Use AMPL's shell command to invoke the editor you want to use.
For example, if your editor is called `edit` and your file is
`diet2a.dat`, give the command

shell "edit diet2a.dat";

The editor temporarily takes over the screen or current window. When you quit the editor, the AMPL prompt reappears, and all models, data and options are as before.

When you have returned from the editor, AMPL cannot tell which files you have changed! Thus to use a changed file, you must reset and read it again. The simplest approach is to reset and re-read everything, as in this example:

ampl:ampl:shell "edit diet.mod";ampl:reset;ampl:model diet.mod;data diet2a.dat;

See our discussion of new `reset`
features for ways to partially reset the model and data.

In a multiple-window environment (such as X on Unix workstations or Microsoft Windows on PCs) it's easier to edit files in their own windows, separate from the windows where you're running AMPL. You still need to reset and re-read after changing a file, though.

If you use a graphical interface to AMPL then you can create editing windows within the AMPL environment. The interface does know when you have changed a file, and it may carry out the reset and re-read operations automatically. To learn more, consult the instructions for the interface that you are using.

- 2.2
- How do I solve a series of different random problems with data drawn from the same distribution?

Use AMPL's `reset` `data` command to resample from
all of the random-valued functions in the model. For example, in
model `steel4.mod` from
the AMPL book, suppose that parameter
`avail` is changed so that its value is given by a random
function:

param avail_mean {STAGE} >= 0; param avail_variance {STAGE} >= 0;

param avail {s in STAGE} := Normal (avail_mean[s], avail_variance[s]);

with corresponding data

param: avail_mean avail_variance := reheat 35 5 roll 40 2 ;

Then AMPL will take new samples from the Normal distribution after
each `reset` `data`:

ampl:ampl:model steel4.mod;data steel4.dat;

ampl:MINOS 5.4: optimal solution found. 3 iterations, objective 187632.2489solve;

ampl:reheat 32.3504 roll 43.038 ;display avail;

ampl:reset data avail;

ampl:MINOS 5.4: optimal solution found. 4 iterations, objective 158882.901solve;

ampl:reheat 32.0306 roll 32.6855 ;display avail;

Using this feature together with one of AMPL's new looping commands, you can automatically solve a series of random realizations from the model, and summarize the results:

model steel4.mod; data steel4.dat;

param nruns := 5; param optvalue {1..nruns};

for {k in 1..nruns} { reset data avail; solve; let optvalue[k] := total_profit; }

display (sum {k in 1..nruns} optvalue[k]) / nruns;

If you use `reset` rather than `reset` `data`,
then AMPL's random number generator is reset, and the values of
`avail` repeat from the beginning. To get a different sequence
of random numbers from the generator, you must change the random
number seed; give the command `option` `randseed`
*n* -- where *n* is a positive integer -- or
`option` `randseed` `0` to have AMPL choose a
seed based on the system clock.

Versions of AMPL prior to
`19951020` work a little differently. For this and other fine
points, see the supplementary reset data
examples.

- 2.3
- When does AMPL evaluate the conditions specified in my model's
`check`statements?

The `check` conditions are evaluated each time that AMPL
generates (or re-generates) an instance of your model. Normally the
generation of an instance is triggered by a `solve` command, but
a few other commands such as `write` and `solution` can
have the same effect.

You can force all `check` statements to be evaluated immediately
by typing the command

check;

or by inserting this command into an AMPL script at the point where you want the checking to occur.

- 2.4
- How do I write an "MPS file" for my problem?

You can use AMPL's `write` command to create a file that
contains a representation of your linear or integer program in a
standard format known as *MPS form*. To write an MPS-form file
for the diet LP from Chapter 2 of the AMPL book,
for example, you could proceed as follows:

ampl:ampl:model diet.mod;data diet2a.dat;

ampl:option auxfiles rc;

ampl:write mdiet2;

AMPL interprets "`write m...`" as indicating that you want to
write an MPS file, and creates the filename by appending
"`.mps`" to the letters after the "`m`". Thus our
example creates a file named `diet2.mps`.
The format of this file is explained in the Linear
Programming FAQ and in the manuals for many solvers.

Because MPS form limits the row (constraint or objective) and column
(variable) names to 8 characters, AMPL substitutes artificial names
such as `R0001` and `C0007`. You can ask for
supplementary files of the true AMPL component names, by also
resetting `option` `auxfiles` `rc`; in the above
example, you would get files `diet2.row`
and `diet2.col`. The ordering of the
names in these files corresponds to their numbering in the MPS file.
(For a more detailed description of `write` and the
`auxfiles` option, see Sections A.13.5 and A.13.6 of the AMPL book.)

An MPS file contains only the nonzero values that define one instance of your model. Thus an MPS file generated by AMPL is mainly useful as input to solvers that do not yet have a direct AMPL interface; because MPS form has been in use for a longer time than any comparable format, it is recognized by more solvers than any other file type. You may also find AMPL's MPS-file option useful for generating new instances of test problems, for submission to libraries such as netlib's lp/data or miplib. If you want to encourage people to use AMPL with your own solver, however, then you should consider hooking your solver to AMPL by use of AMPL's file format, which takes less space, can be processed faster, represents numbers more accurately, and applies to a broader variety of optimization problems (especially nonlinear ones).

- 2.5
- Why does AMPL write an MPS file that is different from what I expect?

Several kinds of transformations
may be applied by AMPL before it writes out any representation of your
problem. Normally you need not be aware of these changes, because
AMPL reverses them after receiving the optimal solution from the
solver. If you write an MPS file, however, it will correspond to the
transformed problem; its coefficients and other values may have been
changed, it may lack some of the variables and constraints that you
defined, or it may contain auxiliary variables and constraints that
AMPL added. To get a summary of AMPL's transformations, set
`option` `show_stats` `1`. To force AMPL to
write the MPS file for your problem as stated, turn off the
transformations.

Representations of numbers in MPS form are limited to 12 characters. As a consequence, the numbers in an MPS file may not have the full precision of the numbers that were generated from your AMPL model and data. Usually these precision discrepancies are inconsequential, but they do give rise to inaccuracies in the optimal solution computed from the MPS file.

Although MPS form is regarded as a standard, it has no definitive statement. As a result, there are a few special cases that are treated differently by different solvers; examples include variables that have an upper bound of zero and no lower bound, and integer variables declared without any bounds. AMPL's version of MPS form is designed to avoid using these unresolved default options, so that its MPS files can be compatible with as many solvers as possible. If using the MPS file gets you a significantly different optimal value from what you get by typing solve, however, then try looking at our list of MPS form inconsistencies.

- 2.6
- What are the transformations that AMPL applies to optimization problems?

AMPL's *presolve* phase attempts to transform your problem to
an equivalent one that is smaller and easier to solve. Presolve first
removes trivial model components, such as variables fixed at constant
values and constraints that express simple lower or upper bounds.
Then it applies an iterative procedure to tighten certain bounds on
variables and constraints, with the result that additional variables
may be fixed and constraints may be dropped. Many of these
transformations are based on ideas first presented by A.L. Brearly, G.
Mitra and H.P. Williams, in ``Analysis of Mathematical Programming
Problems Prior to Applying the Simplex Algorithm,'' *Mathematical
Programming* **8** (1975) 54-83. See also Experience with a Primal Presolve Algorithm
for a detailed discussion of the implementation in AMPL.

If your model uses AMPL's notation for piecewise-linear terms in individual variables, then AMPL transforms your problem's piecewise-linear expressions to equivalent linear expressions, through the addition of auxiliary variables and constraints. Chapter 14 of the AMPL book describes the piecewise-linear notation in more detail. See also Expressing Special Structures in an Algebraic Modeling Language for Mathematical Programming for further discussion of how the transformation is carried out.

You can cause AMPL to eliminate certain variables from your problem, by substituting expressions specified in var declarations or in certain constraints. If the substitution comes from a constraint, then the constraint is also eliminated. See Sections 13.2 and A.15 of the AMPL book for more information.

- 2.7
- How can I prevent AMPL from transforming my problem?

To suppress the presolve phase, set `option`
`presolve` `0`.

To suppress transformation of piecewise-linear terms, set
`option` `pl_linearize` `0`.

To suppress elimination of variables by substitution from constraints,
set `option` `substout` `0`. (This is the
default setting.) Substitutions specified within `var`
declarations are always applied.

To see a summary of all transformations performed, set `option`
`show_stats` `1`.

- 3.1
- Why does AMPL reject my "
`let`" statement with a "`... has a := value in the model`" message?

Your `let` command is attempting to assign a value to some
set or parameter. In the set's or parameter's declaration, however,
you have used a `:=` phrase to permanently define the value. A
`let` command is not permitted to redefine the value of such a
parameter; hence the error message that you received.

As an example, if the model declares

param dstot {p in prod} := sum {w in whse} ds[p,w];

then `dstot[p]` is permanently defined to take the value
`sum` `{w` `in` `whse}` `ds[p,w]`.
You can make any changes you like to the `ds[p,w]` values, and
AMPL will automatically change the `dstot[p]` values
accordingly. Any command beginning `let` `{p`
`in` `prod}` `dstot[p]` `:=` `...`
will be in error, however.

If you want to be able to use `let` to override the defined
value of a parameter, use `default` in place of `:=` in
your `param` declaration.

- 3.2
- What does AMPL mean by "syntax error"? I double-checked the offending statement in the AMPL book, and my syntax is fine.

AMPL is signaling an invalid statement of some sort, but the error may not be a matter of "syntax" in the usual sense. For example, you could be trying to define a set index at a place where it is already in use:

ampl:ampl?display {i in ORIG}:supply[i] * sum {i in DEST} cost[i,j];

syntax error context: supply[i] * sum {i >>> in <<< DEST} cost[i,j];

The index `i` cannot be defined following `sum`, because
it is within the scope of the index `i` that was defined
following `display`.

If you receive a syntax error that is particularly hard to interpret, please let us know.

- 3.3
- How can I tell whether messages on my screen are coming from AMPL or from the solver?

When a solver starts up, it displays a brief identification string
such as `MINOS` `5.4` or `CPLEX` `3.0`.
Output that occurs before this string can be assumed to come from
AMPL, while output after is the solver's.

When a solver concludes its run, it returns a brief summary of the results, such as

optimal solution; objective 903202.0326 399 iterations (244 in phase I)

Output prior to this summary can be assumed to be caused by the solver, while output after is from AMPL again.

- 3.4
- Why does AMPL appear to "hang" for a long time without accepting any input or producing any output?

If AMPL appears to hang after a `solve` command but before
any output from a solver, then it may be taking much more time to
generate your problem than you expected. Try setting `option`
`times` `1,` `gentimes` `1` to get more
output recording AMPL's progress, as explained in the FAQ question
regarding insufficient
memory.

The same advice applies if AMPL hangs after some other command, such
as `write` or `expand`, that forces a lot of variables
or constraints to be generated.

If AMPL appears to hang after a command that produces a listing, such
as `display`, then the listing may be much longer than you
expected. Usually it is possible to make a quick estimate of the size
of the listing, in order to determine whether this could be the
difficulty.

If AMPL appears to hang after a line or more from the solver, then your optimization problem may be taking much more time to solve than you expected. Try setting solver directives that provide more output recording progress toward an optimum. Some solvers may also respond to a "break" sequence by returning the best solution found so far. These features differ from one solver to the next and even from one algorithm to the next within the same solver; see the solver-specific documentation for details.

- 3.5
- Why does AMPL unexpectedly abort in the middle of doing something? I get a short error message, but I can't find it explained in the AMPL book or in the solver documentation.

You have encountered a low-level error message generated by the operating system. AMPL and the solvers try to trap these messages so as to provide you with more useful information instead; but occasionally a mysterious message does get through.

Some messages, such as

no children unrecoverable error, STAT = 1001 not enough swap space

usually indicate that AMPL can't get enough computer resources to
complete the current session. As an example, there might be
insufficient disk space for AMPL to write the temporary file that the
solver reads; to remedy the problem, you can reset option
`TMPDIR` to change the directory to which temporary files are
written. More often, however, the difficulty in this situation is
insufficient memory, a more complicated matter that we discuss in
the next question below.

Other messages, including

segmentation fault bus error

indicate a bug in AMPL or a solver. Often there is some way to work around this trouble temporarily, but you should also look for a more permanent fix. You can consult our bug fix log to see whether this bug has been found and fixed already; if not, you can tell us about the problem through our comment form. Either way, you will want to request a newer version of the AMPL software that incorporates the fix.

- 3.6
- What should I do if I suspect that there is insufficient memory for my AMPL session?

If AMPL fails before passing control to the solver, your computer may not have enough memory to hold all of the variables, constraints and objectives generated by the AMPL translator. If a failure occurs after the solver takes over, memory might be short because AMPL has taken most of it for generating the problem, leaving not enough memory for the solver to be active at the same time.

As a start in diagnosing these situations, display listings of AMPL's memory use by repeating your run with one or more of

option times 1; option gentimes 1; option show_stats 1;

The `times` listing includes the
amount of memory used by each phase of the AMPL translator:

parse initial processing of model data read initial processing of data compile translation of model and data genmod generation of an explicit optimization problem merge postprocessing of optimization problem collect postprocessing of optimization problem presolve reduction of problem size output writing of problem file to be read by solver

The `gentimes` listing includes
memory allocated for processing each declaration in the model. If
AMPL fails before invoking a solver, this information will tell you
how far it got. For failures in the presolve phase, you can save some
memory by setting `option` `presolve` `0`, though
a larger problem will be sent to the solver as a result. (Each line
in a `times` or `gentimes` listing appears when
processing of the phase or component is finished. Thus the cause of
a memory failure must be in the phase or component *after* the
last one that appeared in the listing. It may help to first run a
smaller version of your problem, so that you can see what ought to
appear in a complete, correct listing.)

If failure doesn't occur until after the solver is invoked, then the
`show_stats` listing also
appears, giving the numbers of variables and constraints generated and
the numbers removed by presolve. If there are more variables or
constraints than you expected, then check the `gentimes`
listing for a declaration that has required a very large amount of
memory (relative to what the whole model requires). The offending
declaration may be incorrect; or, even if it is technically correct,
the declaration may specify a very large number of variables or
constraints that are unnecessary to the formulation. (Even if a
variable is never referenced in the model, it takes up some minimum
amount of space in the data structure that AMPL maintains in memory.)

If the difficulty is indeed insufficient memory to run the solver under AMPL, then there is a good chance that you can work around the problem by running AMPL and your solver separately. Here's an example of how this is done:

ampl:ampl:model models\multmip3.mod;data models\multmip3.dat;

ampl:# "b" indicates a binary problem filewrite bmultmip3;

ampl:quit

C:\AMPL>No MIP presolve or aggregator reductions.cplex multmip3

C:\AMPL>ampl

ampl:ampl:model models\multmip3.mod;data models\multmip3.dat;

ampl:solution multmip3.sol;

CPLEX 3.0: optimal integer solution; objective 235625 684 simplex iterations 126 branch-and-bound nodes

ampl:display Trans;

Trans [CLEV,*,*] : bands coils plate := DET 0 525 100 FRA 275 50 50 ...

This is inconvenient, but it can substantially reduce the overall memory requirement.

To diagnose insufficient memory, you may need some idea of the amount of memory available for allocation by AMPL and the solver. Your computer may have a utility to help with this, or you may be able to run a short C program like this that tries to allocate as much as possible:

#include <stdio.h> #include <stdlib.h>

main() { long int avail, incr;

avail = 0;

for (incr = 1024 * 1024; incr >= 1; incr >>= 1) while (malloc(incr)) avail += incr;

printf ("Total allocated: %i\n", avail); }

Keep in mind that the available memory is often influenced not only by the amount of memory physically installed in the computer, but by the amount of disk space allocated to memory swapping and by the requirements of all other processes currently running on the computer.

- 4.1
- Why doesn't AMPL interpret the expression
`T..1`as I expect?

In general, AMPL interprets `a..b` as `{a,`
`a+1,` `a+2,` ..., `b-1,` `b}`. Thus when
`T` is greater than one, `T..1` is an empty set. To
specify the ordered set that goes from `T` down to `1`,
write "`T..1` `by` `-1`".

- 4.2
- Why does "
`set``S``:=``50``..``70`" give me a set of only 3 members?

You have declared "`set` `S`" in your model and
"`set` `S` `:=` `50` `..`
`70`" in your data. Set expressions are not recognized in
AMPL's data mode, however. Instead AMPL tries to recognize
`50` `..` `70` as a space-delimited list of
members of `S`, with the result that it has found three
members: the numbers `50` and `70`, and the string
"`..`".

To define `S` to equal `50` `..` `70` by
use of your data file, first declare `S` in your model by

param begin; param end > begin; set S := begin .. end;

Then state in the data file:

param begin := 50; param end := 70;

Alternatively, it's legal to give "`set` `S` `:=`
`50` `..` `70`" as your declaration of
`S`. This is a less desirable approach, however, because it
moves some of the specific data values into the model.

- 4.3
- I have declared "
`set``S`" and "`param``b``{S}`". How do I write an AMPL expression for the*arg min*of`b[i]`-- that is, the`s`in`S`such that`b[s]`equals the minimum of`b[i]`over all`i`in`S`?

There's no specific arg min operator in AMPL. However, proceeding directly from the definition, you can define the arg min explicitly by a set expression like

{s in S: b[s] = min {i in S} b[i]}

This expression gives a subset of `S`, however, containing all
of the members of `S` that achieve the minimum. To get just
one member representing the arg min, you can define this to be an
ordered set,

set b_argmin ordered := {s in S: b[s] = min {i in S} b[i]};

Then `first(b_argmin)` is guaranteed to be one member of
`S` that minimizes `b[i]`.

As an alternative, you can use AMPL's new
`for` and `if` commands to write a script that loops
over `S` to compute the arg min explicitly:

param bmin; param imin symbolic in S;

let bmin := Infinity;

for {i in S} { if b[i] < bmin then { let bmin := b[i]; let imin := i; } }

In general this is a slower alternative than defining
`b_argmin` as above. It admits a greater variety of
generalizations in complex cases, however.

- 4.4
- How can I get AMPL to index over the "power set" consisting of all subsets of a set?

AMPL can index model components by objects (numbers and character strings) but not by sets of objects. Hence you can't model a power set directly. You may be able to get the same effect, however, by constructing a numbered list of subsets.

As an example, suppose that you want to index over all subsets of the
set of the first `n` nonnegative integers. You can declare:

param n integer > 0; set S := 0 .. n - 1;

set SS := 0 .. 2**n - 1;

set POW {k in SS} := {i in S: (k div 2**i) mod 2 = 1};

Since there are `n` members of `S`, there are
`2**n` subsets of `S`. Hence there exists a one-to-one
correspondence between the members of the set `SS` `:=`
`0` `..` `2**n` `-` `1` and the
subsets of `S`. By use of a simple encoding, you can make this
correspondence explicit; the indexed collection of sets `POW`
above is declared such that `POW[k]` is the `k`th
distinct subset of `S`. (To see the whole power set, type
`display` `POW`.)

Much the same can be done for an arbitrary ordered set `S`:

set S ordered; param n := card {S};

set SS := 0 .. (2**n - 1);

set POW {k in SS} := {i in S: (k div 2**(ord(i)-1)) mod 2 = 1};

Either way, you can use indexing over `POW` to get the effect
of indexing over the power set. In the following example, each member
`s` of `S` has a weight `Wt[s]`, and the average
"weight" of all members of any subset of `S` is constrained not
to exceed `n/2`:

var Wt {S} >= 0;

subj to MaxWt {k in SS}: sum {i in POW[k]} Wt[i] <= (n / 2) * card(POW[k]);

A more involved example, which represents a traveling salesman problem
as an integer program, is provided in `tsp.mod`. Constraints like this can be
useful for studying and testing certain formulations of combinatorial
problems, provided that the underlying set (`S` in our example)
is kept to a reasonably small size.

- 4.5
- How can I apply AMPL's ordered-set functions to pairs and higher-dimensional objects?

AMPL does not define any ordering on pairs, triples, or objects of
higher dimension. Thus `next`, `prev`, and other
functions that apply to objects in ordered sets cannot be applied to
pairs, triples, or tuples of higher dimension. For the same reason,
`first`, `last` and other functions of ordered sets may
not be applied to multi-dimensional sets.

You may apply these functions to individual indices of a
multi-dimensional parameter or variable, however. The following
examples are from `steelT2.mod` (Figure 5-3)
of the AMPL book:

subject to balance0 {j in PROD}: Make[j,first(WEEKS)] + inv0[j] = Sell[j,first(WEEKS)] + Inv[j,first(WEEKS)];

subject to balance {j in PROD, t in WEEKS: ord(t) > 1}: Make[j,t] + Inv[j,prev(t)] = Sell[j,t] + Inv[j,t];

Most models that involve both ordered and multidimensional sets can be handled by some variation of this approach.

- 4.6
- Why do I get an "invalid subscript discarded" message when I display an AMPL parameter?

Either a data table gave values for the parameter with incorrect
subscripts, or the parameter's indexing set changed, causing some
previously valid subscripts to become invalid. For example, in the `diet.mod` + `diet.dat` example (Figures 2-1
and 2-2) of the AMPL book, values of parameter
`cost` are supplied for all eight members of set `FOOD`:

ampl:display cost;

cost [*] := BEEF 3.19 FISH 2.29 MCH 1.89 SPG 1.99 CHK 2.59 HAM 2.89 MTL 1.99 TUR 2.49 ;

If you remove the member `"CHK"` from `FOOD`, using for
example a `let` command, then you get a message that
`cost["CHK"]` has also been dropped from the data:

ampl:let FOOD := FOOD diff {"CHK"};

ampl:Error executing "display" command: error processing param cost: invalid subscript cost['CHK'] discarded.display cost;

cost [*] := BEEF 3.19 HAM 2.89 MTL 1.99 TUR 2.49 FISH 2.29 MCH 1.89 SPG 1.99 ;

Since `cost["CHK"]` has now been dropped, no further error
message will appear if you type "`display` `cost`"
again.

To avoid error messages of this sort, you can define a more flexible
set structure for your model as shown in `dietflex.mod` and `dietflex.dat`. The auxiliary set
`DIET_DROP` defaults to empty, so that the problem is solved
for all foods; but you can change `DIET_DROP` to
`{"CHK"}` to solve without member `"CHK"`:

ampl:ampl:model dietflex.mod;ampl:data dietflex.dat;option show_stats 1;

ampl:solve;

8 variables, all linear 6 constraints, all linear; 47 nonzeros 1 linear objective; 8 nonzeros.

MINOS 5.4: optimal solution found. 13 iterations, objective 118.0594032

ampl:ampl:let FOOD_DROP := {"CHK"};solve;

7 variables, all linear 6 constraints, all linear; 42 nonzeros 1 linear objective; 7 nonzeros.

MINOS 5.4: optimal solution found. 3 iterations, objective 117.3218891

Changing `FOOD_DROP` does not affect the set `FOOD_ALL`,
and consequently all of the subscripts in the data remain valid.

- 5.1
- When I set
`option``substout``1`, why doesn't AMPL make the substitutions that I expect?

A variable is ineligible to be substituted out of a problem if (a) it is subject to any bounds or integrality conditions, or (b) it has already appeared on the right-hand side of a constraint that was used to make a substitution.

Case (a) includes bounds or integrality conditions specified in the
variable's declaration, and also bounds that are added by AMPL's
presolve phase. Thus turning presolve off (by setting `option`
`presolve` `0`) may permit a greater number of
substitutions.

For constraints indexed over a set, the incidence of case (b) may depend on the ordering of the set. Consider for example the constraints

var x {1..10}; subj to step {j in 1..9}: x[j] = x[j+1] + 1;

The first several constraints generated are

step[1]: x[1] = x[2] + 1 step[2]: x[2] = x[3] + 1 step[3]: x[3] = x[4] + 1 step[4]: x[4] = x[5] + 1

Constraint `step[1]` may be used to substitute for
`x[1]`. Constraint `step[2]` may not be used to
substitute for `x[2]`, however, because `x[2]` has
already appeared on the right-hand side of a constraint, namely
`step[1]`, that was used to make a substitution. Similarly,
`step[3]` may be used to substitute for `x[3]`, but
`step[4]` may not be used to substitute for `x[4]`, and
so forth. Only the odd-numbered constraints `step[j]` are
eliminated by substitution in this case.

If instead you write the declaration with the ordered index set reversed,

subj to step {j in 9..1 by -1} x[j] = x[j+1] + 1;

then the constraints are generated as

step[9]: x[9] = x[10] + 1 step[8]: x[8] = x[9] + 1 step[7]: x[7] = x[8] + 1 step[6]: x[6] = x[7] + 1

and case (b) does not occur. All of the constraints `step[j]`
can be eliminated, and every variable except `x[10]` is
substituted out as a result.

Close attention to formulation may thus be necessary to get the
substitutions that you want. Set `option` `show_stats`
`1` to see how many substitutions are being made, and use
AMPL's new constraint expansion commands
to see the constraints (in order) before and after substitution.

- 5.2
- Why does AMPL treat my linear program as nonlinear?

Symptoms of this problem are an `option` `show_stats`
`1` listing that refers to nonlinear variables and constraints,
and rejection by the solver with a "`contains`
`nonlinear` `constraints`" message. The cure may be (a)
to reformulate the model so that certain unintended nonlinearities are
made linear, or (b) set `option` `linelim` `1` so
that substituted linear variables do not become nonlinear.

Case (a) can occur because you have overlooked a simple nonlinearity,
such as a variable multiplying or dividing another variable. AMPL's
built-in arithmetic functions, including simple ones such as
`abs` and `max`, are treated as nonlinear when applied
to variables; `if` `...` `then` `...`
`else` `...` expressions are also nonlinear if variables
appear in the expression following the `if`. You may be able
to convert these kinds of "nonlinearities" to equivalent linear
expressions, but AMPL cannot do the conversion automatically. (The
only such conversions currently built into AMPL are for the
piecewise-linear functions described in Chapter 14 of the AMPL book.)

Case (b) occurs when AMPL's defined variable feature is invoked to
substitute an expression for a variable -- either by using the
`=` operator in declarations of variables, or by setting
`option` `substout` `1` to infer substitutions
from the constraints. Under `option` `linelim`
`0`, AMPL does not substitute explicitly in the constraints, but
instead records the substitution as an additional piece of information
in the file sent to the solver. This affords very efficient handling
of sub-expressions that appear at many places in a problem, but it has
the side-effect of causing all variables in a substituted expression to
be treated as nonlinear. To request explicit substitution, so that
linearity is preserved, set `option` `linelim`
`1`. This is the default for AMPL versions 20000327 and later, but if you're
using an earlier version you'll need to set `option`
`linelim` `1` explicitly.

- 5.3
- When certain variables are fixed, the nonlinear expressions in my model all become linear. Why does AMPL still consider my model to be nonlinear in this case?

Versions of AMPL prior to 20000128 are unable to recognize linearity in this case. If you are using one of these earlier versions and cannot obtain an update, you may be able to handle this situation in a more indirect way, such as by writing a script to alternate between related linear models in which the fixed variables are replaced by parameters.

As a simple example, suppose you want to minimize a quadratic function
of variables `X[i]` and `Y[j]`:

param q {1..n,1..n};

var X {1..n} >= 0; var Y {1..n} >= 0;

minimize Quadratic: sum {i in 1..n, j in 1..n} X[i] * q[i,j] * Y[j];

The objective becomes linear when you fix either all the `X[i]`
or all the `Y[j]`. This suggests creating two new linear
objectives in which parameters are substituted for the variables to be
fixed:

param xfix {1..n}; param yfix {1..n};

minimize QuadX: sum {i in 1..n, j in 1..n} X[i] * q[i,j] * yfix[j]; minimize QuadY: sum {i in 1..n, j in 1..n} xfix[i] * q[i,j] * Y[j];

Given some initial `yfix[j]` values, you can use a linear
programming solver to minimize `QuadX`. Then you can assign
the optimal values of `X[i]` to `xfix[i]`, after which
you can use a linear programming solver to minimize `QuadY`.
Finally you can assign the optimal values of `Y[j]` to
`yfix[j]`, and repeat. This iteration is readily written using
AMPL's new repeat loop construct as:

repeat { objective QuadX; solve; let {i in 1..n} xfix[i] := X[i];

objective QuadY; solve; let {j in 1..n} yfix[j] := Y[j];

} until abs(QuadX - QuadY) < 0.001;

For brevity we have not shown constraints, which can alternated like
the objectives by use of `drop` and `restore` (Section
10.8 of the AMPL book) or AMPL's new named problem feature. We also caution
that an iterative scheme like this may never stop; a guarantee of
termination can be supplied only for certain special cases.

- 6.1
- How can I look at the explicit constraints that AMPL has generated from my model and data?

AMPL's new `expand` command can
display any explicit linear constraint, or indexed collection of
constraints. For example:

ampl:ampl:model transp.mod;data transp.dat;

ampl:expand Demand['STL'];

s.t. Demand['STL']: Trans['GARY','STL'] + Trans['CLEV','STL'] + Trans['PITT','STL'] = 1700;

ampl:expand Supply;

s.t. Supply['GARY']: Trans['GARY','FRA'] + Trans['GARY','DET'] + Trans['GARY','LAN'] + Trans['GARY','WIN'] + Trans['GARY','STL'] + Trans['GARY','FRE'] + Trans['GARY','LAF'] = 1400;

s.t. Supply['CLEV']: Trans['CLEV','FRA'] + Trans['CLEV','DET'] + Trans['CLEV','LAN'] + Trans['CLEV','WIN'] + Trans['CLEV','STL'] + Trans['CLEV','FRE'] + Trans['CLEV','LAF'] = 2600;

s.t. Supply['PITT']: Trans['PITT','FRA'] + Trans['PITT','DET'] + Trans['PITT','LAN'] + Trans['PITT','WIN'] + Trans['PITT','STL'] + Trans['PITT','FRE'] + Trans['PITT','LAF'] = 2900;

The `expand` command also works with variables and objectives,
and has indexing options similar to those of `display` or
`print` for determining which components are expanded.

- 6.2
- How do I list all variables that have a certain property in the optimal solution?

The built-in parameter `_nvars` contains the number of
variables; a symbolic parameter `_varname[j]` contains the AMPL
name of the `j`th variable; and `_var[j]` is a "synonym"
that refers to the `j`th variable. Thus to show the names of
all variables that are below their upper bounds at the optimum, for
example, you can write:

ampl:ampl?display {j in 1.._nvars:_var[j] < _var[j].ub - 0.00001} _varname[j];

_varname[j] [*] := 2 "PD_Ship['SE']" 5 "DW_Ship['NE','BWI']" 6 "DW_Ship['SE','EWR']" 7 "DW_Ship['SE','BWI']" ;

This is only one of the uses for AMPL's generic synonyms for variables, constraints and objectives. See the discussion of AMPL's new generic synonym feature for more details.

- 6.3
- How do I get "ranges" and other sensitivity analyses?

AMPL's new suffix feature can be used by solvers to return ranging information. See in particular the discussion of solver-defined suffixes for an example of range output from CPLEX. If you are using a solver that offers ranging, you may need to update the AMPL driver for that solver in order to get access to the ranging suffixes; see our solver listing for information on solver vendors and download sites.

AMPL does not currently support "parametric" algorithms for postoptimal analysis of objective functions or constraint right-hand sides.

In practice, ranging often provides sensitivity information of limited usefulness, and parametric algorithms are limited to certain kinds of linear changes to the data. You may do better to write a simple AMPL script that solves the same model for a series of different parameter values. For an example, see our writeup on AMPL's new looping commands and related features for programming in the command language.

- 6.4
- How do I get a "tableau column" from AMPL?

AMPL cannot determine by itself the values from the linear programming tableau, because the sparse linear algebra routines capable of computing these values are found only in the solvers. Efficient solver implementations avoid computing or storing more than a few tableau columns at a time, however. Hence AMPL also has no solver directives that can cause tableau values to be returned.

For a specific AMPL model, it is possible to set up an auxiliary model that finds the tableau values, at least in the nondegenerate case; see our diet tableau example based on the diet model from Chapter 2 of the AMPL book. This approach is highly inefficient, but should be adequate for small linear programs -- up to a few dozen variables, say.

- 6.5
- Why can't I view an indexed collection of subsets by typing
`display``{k``in``SS}``POW[k]`?

The `display` command does not currently recognize `{k`
`in` `SS}` `POW[k]` where `POW` is an
indexed (subscripted) set. For this elementary case, you can exhibit
the whole indexed collection of subsets by giving just the name of the
collection:

display POW;

You can also exhibit each of the indexed sets separately, by using the
iterated form of the `display` command; it resembles the
ordinary form, but with a colon after the index set:

display {k in SS}: POW[k];

This gives the same output as if you had typed a separate statement
`display` `POW[k]` for each member `k` of
`SS`. Any set expression (or list of expressions) may follow
the colon.

- 6.6
- How can I get the
`display`command to list a set's members in the same order that they were given in my data file?

Add the keyword "`ordered`" to the set's declaration, after the
set name. It can be useful to declare a set `ordered` for
purposes of ordering the output, even when the ordering plays no role
in the model.

- 6.7
- Where do I find the amount of computation (CPU) time taken by AMPL or by a solver?

AMPL provides the following built-in timing parameters:

_ampl_elapsed_time |
elapsed seconds since the start of the AMPL process |

_ampl_system_time |
system CPU seconds used by the AMPL process itself |

_ampl_user_time |
user CPU seconds used by the AMPL process itself |

_ampl_time |
_ampl_system_time + _ampl_user_time |

_shell_elapsed_time |
elapsed seconds for most recent shell command |

_shell_system_time |
system CPU seconds used by most recent shell command |

_shell_user_time |
user CPU seconds used by most recent shell command |

_shell_time |
_shell_system_time + _shell_user_time |

_solve_elapsed_time |
elapsed seconds for most recent solve command |

_solve_system_time |
system CPU seconds used by most recent solve command |

_solve_user_time |
user CPU seconds used by most recent solve command |

_solve_time |
_solve_system_time + _solve_user_time |

_total_shell_elapsed_time |
elapsed seconds used by all shell commands |

_total_shell_system_time |
system CPU seconds used by all shell commands |

_total_shell_user_time |
user CPU seconds used by all shell commands |

_total_shell_time |
_total_shell_system_time + _total_shell_user_time |

_total_solve_elapsed_time |
elapsed seconds used by all solve commands |

_total_solve_system_time |
system CPU seconds used by all solve commands |

_total_solve_user_time |
user CPU seconds used by all solve commands |

_total_solve_time |
_total_solve_system_time + _total_solve_user_time |

These parameters can be used in all the same ways as ordinary AMPL parameters defined through `param` statements. Thus in particular you can show their values by use of `display` or `printf` commands.

- 7.1
- How do I relax the integrality of only some of a model's integer variables?

For each variable whose integrality you want to relax, assign a positive value to *variable-name*`.relax`. For example, if your model has

var X {1..n} integer >= 0; var Y {1..m} integer >= 0;

then to relax the integrality of only the `Y` variables, you can use the command

let {i in 1..m} Y[i].relax := 1;

To remove a relaxation specified in this way, assign a nonpositive value to *variable-name*`.relax`.

- 7.2
- Why does my solver's
`relax`directive sometimes give a higher objective value than AMPL's`relax_integrality`option?

These two ways of relaxing integrality can give different results because they interact differently with AMPL's presolve phase.

Under `option` `relax_integrality` `1`, all
integer variables are changed to continuous before AMPL's presolve.
Thus presolve works on the "true" relaxation, and the reduced LP that
comes out of presolve has the same objective value as the true
relaxation.

Under `option` `relax_integrality` `0`, all
integer variables remain integer through AMPL's presolve phase.
Presolve may take advantage of this integrality to further tighten
bounds and reduce the problem size. If the solver's `relax`
directive is subsequently set, then it will solve the relaxation of
the presolved integer program, which may not have the same objective
value as the true relaxation. (Specifically, its value may be higher
for a minimization, or lower for a maximization.)

As a simple example, imagine a minimization model in which there are
integer variables `X[t]` constrained by `sum`
`{t` `in` `1..T}` `X[t]` `<=`
`7.5`. If `relax_integrality` is set to `1`,
then the variables are made continuous, but otherwise the constraint
remains the same. If `relax_integrality` is instead left at
`0`, then presolve will tighten `7.5` to `7`
before sending the integer program to the solver. This has no effect
on the integer optimum, but by tightening the constraint it may cause
the solver's relaxation to have a higher value than AMPL's relaxation.

For purposes of solving the problem, the solver's higher relaxation
value is normally to be preferred. In some iterative schemes that
solve a series of relaxations, however, only the lower true relaxation
value makes sense. To ensure that you get the optimum of the true
relaxation, either set `option` `relax_integrality`
`1` or set `option` `presolve` `0` and
turn on the solver's `relax` directive.

- 7.3
- How can I "break" a run of an integer programming solver and get back the best integer solution found so far?

The "break" signal (Ctrl-C for many computers) stops the solver and returns control to AMPL, but does not necessarily return any solution from the solver. Some solvers may make provision to "catch" the break signal and return the best solution found so far; consult the solver directive instructions to see if this is the case for the solver that you are using.

Various solver directives can stop a run and return the current incumbent optimal solution, but they must be given before the run begins. Available stopping criteria may include number of branch-and-bound nodes, number of integer solutions, and total time. Directives are different for each solver, so consult AMPL's solver directive instructions for details.

- 7.4
- How can I use the solver's "special ordered sets" feature?

Special ordered sets of type 2 (SOS2s) are used automatically by some solvers (including CPLEX and OSL) to handle piecewise-linear functions as described in Chapter 14 of the AMPL book.

Special ordered sets of type 1 and 3 are most useful for handling
variables that are restricted to a finite but not regularly-spaced
series of values. For example, a variable `Cap[j]` standing
for capacity of warehouse `j` might be required to take one of
the values 0, 15, 25 or 30. AMPL doesn't currently have any
convenient way to express such restrictions. (CPLEX's `sosscan`
directive invokes a preprocessor that can automatically identify
constraints that have a SOS3 interpretation. However, AMPL does not
usually supply enough information about these constraints to afford
any significant efficiency in the branch-and-bound process.)

- 8.1
- What is the student edition of AMPL?

The AMPL Student Edition consists of the AMPL software together with the MINOS and CPLEX solvers. It is limited to 300 variables and 300 constraints and objectives, and does not support user-defined functions, but is otherwise identical to the full professional edition.

The latest version of the student edition for PCs is the AMPL Plus 1.6 Student Edition, which
incorporates a Microsoft Windows graphical user interface. *Users of
the AMPL Plus Student Edition software will need to download a new
version for 2002* -- see our book
software update instructions for details. Student editions of the
AMPL translator and some corresponding solvers can also be downloaded for most popular
Unix workstations and for Linux on PCs.

Educational discounts for other versions of AMPL are also available from several AMPL vendors.

- 8.2
- What is the professional edition of AMPL?

The professional edition is the full-featured, unrestricted version. Numbers of variables and constraints are limited only by available computer resources.

Professional edition users may choose among numerous solvers. Several vendors offer packages of the AMPL software with selected solvers. Other solvers may be added at any time, at only the cost of the solver software; you do not need to buy additional AMPL software in order to add a solver.

- 8.3
- Is there a graphical ("gui") version of AMPL?

Several experimental AMPL graphical interfaces for Windows are available for downloading at no charge.

If you are using a Unix workstation, AMPL's command-line environment should run nicely within a command or text window. The workstation's windowing software lets you scroll back through an AMPL session and copy previous AMPL commands. You can set up other windows to simultaneously view the model and data. You can download a similar, free scrolling-window utility for use with AMPL's command-line environment under Windows.

- 8.4
- Can I get a version of AMPL that will run on my computer, under my computer's operating system?

On 80386, 80486, and Pentium-based personal computers (or "PCs" or "IBM clones"), AMPL runs and under Linux, FreeBSD, Solaris, and Microsoft Windows (including NT, XP, Vista).

AMPL runs on RISC workstations from DEC, Hewlett-Packard, IBM, Silicon Graphics, and Sun, under their versions of Unix. Both Solaris 1.1 (alias SunOS 4.1) and Solaris 2.x are supported on Sun machines. <-- Unix versions are also available for PCs running Linux and FreeBSD.-->

AMPL also works on Apple Macintosh computers that run the MacOSX 10.x operating system.

- 8.5
- Where can I get more information about how AMPL works under specific operating systems?

If you are using the student edition of AMPL that comes with the AMPL book, then you will find this information in a booklet ("Using the AMPL Student Edition Under MS-DOS") that is also packaged with the book.

Operating system information for other AMPL versions is available in two booklets, "Using AMPL Under MS-DOS" and "Using AMPL Under Unix". You can download them in gzip-compressed postscript form (see our instructions), or write to info@ampl.com to request a printed copy.

- 8.6
- How can I determine the version number of the copy of AMPL that I'm currently running?

You can look at the current version message by invoking AMPL with the -v command-line switch:

%AMPL Version 20000516ampl -v

Or, at any point in an AMPL session, you can see the version message by looking at the contents of AMPL's version option, by typing

ampl:option version 'AMPL Version 20000516\ '; ampl:option version;

or

ampl:AMPL Version 20000516 ampl:print $version;

The 8-digit number represents a date in the form *yyyymmdd* -- 16 May
2000 in this example. You can compare this date against the dates of
the entries in the AMPL change logs and
in the writeups of new AMPL features.

- 8.7
- How can I learn about updates to AMPL, and where can I get updated AMPL software?

AMPL's modeling language and environment have continued to evolve in response to users' needs. Thus many significant features have been added since the publication of the AMPL book. See the AMPL Extensions page for links to online summaries, descriptions and examples of new features.

To obtain the latest updates to the AMPL student edition software, see
our downloads page. If you send the
one-line E-mail message "`subscribe` `ampl`" to
`netlib@research.bell-labs.com`, then you will receive an e-mail
message whenever we update this software. (Updates are made
frequently. Send netlib the message "`unsubscribe`
`ampl`" to turn these notifications back off.)

For updates to other AMPL software, contact if possible the vendor that originally sold you AMPL. If you're having trouble locating your vendor, our vendor list may help. If vendor information is not available or your original vendor cannot be located, write to info@ampl.com for assistance.

- 9.1
- What solvers does AMPL support?

AMPL works with a variety of solvers for linear, nonlinear and integer programming. See our solver listings for details.

- 9.2
- Can I buy AMPL and the solvers separately?

Yes. Once you have AMPL running, you add a solver by simply

- installing the solver software, and
- installing that solver's AMPL driver in a directory that's in your search path.

The procedure is equally simple if you already have a solver running, and want to later add AMPL to your system.

There is a separate AMPL driver for each solver package. The driver may be already included in the package (as in the case of CPLEX), or may be available on-line (as for MINOS and OSL), or may be available directly from the solver's distributor. Details are provided in our solver listing.

In most cases, there is no extra charge for the AMPL driver.

- 9.3
- Where can I get more information about AMPL's interface to specific solvers?

Many solver options can be specified directly from AMPL. You don't need to prepare separate "spec files" or run solvers outside the AMPL environment in order to get the benefits of these options.

If you are using the student edition software that comes with the AMPL book, then you will find a guide to using the packaged solvers (MINOS and CPLEX) in a booklet ("Using the AMPL Plus Student Edition Under Microsoft Windows") that is packaged with the book.

For the professional edition of AMPL, separate guides to solver directives are available online, from the solver developers, or both. See the AMPL solver listing for more information.

- 9.4
- How can I interface my own solver to AMPL?

AMPL has a publicly documented interface that you can use to make your own link to any solver you are developing. The interface works through files; AMPL writes a problem file to be read by your solver, and your solver writes a solution file to be read back by AMPL. The file format has equivalent binary and ASCII versions. It offers the flexibility needed to support a wide variety of solvers, yet is designed to afford very efficient reading and writing.

The AMPL interface is described and illustrated in "Hooking Your Solver to AMPL". You can also download standard interface routines (in C) for reading and writing the AMPL file formats, along with a variety of examples of complete AMPL/solver links; see our hooking page for details.

- 10.1
- Where can I get more information on AMPL?

The AMPL book is the definitive introduction, tutorial and reference for AMPL. Its contents, introduction and first chapter are available on-line, along with ordering instructions. All copies of the book include a disk containing the student edition of AMPL for DOS/Windows PCs.

To learn about new AMPL features have been implemented since the appearance of the book, see the AMPL Extensions pages.

The following articles describe and analyze many aspects of the design of AMPL:

- Robert Fourer, David M. Gay and Brian W. Kernighan, A
Modeling Language for Mathematical Programming.
*Management Science***36**(1990) 519-554. - Robert Fourer and David M. Gay, Experience with a Primal
Presolve Algorithm. In
*Large Scale Optimization: State of the Art,*W.W. Hager, D.W. Hearn and P.M. Pardalos, eds., Kluwer Academic Publishers (Dordrecht, 1994) 135-154. - Robert Fourer and David M. Gay, Expressing Special
Structures in an Algebraic Modeling Language for Mathematical
Programming.
*ORSA Journal on Computing***7**(1995) 166-190.

- 10.2
- How can I get answers to more questions about AMPL?

Mail to info@ampl.com is forwarded to the AMPL developers for reply. See our vendor listing for direct numbers and addresses of particular vendors of AMPL and solvers.