6 The MOSEK-bundled AMPL shell

AMPL is a modeling language for specifying linear and nonlinear optimization models in a natural way. AMPL also makes it easy to solve the problem and e.g. display the solution or part of it. We will not discuss the specifics of the AMPL language here but instead refer the reader to [FGK03], http://ampl.com/BOOK/download.html and the AMPL website http://www.ampl.com.

AMPL cannot solve optimization problems by itself but requires a link to an optimizer. The MOSEK distribution includes:

  • An AMPL link which makes it possible to use MOSEK as an optimizer within AMPL. The link can be used from any AMPL shell.
  • The full, official AMPL shell repackaged under the name mampl. This is sold as a separate product, and it can be hooked to other optimizers as well.

Note

  • To use MOSEK from AMPL you need to set up the system path to the MOSEK command line tool.
  • It is possible to specify problems in AMPL that cannot be solved by MOSEK. The optimization problem must be a smooth convex optimization problem as discussed in Sec. 7 (Problem Formulation and Solutions).

For the remainder of this section we refer to the MOSEK-bundled mampl as the AMPL interpreter of choice. However, the tutorial applies also to any other standard AMPL shell available to the user.

6.1 Locating the AMPL shell

Assuming MSKHOME is the folder in which MOSEK has been installed, the AMPL shell is the executable file

{MSKHOME}/mosek/8/tools/platform/{PLATFORM}/bin/mampl

for Linux and OSX users (PLATFORM must be among linux64x86, osx64x86), and under

{MSKHOME}\mosek\8\tools\platform\{PLATFORM}\bin\mampl

for Windows users (PLATFORM must be among win32x86, win64x86).

6.2 An example

In many instances, you can successfully apply MOSEK simply by specifying the model and data, setting the solver option to MOSEK, and typing solve.

Consider a simple linear optimization problem formulated as an AMPL model in Listing 3.

Listing 3 An example of an optimization problem in AMPL language. Click here to download.
set NUTR ordered;
set FOOD ordered;

param cost {FOOD} >= 0;
param f_min {FOOD} >= 0, default 0;
param f_max {j in FOOD} >= f_min[j], default Infinity;

param n_min {NUTR} >= 0, default 0;
param n_max {i in NUTR} >= n_min[i], default Infinity;

param amt {NUTR,FOOD} >= 0;

# --------------------------------------------------------

var Buy {j in FOOD} >= f_min[j], <= f_max[j];

# --------------------------------------------------------

minimize Total_Cost:  sum {j in FOOD} cost[j] * Buy[j];

minimize Nutr_Amt {i in NUTR}: sum {j in FOOD} amt[i,j] * Buy[j];

# --------------------------------------------------------

subject to Diet {i in NUTR}:
   n_min[i] <= sum {j in FOOD} amt[i,j] * Buy[j] <= n_max[i];

We can specify the input data using an input file again following the AMPL syntax, as in Listing 4.

Listing 4 An example of data for an optimization problem using AMPL language. Click here to download.
param:  FOOD:                    cost  f_min  f_max :=
  "Quarter Pounder w/ Cheese"    1.84     .      .
  "McLean Deluxe w/ Cheese"      2.19     .      .
  "Big Mac"                      1.84     .      .
  "Filet-O-Fish"                 1.44     .      .
  "McGrilled Chicken"            2.29     .      .
  "Fries, small"                  .77     .      .
  "Sausage McMuffin"             1.29     .      .
  "1% Lowfat Milk"                .60     .      .
  "Orange Juice"                  .72     .      . ;

param:  NUTR:   n_min  n_max :=
        Cal      2000      .
        Carbo     350    375 
        Protein    55      .
        VitA      100      .
        VitC      100      .
        Calc      100      .
        Iron      100      . ;
     
param amt (tr):
                               Cal  Carbo Protein   VitA   VitC  Calc  Iron :=
  "Quarter Pounder w/ Cheese"  510     34     28     15      6    30    20 
  "McLean Deluxe w/ Cheese"    370     35     24     15     10    20    20 
  "Big Mac"                    500     42     25      6      2    25    20 
  "Filet-O-Fish"               370     38     14      2      0    15    10 
  "McGrilled Chicken"          400     42     31      8     15    15     8 
  "Fries, small"               220     26      3      0     15     0     2 
  "Sausage McMuffin"           345     27     15      4      0    20    15 
  "1% Lowfat Milk"             110     12      9     10      4    30     0 
  "Orange Juice"                80     20      1      2    120     2     2 ;

Invoke the AMPL shell:

mampl

and type in the commands:

ampl: model diet.mod;
ampl: data diet.dat;
ampl: option solver mosek;
ampl: solve;

The resulting output is:

MOSEK finished.
Problem status    - PRIMAL_AND_DUAL_FEASIBLE
Solution status   - OPTIMAL
Primal objective  - 14.8557377
Dual objective    - 14.8557377

Objective = Total_Cost

6.3 Retrieving solutions

6.3.1 Status codes

The AMPL parameter solve_result_num is used to indicate the outcome of the optimization process. It is used as follows

ampl: display solve_result_num

Please refer to table Table 2 for possible values of this parameter.

Table 2 Interpretation of solve_result_num.
Value Message
0 the solution is optimal.
100 suboptimal primal solution.
101 superoptimal (dual feasible) solution.
150 the solution is near optimal.
200 primal infeasible problem.
300 dual infeasible problem.
400 too many iterations.
500 solution status is unknown.
501 ill-posed problem, solution status is unknown.
> 501 Mapped MOSEK response code. See note below.

MOSEK response codes are mapped to AMPL return codes greater than 501. In order to get the actual response code the base value 501 must be subtracted. For example: the AMPL return code 502 corresponds to MOSEK response code 1.

6.3.2 Which solution is returned

MOSEK can produce three types of solutions: basic, interior point and integer. The solution returned to AMPL is determined according to the following rules:

  • For problems containing integer variables only the integer solution is available and it is returned.
  • For nonlinear problems only the interior point solution is available and it is returned.
  • For linear problems, if both basic and interior point solution are available, then the basic solution is returned. Otherwise the only available solution is returned.

6.4 Optimizer options

6.4.1 The MOSEK parameter database

The MOSEK optimizer can be controller using solver parameters, as described in Sec. 5.4 (Solver Parameters). These parameters can be modified within AMPL as shown in the example below:

ampl: model diet.mod;
ampl: data diet.dat;
ampl: option solver mosek;
ampl: option mosek_options
ampl? 'msk_ipar_optimizer = msk_optimizer_primal_simplex \
ampl? msk_ipar_sim_max_iterations = 100000';
ampl: solve;

In the example above a string called mosek_options is created which contains the parameter settings. Each parameter setting has the format

parameter_name = value

where parameter_name is a valid MOSEK parameter name. See Sec. 13.2 (Parameters (alphabetical list sorted by type)) for a description of all valid MOSEK parameters.

An alternative way of specifying the parameters is

ampl: option mosek_options
ampl? 'msk_ipar_optimizer = msk_optimizer_primal_simplex'
ampl? 'msk_ipar_sim_max_iterations = 100000';

New parameters can also be appended to an existing option string as shown below.

ampl: option mosek_options $mosek_options
ampl? ' msk_ipar_sim_print_freq = 0 msk_ipar_sim_max_iterations = 1000';

The expression $mosek_options expands to the current value of the option. Line two in the example appends an additional value msk_ipar_sim_max_iterations to the option string.

6.4.2 Options

MOSEK recognizes the following AMPL options.

outlev

Controls the amount of printed output. \(0\) means no printed output and a higher value means progressively more output. An example of setting outlev is as follows:

ampl: option mosek_options 'outlev=2';

wantsol

Controls the solution information generated when run in standalone mode (called without the argument -AMPL). It should be constructed as the sum of

1 to write a .sol file
2 to print the primal variable values
4 to print the dual variable values
8 to suppress printing the solution message

We refer the reader to the AMPL manual [FGK03] for more details.

6.4.3 Passing variable names to MOSEK

AMPL assigns meaningful names to all the constraints and variables. Since MOSEK uses item names in error and log messages, it may be useful to pass the AMPL names to MOSEK. This can be achieved with the command:

ampl: option auxfiles rc;
ampl: solve;

6.5 Hot-start

Frequently, a sequence of optimization problems is solved where each problem differs only slightly from the previous problem. In that case it may be advantageous to use the previous optimal solution to warm-start the optimizer. Such a facility is available in MOSEK only when the simplex optimizer is used.

The warm-start facility exploits the AMPL variable suffix sstatus to communicate the optimal basis back to AMPL, and AMPL uses this facility to communicate an initial basis to MOSEK. The following example demonstrates this feature.

ampl: model diet.mod;
ampl: data diet.dat;
ampl: option solver mosek;
ampl: option mosek_options
ampl? 'msk_ipar_optimizer = msk_optimizer_primal_simplex outlev=2';
ampl: solve;
ampl: display Buy.sstatus;
ampl: solve;

The resulting output is:

Accepted: msk_ipar_optimizer                  = MSK_OPTIMIZER_PRIMAL_SIMPLEX
Accepted: outlev                              = 2

Computer   - Platform               : Linux/64-X86
Computer   - CPU type               : Intel-P4
MOSEK      - task name              :
MOSEK      - objective sense        : min
MOSEK      - problem type           : LO (linear optimization problem)
MOSEK      - constraints            : 7                 variables              : 9
MOSEK      - integer variables      : 0
Optimizer started.
Simplex optimizer started.
Presolve started.
Linear dependency checker started.
Linear dependency checker terminated.
Presolve   - Stk. size (kb) : 0
Eliminator - tries                  : 0                 time                   : 0.00
Eliminator - elim's                 : 0
Lin. dep.  - tries                  : 1                 time                   : 0.00
Lin. dep.  - number                 : 0
Presolve terminated. Time: 0.00
Primal simplex optimizer started.
Primal simplex optimizer setup started.
Primal simplex optimizer setup terminated.
Optimizer  - solved problem         : the primal
Optimizer  - constraints            : 7                 variables              : 9
Optimizer  - hotstart               : no
ITER      DEGITER(%)  PFEAS       DFEAS       POBJ                  DOBJ                  TIME      TOTTIME
0         0.00        1.40e+03    NA          1.2586666667e+01      NA                    0.00      0.01
3         0.00        0.00e+00    NA          1.4855737705e+01      NA                    0.00      0.01
Primal simplex optimizer terminated.
Simplex optimizer terminated. Time: 0.00.
Optimizer terminated. Time: 0.01
Return code - 0  [MSK_RES_OK]
MOSEK finished.
Problem status    : PRIMAL_AND_DUAL_FEASIBLE
Solution status   : OPTIMAL
Primal objective  : 14.8557377
Dual objective    : 14.8557377

Objective = Total_Cost
Buy.sstatus [*] :=
'Quarter Pounder w/ Cheese'  bas
'McLean Deluxe w/ Cheese'  low
'Big Mac'  low
Filet-O-Fish  low
'McGrilled Chicken'  low
'Fries, small'  bas
'Sausage McMuffin'  low
'1% Lowfat Milk'  bas
'Orange Juice'  low
;
Accepted: msk_ipar_optimizer                  = MSK_OPTIMIZER_PRIMAL_SIMPLEX
Accepted: outlev                              = 2
Basic solution
Problem status  : UNKNOWN
Solution status : UNKNOWN
Primal - objective: 1.4855737705e+01   eq. infeas.: 3.97e+03 max bound infeas.: 2.00e+03
Dual   - objective: 0.0000000000e+00   eq. infeas.: 7.14e-01 max bound infeas.: 0.00e+00

Computer   - Platform               : Linux/64-X86
Computer   - CPU type               : Intel-P4
MOSEK      - task name              :
MOSEK      - objective sense        : min
MOSEK      - problem type           : LO (linear optimization problem)
MOSEK      - constraints            : 7                 variables              : 9
MOSEK      - integer variables      : 0
Optimizer started.
Simplex optimizer started.
Presolve started.
Presolve   - Stk. size (kb) : 0
Eliminator - tries                  : 0                 time                   : 0.00
Eliminator - elim's                 : 0
Lin. dep.  - tries                  : 0                 time                   : 0.00
Lin. dep.  - number                 : 0
Presolve terminated. Time: 0.00
Primal simplex optimizer started.
Primal simplex optimizer setup started.
Primal simplex optimizer setup terminated.
Optimizer  - solved problem         : the primal
Optimizer  - constraints            : 7                 variables              : 9
Optimizer  - hotstart               : yes
Optimizer  - Num. basic             : 7                 Basis rank             : 7
Optimizer  - Valid bas. fac.        : no
ITER      DEGITER(%)  PFEAS       DFEAS       POBJ                  DOBJ                  TIME      TOTTIME
0         0.00        0.00e+00    NA          1.4855737705e+01      NA                    0.00      0.01
0         0.00        0.00e+00    NA          1.4855737705e+01      NA                    0.00      0.01
Primal simplex optimizer terminated.
Simplex optimizer terminated. Time: 0.00.
Optimizer terminated. Time: 0.01
Return code - 0  [MSK_RES_OK]
MOSEK finished.
Problem status    : PRIMAL_AND_DUAL_FEASIBLE
Solution status   : OPTIMAL
Primal objective  : 14.8557377
Dual objective    : 14.8557377

Objective = Total_Cost

Please note that the second solve takes fewer iterations since the previous optimal basis is reused.

6.6 Infeasibility report

For linear optimization problems without any integer constrained variables MOSEK can generate an infeasibility report automatically. The report provides important information about the infeasibility.

The generation of the infeasibility report is turned on using the parameter setting

option auxfiles rc;
option mosek_options 'msk_ipar_infeas_report_auto=msk_on';

For further details about infeasibility report see Sec. 11 (Analyzing Infeasible Problems).

6.7 Sensitivity analysis

MOSEK can calculate sensitivity information for the objective and constraints. To enable sensitivity information set the option:

sensitivity = 1

Results are returned in variable/constraint suffixes as follows:

  • .down Smallest value of objective coefficient/right hand side before the optimal basis changes.
  • .up Largest value of objective coefficient/right hand side before the optimal basis changes.
  • .current Current value of objective coefficient/right hand side.

For ranged constraints sensitivity information is returned only for the lower bound.

The example below returns sensitivity information on the diet model.

ampl: model diet.mod;
ampl: data diet.dat;
ampl: option solver mosek;
ampl: option mosek_options 'sensitivity=1';

ampl: solve;
#display sensitivity information and current solution.
ampl: display _var.down,_var.current,_var.up,_var;
#display sensitivity information and optimal dual values.
ampl: display _con.down,_con.current,_con.up,_con;

The resulting output is:

Return code - 0  [MSK_RES_OK]
MOSEK finished.
Problem status    : PRIMAL_AND_DUAL_FEASIBLE
Solution status   : OPTIMAL
Primal objective  : 14.8557377
Dual objective    : 14.8557377


suffix up OUT;
suffix down OUT;
suffix current OUT;
Objective = Total_Cost
:  _var.down _var.current       _var.up        _var      :=
1   1.37385       1.84             1.86075    4.38525
2   1.8677        2.19      Infinity          0
3   1.82085       1.84      Infinity          0
4   1.35466       1.44      Infinity          0
5   1.57633       2.29      Infinity          0
6   0.094         0.77             0.794851   6.14754
7   1.22759       1.29      Infinity          0
8   0.57559       0.6              0.910769   3.42213
9   0.657279      0.72      Infinity          0
;
ampl: display _con.down,_con.current,_con.up,_con;
:     _con.down    _con.current   _con.up      _con       :=
1   -Infinity           2000      3965.37    0
2         297.6          350       375       0.0277049
3   -Infinity             55       172.029   0
4          63.0531       100       195.388   0.0267541
5   -Infinity            100       132.213   0
6   -Infinity            100       234.221   0
7          17.6923       100       142.821   0.0248361
;

6.8 Using the command line version of the AMPL interface

AMPL can generate a data file containing the optimization problem and all relevant information which can then be read and solved by the MOSEK command line tool.

When the problem has been loaded into AMPL, the commands

ampl: option auxfiles rc;
ampl: write  bprob;

will make AMPL write the appropriate data files, i.e.

prob.nl
prob.col
prob.row

Then the problem can be solved using the command line version of MOSEK as follows

mosek prob.nl outlev=10 -a

The option -a indicates that MOSEK is invoked in AMPL mode. When MOSEK is invoked in AMPL mode the standard MOSEK command line options should appear after the -a option except for the file name which should be the first argument. As the above example demonstrates MOSEK accepts command line options following the AMPL convention. To see which command line arguments MOSEK accepts in AMPL mode write:

mosek -= -a

For linear, quadratic and quadratically constrained problems a text file representation of the problem can be obtained by performing one of the following conversions:

mosek prob.nl -a -x -out prob.mps
mosek prob.nl -a -x -out prob.opf
mosek prob.nl -a -x -out prob.lp