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.
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. 8 (Problem Formulation and Solutions).
We refer to your AMPL documentation for how to specify optimization problems in AMPL and attach MOSEK as a solver.
6.1 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 6.1.
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 6.2.
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 ;
In AMPL 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.2 Retrieving solutions¶
6.2.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 6.1 for possible values of this parameter.
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.2.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.3 Optimizer options¶
6.3.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. 11.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.3.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 |
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.3.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.4 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.5 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. 10.2 (Automatic Repair of Infeasible Problems).
6.6 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.7 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