The OPTMODEL Procedure
Suffixes
You can use suffixes with identifier-expressions to retrieve and modify various auxiliary values maintained by the solver. The values of the suffixes can come from expressions in the declaration of the name that is suffixed. For example, the following declaration of variable v provides the values of several suffixes of v at the same time:
var v >= 0 <= 2 init 1 suffixes=(label='X0000000' status init 'L');
The preceding example sets the lower and upper bounds for variable v (that is, v.lb and v.ub, respectively) to 0 and 2. The solver label (v.label) is set to the string 'X0000000', and the initial solver status (v.status) is 'L'. The initial value of v is also set to 1. You can use more complex expressions in a declaration, as shown in the following example:
num ubound{1..N} init 2;
var x{i in 1..N} >= 0 <= ubound[i] suffixes=(label='X'||put(i,z7.));
The preceding declaration makes the upper bound value for each element of x equal to the value of the element in the ubound array with a corresponding index. That is, for each i in 1 to N, x[i].ub is equal to ubound[i]. Similarly, the declaration provides a distinct .label value for each element of the x array.
The CONSTRAINT, MAX, MIN, PROBLEM, and VAR statements support a SUFFIXES=() clause that allows values for existing, modifiable suffixes (other than .lb and .ub) to be specified with each declaration. This is the syntax for a SUFFIXES=() clause:
SUFFIXES=( values )
Each value specifies a suffix value. The following forms are allowed:
The values of the suffixes also come from the solver or from values assigned by assignment, READ DATA, or other statements (see an example in the section Data Set Input/Output). Note that PROC OPTMODEL allows the .lb and .ub suffixes to be assigned after the declaration even when the declaration provides a value with an expression following >= or <=.
You must use suffixes with names of the appropriate type. For example, the .dual suffix cannot be used with the name of an objective. In particular, local dummy parameter names cannot have suffixes.
Table 15 shows the names of the available suffixes.
Table 15: Suffix Names
| Name Type | Suffix | Modifiable | Description |
|---|---|---|---|
| any | .name | No | Name text for any non-dummy symbol |
| Constraint | .active | No | Active status in the current problem |
| Constraint | .block | Yes | Block ID for Dantzig-Wolfe decomposition |
| Constraint | .body | No | Current constraint body value |
| Constraint | .dual | Yes | Dual value from the solver |
| Constraint | .label | Yes | Label text for the solver |
| Constraint | .lb | Yes | Current lower bound |
| Constraint | .lbmax | No | Largest value of the stability interval for the lower bound in sensitivity analysis |
| Constraint | .lbmin | No | Smallest value of the stability interval for the lower bound in sensitivity analysis |
| Constraint | .status | Yes | Status information from the solver |
| Constraint | .ub | Yes | Current upper bound |
| Constraint | .ubmax | No | Largest value of the stability interval for the upper bound in sensitivity analysis |
| Constraint | .ubmin | No | Smallest value of the stability interval for the upper bound in sensitivity analysis |
| Implicit variable | .sol | No | Current solution value |
| Objective | .active | No | Active status in the current problem |
| Objective | .sol | No | Current objective value |
| Objective | .label | Yes | Label text for the solver |
| Problem | .active | No | Active status of the problem |
| Problem | .label | Yes | Label text for the solver |
| Variable | .active | No | Active status in the current problem |
| Variable | .block | Yes | Block ID for Benders decomposition |
| Variable | .dcone | No | Dual value for a cone constraint |
| Variable | .direction | Yes | Branching direction for MILP |
| Variable | .dual | Yes | Alias for .rc |
| Variable | .fixed | No | Fixed status |
| Variable | .label | Yes | Label text for the solver |
| Variable | .lb | Yes | Lower bound |
| Variable | .lbmax | No | Largest value of the stability interval for the lower bound in sensitivity analysis |
| Variable | .lbmin | No | Smallest value of the stability interval for the lower bound in sensitivity analysis |
| Variable | .msinit | No | Numeric value at the best starting point reported by the multistart solver |
| Variable | .objmax | No | Largest value of the stability interval for the objective coefficient in sensitivity analysis |
| Variable | .objmin | No | Smallest value of the stability interval for the objective coefficient in sensitivity analysis |
| Variable | .priority | Yes | Branching priority for MILP and CLP |
| Variable | .rc | Yes | Reduced cost (LP) or gradient of the Lagrangian function |
| Variable | .relax | Yes | Relaxation of integrality restriction |
| Variable | .sol | No | Current variable value |
| Variable | .sol[i] | Yes | Saved solution value |
| Variable | .status | Yes | Status information from the solver |
| Variable | .ub | Yes | Upper bound |
| Variable | .ubmax | No | Largest value of the stability interval for the upper bound in sensitivity analysis |
| Variable | .ubmin | No | Smallest value of the stability interval for the upper bound in sensitivity analysis |
The .sol suffix for a variable, implicit variable, or objective can be used within a declaration to reference the current value of the symbol. It is treated as a constant in such cases. The value is independent of the current problem. When the OPTMODEL procedure processes a SOLVE statement, the value is fixed at the start of the SOLVE statement. The .sol suffix can be followed by a positive integer solution index to refer to a particular solution that the SOLVE statement returns. See the section Multiple Solutions for more information about accessing multiple solutions from the solver. Each problem tracks saved solution values separately. Outside of declarations, a variable, implicit variable, or objective name with the .sol suffix and no solution index is equivalent to the unsuffixed name.
The .status suffix reports status information from the solver. Currently, the LP, MILP, NLP, and QP solvers provide status information. For other solvers, the .status values default to a single blank character.
For the LP solver, the .status suffix takes the same character values that are found in the _STATUS_ variable of the PRIMALOUT= and DUALOUT= data sets for the OPTLP procedure, including the values specific to the IIS=TRUE option. The MILP, NLP, and QP solvers provide status information only when the IIS=TRUE option is specified. The NLP and QP solvers use the same status values as the LP solver for items that are in the irreducible infeasible set (IIS); the .status value for items not in an IIS is a single blank character. For more information that applies to the LP, NLP, and QP solvers, see the section Variable and Constraint Status and the section Irreducible Infeasible Set, both in Chapter 13, The Linear Programming Solver. For more information that applies to the MILP solver, see the section Variable and Constraint Status and the section Irreducible Infeasible Set, both in Chapter 14, The Mixed Integer Linear Programming Solver.
If you choose to modify the .status suffix for a variable or constraint, the assigned suffix value can be a single character or an empty string. The LP solver rejects invalid status characters. Blank or empty strings are treated as new row or column entries for the purpose of "warm starting" the solver.
The .active suffix reports the current activity status for names in the problem. The value is 1 if the element is active or 0 otherwise. A PROBLEM name is considered active if it is the current problem (that is, it was selected by the most recent USE PROBLEM statement). A constraint is considered active if it is included in the current problem and not dropped. An objective is considered active if it is the last objective that is added to the current problem. A variable is considered active if it is included in the current problem, independent of the fixed status.
The .fixed suffix reports the fixed status of a variable. The value is 1 if the variable is fixed using the FIX statement for the current problem or 0 otherwise. Variables that are not included in the current problem are treated as unfixed.
The .msinit suffix reports the numeric value of a variable at the best starting point, as reported by the NLP solver when the MULTISTART option is specified. If the solver does not report a best starting point, then the value is missing. The value is tracked independently for each problem to support multiple subproblems. See the section Multistart in Chapter 16, The Nonlinear Programming Solver, for more information.
The .block suffix for constraints identifies the subproblem for constraints when used with the METHOD=USER option of the Dantzig-Wolfe decomposition algorithm. The value must be numeric and is initially assigned a missing value. A constraint that has a missing value for the .block suffix is part of the master problem. Otherwise constraints belong to the same subproblem if and only if they have the same .block suffix values. See Chapter 18, The Dantzig-Wolfe Decomposition Algorithm, for more information.
The .block suffix for variables identifies the subproblem for variables when the Benders decomposition algorithm is used. The value must be numeric and is initially assigned a missing value. A variable that has a missing value for the .block suffix is part of the master problem. Otherwise, variables belong to the same subproblem if and only if they have the same .block suffix values. See Chapter 19, The Benders Decomposition Algorithm, for more information.
The .label suffix represents the text passed to the solver to identify a variable, constraint, or objective. Some solvers can display this label in their output. The maximum text length passed to the solver is controlled by the MAXLABLEN= option. The default text is based on the name in the model, abbreviated to fit within MAXLABLEN. For example, a model variable x[1] would be labeled "x[1]". This label text can be reassigned. The .label suffix value is also used to create MPS labels stored in the output data set for the SAVE MPS and SAVE QPS statements.
The .name suffix represents the name of a symbol as a text string. The .name suffix can be used with any declared name except for local dummy parameters. This suffix is primarily useful when applied to problem symbols (see the section Problem Symbols), since the .name suffix returns the name of the referenced symbol, not the problem symbol name. The name text is based on the name in the model, abbreviated to fit in 256 characters.
Suffixed names can be used wherever a parameter name is accepted, provided only the value is required. However, you are not allowed to change the value of certain suffixes. Table 15 marks these suffixes as not modifiable. Suffixed names that are used as a target in an assignment or READ DATA statement must be modifiable.
The following statements formulate a trivial linear programming problem. The objective value is unbounded, which is reported after the execution of the SOLVE statement. The PRINT statements illustrate the corresponding default auxiliary values. This is shown in Figure 60.
proc optmodel;
var x, y;
min z = x + y;
con c: x + 2*y <= 3;
solve;
print x.lb x.ub x.status x.sol;
print y.lb y.ub y.status y.sol;
print c.lb c.ub c.body c.dual;
Figure 60: Using a Suffix: Retrieving Auxiliary Values
| x.LB | x.UB | x.STATUS | x.SOL |
|---|---|---|---|
| -1.7977E+308 | 1.7977E+308 | I | 0 |
| y.LB | y.UB | y.STATUS | y.SOL |
|---|---|---|---|
| -1.7977E+308 | 1.7977E+308 | I | 0 |
| c.LB | c.UB | c.BODY | c.DUAL |
|---|---|---|---|
| -1.7977E+308 | 3 | 0 | . |
Next, continue to submit the following statements to change the default bounds and solve again. The output is shown in Figure 61.
x.lb=0;
y.lb=0;
c.lb=1;
solve;
print x.lb x.ub x.status x.sol;
print y.lb y.ub y.status y.sol;
print c.lb c.ub c.body c.dual;
Figure 61: Using a Suffix: Modifying Auxiliary Values
| x.LB | x.UB | x.STATUS | x.SOL |
|---|---|---|---|
| 0 | 1.7977E+308 | L | 0 |
| y.LB | y.UB | y.STATUS | y.SOL |
|---|---|---|---|
| 0 | 1.7977E+308 | B | 0.5 |
| c.LB | c.UB | c.BODY | c.DUAL |
|---|---|---|---|
| 1 | 3 | 1 | 0.5 |
Note: Spaces are significant. The form NAME. TAG is treated as a SAS format name followed by the tag name, not as a suffixed identifier. The forms NAME.TAG, NAME . TAG, and NAME .TAG (note the location of spaces) are interpreted as suffixed references.