# AMPL Interface

AMPL is an algebraic modeling language for describing large-scale complex mathematical problems, it was hooked to many commercial and open-source mathematical optimizers, with various data interfaces and extensions, and received high popularity among both industries and institutes, see Who uses AMPL? for more information. The solver coptampl uses Cardinal Optimizer to solve linear programming, convex quadratic programming, convex quadratic constrainted programming and mixed integer programming problems. Normally coptampl is invoked by AMPL’s solve command, which gives the invocation:

coptampl stub -AMPL


in which stub.nl is an AMPL generic output file (possibly written by 'ampl -obstub' or 'ampl -ogstub'). After solving the problem, coptampl writes a stub.sol file for use by AMPL’s solve and solution commands. When you run AMPL, this all happens automatically if you give the AMPL commands:

ampl: option solver coptampl;
ampl: solve;


## Installation Guide

To use coptampl in AMPL, you must have a valid AMPL license and make sure that you have installed Cardinal Optimizer and setup its license properly, see How to install Cardinal Optimizer for details. Be sure to check if it satisfies the following requirements for different operating systems.

### Windows

On Windows platform, the coptampl.exe utility and the copt.dll dynamic library contained in the Cardinal Optimizer must appear somewhere in your user or system PATH environment variable (or in the current directory).

To test if your setting meets the above requirements, you can check it by executing commands below in command prompt:

coptampl -v


And you are expected to see output similar to the following on screen:

AMPL/x-COPT Optimizer [6.0.0] (windows-x86), driver(20220526), MP(20220526)

If the commands failed, then you should recheck your settings.

### Linux

On Linux platform, the coptampl utility must appears somewhere in your $PATH environment variable, while the libcopt.so shared library must appears somewhere in your $LD_LIBRARY_PATH environment variable.

Similarly, to test if your setting meets the above requirements, just execute commands below in shell:

coptampl -v


And you are expected to see output similar to the following on screen:

AMPL/x-COPT Optimizer [6.0.0] (linux-x86), driver(20220526), MP(20220526)

### MacOS

On MacOS platform, the coptampl utility must appears somewhere in your $PATH environment variable, while the libcopt.dylib dynamic library must appears somewhere in your $DYLD_LIBRARY_PATH environment variable.

You can execute commands below in shell to see if your settings meets the above requirements:

coptampl -v


And you are expected to see output similar to the following on screen:

AMPL/x-COPT Optimizer [6.0.0] (macos-x86), driver(20220526), MP(20220526)

## Solver Options and Exit Codes

The coptampl utility offers some options to customize its behavior. Uers can control it by setting the environment variable copt_options or use AMPL’s option command. To see all available options, please invoke:

coptampl -=


The supported parameters and their interpretation for current version are shown in Table 4:

 Parameter Interpretation barhomogeneous whether to use homogeneous self-dual form in barrier bariterlimit iteration limit of barrier method barthreads number of threads used by barrier basis whether to use or return basis status bestbound whether to return best bound by suffix conflictanalysis whether to perform conflict analysis crossoverthreads number of threads used by crossover cutlevel level of cutting-planes generation divingheurlevel level of diving heuristics dualize whether to dualize a problem before solving it dualperturb whether to allow the objective function perturbation dualprice specifies the dual simplex pricing algorithm dualtol the tolerance for dual solutions and reduced cost feastol the feasibility tolerance heurlevel level of heuristics iisfind whether to compute IIS and return result iismethod specify the IIS method inttol the integrality tolerance for variables logging whether to print solving logs logfile name of log file exportfile name of model file to be exported lpmethod method to solve the LP problem matrixtol input matrix coefficient tolerance mipstart whether to use initial values for MIP problem miptasks number of MIP tasks in parallel nodecutrounds rounds of cutting-planes generation of tree node nodelimit node limit of the optimization objno objective number to solve count whether to count the number of solutions stub name prefix for alternative MIP solutions written presolve level of presolving before solving a problem relgap the relative gap of optimization absgap the absolute gap of optimization return_mipgap whether to return absolute/relative gap by suffix rootcutlevel level of cutting-planes generation of root node rootcutrounds rounds of cutting-planes generation of root node roundingheurlevel level of rounding heuristics scaling whether to perform scaling before solving a problem simplexthreads number of threads used by dual simplex sos whether to use ‘.sosno’ and ‘.ref’ suffix sos2 whether to use SOS2 to represent piecewise linear terms strongbranching level of strong branching submipheurlevel level of Sub-MIP heuristics threads number of threads to use timelimit time limit of the optimization treecutlevel level of cutting-planes generation of search tree wantsol whether to generate ‘.sol’ file

Please refer to COPT Parameters for details.

AMPL uses suffix to store or pass model and solution information, and also some extension features, such as support for SOS constraints. Currently, coptampl support suffix information as shown in Suffix supported by coptampl :

 Suffix Interpretation absmipgap absolute gap for MIP problem bestbound best bound for MIP problem iis store IIS status of variables or constraints nsol number of pool solutions written ref weight of variable in SOS constraint relmipgap relative gap for MIP problem sos store type of SOS constraint sosno type of SOS constraint sosref store variable weight in SOS constraint sstatus basis status of variables and constraints

Users who want to know how to use SOS constraints in AMPL, please refer to resources in AMPL’s website: How to use SOS constraints in AMPL .

When solving finished, coptampl will display a status message and return exit code to AMPL. The exit code can be displayed by:

ampl: display solve_result_num;


If no solution was found or something unexpected happened, coptampl will return non-zero code to AMPL from Table 6:

 Exit Code Interpretation 0 optimal solution 200 infeasible 300 unbounded 301 infeasible or unbounded 600 user interrupted

## Example Usage

The following section will illustrate the use of AMPL by a well-known example called “Diet problem”, which finds a mix of foods that satisfies requirements on the amounts of various vitamins, see AMPL book for details.

Suppose the following kinds of foods are available for the following prices per unit, see Table 7:

 Food Price BEEF 3.19 CHK 2.59 FISH 2.29 HAM 2.89 MCH 1.89 MTL 1.99 SPG 1.99 TUR 2.49

These foods provide the following percentages, per unit, of the minimum daily requirements for vitamins A, C, B1 and B2, see Table 8:

 A C B1 B2 BEEF 60% 20% 10% 15% CHK 8 0 20 20 FISH 8 10 15 10 HAM 40 40 35 10 MCH 15 35 15 15 MTL 70 30 15 15 SPG 25 50 25 15 TUR 60 20 15 10

The problem is to find the cheapest combination that meets a week’s requirements, that is, at least 700% of the daily requirements for each nutrient.

To summarize, the mathematical form for the above problem can be modeled as shown in Eq. 6:

(6)$\begin{split}\textrm{Minimize: } & \\ & \sum_{j \in J} cost_j \cdot buy_j \\ \textrm{Subject to: } & \\ & n\_min_i \leq \sum_{j \in J} amt_{i, j} \cdot buy_j \leq n\_max_i \,\,\, \forall i \in I \\ & f\_min_j \leq buy_j \leq f\_max_j \,\,\, \forall j \in J\end{split}$

The AMPL model for above problem is shown in diet.mod, see Listing 7:

Listing 7 diet.mod
 1# The code is adopted from:
2#
3# https://github.com/Pyomo/pyomo/blob/master/examples/pyomo/amplbook2/diet.mod
4#
5# with some modification by developer of the Cardinal Optimizer
6
7set NUTR;
8set FOOD;
9
10param cost {FOOD} > 0;
11param f_min {FOOD} >= 0;
12param f_max {j in FOOD} >= f_min[j];
13
14param n_min {NUTR} >= 0;
15param n_max {i in NUTR} >= n_min[i];
16
17param amt {NUTR, FOOD} >= 0;
18
19var Buy {j in FOOD} >= f_min[j], <= f_max[j];
20
21minimize Total_Cost:
22  sum {j in FOOD} cost[j] * Buy[j];
23
24subject to Diet {i in NUTR}:
25  n_min[i] <= sum {j in FOOD} amt[i, j] * Buy[j] <= n_max[i];


The data file for above problem is shown in diet.dat, see Listing 8:

Listing 8 diet.dat
 1# The data is adopted from:
2#
3# https://github.com/Pyomo/pyomo/blob/master/examples/pyomo/amplbook2/diet.dat
4#
5# with some modification by developer of the Cardinal Optimizer
6
7data;
8
9set NUTR := A B1 B2 C ;
10set FOOD := BEEF CHK FISH HAM MCH MTL SPG TUR ;
11
12param:   cost  f_min  f_max :=
13  BEEF   3.19    0     100
14  CHK    2.59    0     100
15  FISH   2.29    0     100
16  HAM    2.89    0     100
17  MCH    1.89    0     100
18  MTL    1.99    0     100
19  SPG    1.99    0     100
20  TUR    2.49    0     100 ;
21
22param:   n_min  n_max :=
23   A      700   10000
24   C      700   10000
25   B1     700   10000
26   B2     700   10000 ;
27
28param amt (tr):
29           A    C   B1   B2 :=
30   BEEF   60   20   10   15
31   CHK     8    0   20   20
32   FISH    8   10   15   10
33   HAM    40   40   35   10
34   MCH    15   35   15   15
35   MTL    70   30   15   15
36   SPG    25   50   25   15
37   TUR    60   20   15   10 ;


To solve the problem with coptampl in AMPL, just type commands in command prompt on Windows or shell on Linux and MacOS:

ampl: model diet.mod;
ampl: data diet.dat;
ampl: option solver coptampl;
ampl: option copt_options 'logging 1';
ampl: solve;


coptampl solve it quickly and display solving log and status message on screen:

x-COPT 5.0.1: optimal solution; objective 88.2
1 simplex iterations


So coptampl claimed it found the optimal solution, and the minimal cost is 88.2 units. You can further check the solution by:

ampl: display Buy;


And you will get:

Buy [*] :=
BEEF   0
CHK   0
FISH   0
HAM   0
MCH  46.6667
MTL   0
SPG   0
TUR   0
;


So if we buy 46.667 units of MCH, we will have a minimal cost of 88.2 units.