The OPTLSO Procedure

Example 3.4 Combining MPS and FCMP Function Definitions

In this example, the linear component of the same problem definition as in Example 3.1 is described by using the OPTMODEL procedure and is saved as an MPS data set. The quadratic component of the objective is then defined by using the FCMP function QUADOBJ.

As in Using MPS Format, you can use the macro definition lsompsmod to strip brackets from the resulting data set:

%macro lsompsmod(setold,setnew);
   data &setnew(drop=i);
      set &setold;
      array FC{*} _CHARACTER_;
      do i=1 to dim(FC);
         FC[i] = compress(FC[i], "[]");
      end;
   run;
%mend;

For more complicated array structures, take care to ensure that the resulting transformation is well defined. Next you run a PROC OPTMODEL step that outputs a MPS data set, followed by the %LSOMPSMOD macro, followed by the PROC FCMP step that defines the FCMP function QUADOBJ, followed by a PROC OPTLSO step that takes as input both the MPS data set that was output by PROC OPTMODEL and transformed by the %LSOMPSMOD macro and the quadratic component of the objective that was defined by PROC FCMP.

proc optmodel;
   var x{1..13} >= 0 <= 1;
   for {i in 10..12} x[i].ub = 100;
   min linobj = 5*sum{i in 1..4} x[i] - sum{i in 5..13} x[i];
   con a1: 2*x[1] + 2*x[2] + x[10] + x[11] <= 10;
   con a2: 2*x[1] + 2*x[3] + x[10] + x[12] <= 10;
   con a3: 2*x[1] + 2*x[3] + x[11] + x[12] <= 10;
   con a4: -8*x[1] + x[10] <= 0;
   con a5: -8*x[2] + x[11] <= 0;
   con a6: -8*x[3] + x[12] <= 0;
   con a7: -2*x[4] - x[5] + x[10] <= 0;
   con a8: -2*x[6] - x[7] + x[11] <= 0;
   con a9: -2*x[8] - x[9] + x[12] <= 0;
   save mps lindataOld;
quit;
%lsompsmod(lindataOld, lindata);

proc fcmp outlib=sasuser.myfuncs.mypkg;
   function quadobj(x1,x2,x3,x4,f1);
      return (f1 - 5*(x1**2 + x2**2 + x3**2 + x4**2));
   endsub;
run;

data objdata;
   input _id_ $ _function_ $ _sense_ $;
   datalines;
f1  linobj    .
f   quadobj   min
;

options cmplib = sasuser.myfuncs;
proc optlso
   primalout = solution
   mpsdata   = lindata
   objective = objdata;
   performance nthreads=2;
run;

proc print data=solution;
run;

Output 3.4.1 shows the output from running these steps.

Output 3.4.1: Using MPS Format

The OPTLSO Procedure

Performance Information
Execution Mode Single-Machine
Number of Threads 2

Problem Summary
Problem Type NLP
   
MPS Data Set LINDATA
Objective Definition Set OBJDATA
   
Number of Variables 13
Integer Variables 0
Continuous Variables 13
   
Number of Constraints 9
Linear Constraints 9
Nonlinear Constraints 0
   
Objective Definition Source OBJDATA
Objective Sense Minimize
Objective Intermediate Functions 1

Solution Summary
Solution Status Function convergence
Objective -15.00072737
Infeasibility 0.0007273676
Iterations 22
Evaluations 2520
Cached Evaluations 514
Global Searches 1
Population Size 160
Seed 1

Obs _sol_ _id_ _value_
1 0 _obj_ -15.0007
2 0 _inf_ 0.0007
3 0 x1 1.0000
4 0 x2 1.0000
5 0 x3 1.0000
6 0 x4 1.0000
7 0 x5 1.0000
8 0 x6 1.0000
9 0 x7 1.0000
10 0 x8 1.0000
11 0 x9 1.0000
12 0 x10 3.0007
13 0 x11 3.0000
14 0 x12 3.0000
15 0 x13 1.0000
16 0 f -15.0007
17 0 f1 4.9993
18 0 linobj 4.9993