Performing sensitivity analysis
This application demonstrates sensitivity analysis in the C API.
In Performing sensitivity analysis, there
is a discussion of how to perform sensitivity analysis in the Interactive
Optimizer. As with most interactive features of CPLEX, there is a
direct approach to this task from the Callable Library. This section
modifies the example lpex1.c in Building and solving a small LP model in C to show how to perform sensitivity analysis
with routines from the Callable Library.
To begin, make a copy of lpex1.c , and edit this
new source file. Among the declarations (for example, immediately
after the declaration for dj ) insert these additional
declarations:
double *lowerc = NULL, *upperc = NULL;
double *lowerr = NULL, *upperr = NULL;
At some point after the call to CPXlpopt,
(for example, just before the call to CPXwriteprob),
perform sensitivity analysis on the objective function and on the
righthand side coefficients by inserting this fragment of code:
upperc = (double *) malloc (cur_numcols * sizeof(double));
lowerc = (double *) malloc (cur_numcols * sizeof(double));
status = CPXobjsa (env, lp, 0, cur_numcols-1, lowerc, upperc);
if ( status ) {
fprintf (stderr, "Failed to obtain objective sensitivity.\n");
goto TERMINATE;
}
printf ("\nObjective coefficient sensitivity:\n");
for (j = 0; j < cur_numcols; j++) {
printf ("Column %d: Lower = %10g Upper = %10g\n",
j, lowerc[j], upperc[j]);
}
upperr = (double *) malloc (cur_numrows * sizeof(double));
lowerr = (double *) malloc (cur_numrows * sizeof(double));
status = CPXrhssa (env, lp, 0, cur_numrows-1, lowerr, upperr);
if ( status ) {
fprintf (stderr, "Failed to obtain RHS sensitivity.\n");
goto TERMINATE;
}
printf ("\nRight-hand side coefficient sensitivity:\n");
for (i = 0; i < cur_numrows; i++) {
printf ("Row %d: Lower = %10g Upper = %10g\n",
i, lowerr[i], upperr[i]);
}
This sample is familiarly known as “throw away” code. For production
purposes, you probably want to observe good programming practices
such as freeing these allocated arrays at the TERMINATE label
in the application.
A bound value of 1e+20 (CPX_INFBOUND) is treated
as infinity within CPLEX, so this is the value printed by our sample
code in cases where the upper or lower sensitivity range on a row
or column is infinite; a more sophisticated program might print a
string, such as -inf or +inf, when
negative or positive CPX_INFBOUND is encountered
as a value.
Similar code could be added to perform sensitivity analysis with
respect to bounds via CPXboundsa.