Obtaining information

In addition to the Knitro log that is printed on screen, information about the computation performed by Knitro is available in the form of various function calls. This section explains how this information can be retrieved and interpreted.

Knitro output for continuous problems

This section describes Knitro outputs at various levels for continuous problems. We examine the output that results from running examples/C/exampleNLP1.c with full output.

Note

If outlev=0 then all printing of output is suppressed. If outlev is positive, then Knitro prints information about the solution of your optimization problem either to standard output (outmode = screen), to a file named knitro.log (outmode = file), or to both (outmode = both). The option outdir controls the directory where output files are created (if any are) and the option outappend controls whether output is appended to existing files.

Display of Nondefault Options

Knitro first prints the banner displaying the Artelys license type and version of Knitro that is installed. It then lists all user options which are different from their default values If nothing is listed in this section then it must be that all user options are set to their default values. Lastly, Knitro prints messages that describe how it resolved user options that were set to automatic values. For example, if option algorithm = auto, then Knitro prints the algorithm that it chooses.

=======================================
          Commercial License
         Artelys Knitro 11.0.0
=======================================

Knitro presolve eliminated 0 variables and 0 constraints.

outlev:               6
Knitro changing algorithm from AUTO to 1.
Knitro changing bar_initpt from AUTO to 3.
Knitro changing bar_murule from AUTO to 4.
Knitro changing bar_penaltycons from AUTO to 1.
Knitro changing bar_penaltyrule from AUTO to 2.
Knitro changing bar_switchrule from AUTO to 2.
Knitro changing linesearch from AUTO to 1.
Knitro changing linsolver from AUTO to 2.

In the example above, it is indicated that we are using a more verbose output level (outlev = 6) instead of the default value (outlev = 2). Knitro chose algorithm 1 (Interior/Direct), and then automatically determined some other options related to the algorithm.

Display of problem characteristics

Knitro next prints a summary description of the problem characteristics including the number and type of variables and constraints and the number of nonzero elements in the Jacobian matrix and Hessian matrix. If the Knitro presolver is enabled, then information about the presolved form of the problem is printed as well.

Problem Characteristics                                 (   Presolved)
-----------------------
Objective goal:  Minimize
Objective type:  general
Number of variables:                                  2 (           2)
    bounded below only:                               0 (           0)
    bounded above only:                               1 (           1)
    bounded below and above:                          0 (           0)
    fixed:                                            0 (           0)
    free:                                             1 (           1)
Number of constraints:                                2 (           2)
    linear equalities:                                0 (           0)
    quadratic equalities:                             0 (           0)
    gen. nonlinear equalities:                        0 (           0)
    linear one-sided inequalities:                    0 (           0)
    quadratic one-sided inequalities:                 2 (           2)
    gen. nonlinear one-sided inequalities:            0 (           0)
    linear two-sided inequalities:                    0 (           0)
    quadratic two-sided inequalities:                 0 (           0)
    gen. nonlinear two-sided inequalities:            0 (           0)
Number of nonzeros in Jacobian:                       4 (           4)
Number of nonzeros in Hessian:                        3 (           3)

Display of Iteration Information

Next, if outlev is greater than 2, Knitro prints columns of data reflecting detailed information about individual iterations during the solution process. An iteration is defined as a step which generates a new solution estimate (i.e., a successful step).

If outlev = 2, summary data is printed every 10 iterations, and on the final iteration. If outlev = 3, summary data is printed every iteration. If outlev = 4, the most verbose iteration information is printed every iteration.

  Iter     fCount     Objective      FeasError   OptError    ||Step||    CGits
--------  --------  --------------  ----------  ----------  ----------  -------
       0         7    9.090000e+02   3.000e+00
       1         8    7.996681e+02   2.859e+00   2.186e+01   7.226e-02        0
       2         9    1.859212e+01   9.066e-01   3.943e+01   2.199e+00        0
       3        17    3.280079e+02   8.816e-01   6.903e+00   1.356e+00        8
       4        18    1.445972e+01   4.912e-01   6.736e-01   1.173e+00        2
       5        19    3.562070e+01   3.874e-01   3.874e-01   1.929e-01        0
       6        20    1.153310e+02   2.196e-01   5.652e-01   4.098e-01        0
       7        21    2.363651e+02   7.226e-02   7.226e-02   4.156e-01        0
       8        22    3.018949e+02   5.268e-03   1.827e-02   1.861e-01        0
       9        23    3.064952e+02   6.791e-06   1.513e-04   1.267e-02        0
      10        24    3.065000e+02   9.480e-11   9.480e-11   1.358e-05        0

The meaning of each column is described below.

  • Iter: iteration number.
  • fCount: the cumulative number of (nonlinear) function evalutions. (This information is only printed if outlev is greater than 3).
  • Objective: the value of the objective function at the current iterate.
  • FeasError: a measure of the feasibility violation at the current iterate
  • OptError: a measure of the violation of the Karush-Kuhn-Tucker (KKT) (first-order) optimality conditions (not including feasibility) at the current iterate.
  • Step: the 2-norm length of the step (i.e., the distance between the new iterate and the previous iterate).
  • CGits: the number of Projected Conjugate Gradient (CG) iterations required to compute the step.

Display of termination status

At the end of the run a termination message is printed indicating whether or not the optimal solution was found and if not, why Knitro stopped. The termination message typically starts with the word “EXIT”. If Knitro was successful in satisfying the termination test, the message will look as follows:

EXIT: Locally optimal solution found.

Display of Final Statistics

Following the termination message, a summary of some final statistics on the run are printed. Both relative and absolute error values are printed.

Final Statistics
----------------
Final objective value               =   3.06499999937285e+02
Final feasibility error (abs / rel) =   9.48e-11 / 3.16e-11
Final optimality error  (abs / rel) =   9.48e-11 / 6.50e-12
# of iterations                     =         10
# of CG iterations                  =         10
# of function evaluations           =         24
# of gradient evaluations           =         15
# of Hessian evaluations            =         10
Total program time (secs)           =       0.00258 (     0.002 CPU time)
Time spent in evaluations (secs)    =       0.00002

Display of solution vector and constraints

If outlev equals 5 or 6, the values of the solution vector are printed after the final statistics. If outlev equals 6, the final constraint values are also printed, and the values of the Lagrange multipliers (or dual variables) are printed next to their corresponding constraint or bound.

Constraint Vector                Lagrange Multipliers
-----------------                ---------------------
c[       0] =   9.99999999905e-01,   lambda[       0] =  -6.99999999925e+02
c[       1] =   4.49999999927e+00,   lambda[       1] =  -8.09211653221e-10

Solution Vector
---------------
x[       0] =   4.99999999998e-01,   lambda[       2] =   1.75099999969e+03
x[       1] =   1.99999999982e+00,   lambda[       3] =   0.00000000000e+00

Debugging / profiling information

Knitro can produce additional information which may be useful in debugging or analyzing performance. If outlev is positive and debug = 1, then multiple files named kdbg_*.log are created which contain detailed information on performance. If outlev is positive and debug = 2, then Knitro prints information useful for debugging program execution. The information produced by debug is primarily intended for developers, and should not be used in a production setting.

Intermediate iterates

Users can generate a file containing iterates and/or solution points with option newpoint. The output file is called knitro_newpoint.log.

Knitro output for discrete problems

This section describes Knitro outputs at various levels for discrete or mixed integer problems. We examine the output that results from running examples/C/callbackMINLP1.c.

Note

When outlev is positive, the options mip_outlevel, mip_debug, mip_outinterval and mip_outsub control the amount and type of MIP output generated as described below.

Knitro first prints the banner displaying the license type and version of Knitro that is installed. It then lists all user options which are different from their default values. If nothing is listed in this section then it must be that all user options are set to their default values. Lastly, Knitro prints messages that describe how it resolved user options that were set to automatic values. For example, if option mip_branchrule = auto, then Knitro prints the branching rule that it chooses.

=======================================
          Commercial License
         Artelys Knitro 11.0.0
=======================================

mip_method: 1
mip_outinterval: 1
Knitro changing mip_rootalg from AUTO to 1.
Knitro changing mip_lpalg from AUTO to 3.
Knitro changing mip_branchrule from AUTO to 2.
Knitro changing mip_selectrule from AUTO to 2.
Knitro changing mip_rounding from AUTO to 3.
Knitro changing mip_heuristic from AUTO to 2.
Knitro changing mip_pseudoinit from AUTO to 1.

In the example above, it is indicated that we are using mip_method = 1 which is the standard branch and bound method, and that we are printing output information at every node since mip_outinterval = 1. It then determined seven other options related to the MIP method.

Display of Problem Characteristics

Knitro next prints a summary description of the problem characteristics including the number and type of variables and constraints and the number of nonzero elements in the Jacobian matrix and Hessian matrix (if providing the exact Hessian).

If no initial point is provided by the user, Knitro indicates that it is computing one. Knitro also prints the results of any MIP preprocessing to detect special structure and indicates which MIP method it is using.

Problem Characteristics
-----------------------
Objective goal:  Minimize
Objective type:  general
Number of variables:                                  6
    bounded below only:                               0
    bounded above only:                               0
    bounded below and above:                          6
    fixed:                                            0
    free:                                             0
Number of binary variables:                           3
Number of integer variables:                          0
Number of constraints:                                6
    linear equalities:                                0
    quadratic equalities:                             0
    gen. nonlinear equalities:                        0
    linear one-sided inequalities:                    4
    quadratic one-sided inequalities:                 0
    gen. nonlinear one-sided inequalities:            2
    linear two-sided inequalities:                    0
    quadratic two-sided inequalities:                 0
    gen. nonlinear two-sided inequalities:            0
Number of nonzeros in Jacobian:                      16
Number of nonzeros in Hessian:                        3

No start point provided -- Knitro computing one.

Knitro detected 1 GUB constraints
Knitro derived 0 knapsack covers after examining 3 constraints
Knitro solving root node relaxation
Knitro searching for integer feasible point using heuristic
*  iter =      1: Iinf =      0, FeasError =   2.068e-26, Obj =   1.000e+01
Knitro found integer feasible point in 1 heuristic iteration
Knitro MIP using Branch and Bound method

Display of Node Information

Next, if mip_outlevel = 1, Knitro prints columns of data reflecting detailed information about individual nodes during the solution process. If mip_outlevel = 2, the accumulated time is printed at each node also. The frequency of this node information is controlled by the mip_outinterval parameter. For example, if mip_outinterval = 100, this node information is printed only for every 100th node (printing output less frequently may save significant CPU time in some cases). In the example below, mip_outinterval = 1, so information about every node is printed (without the accumulated time).

   Node    Left    Iinf     Objective         Best Relaxatn  Best Incumbent
  ------  ------  ------  --------------     --------------  --------------
       1       0       2    7.592844e-01       7.592844e-01    1.000000e+01
       2       1       1    5.171320e+00       7.592844e-01    1.000000e+01
*      2       1                          r                    7.671320e+00
*      3       2       0    6.009759e+00  f    5.171320e+00    6.009759e+00
       4       1            1.000000e+01 pr    5.171320e+00    6.009759e+00
       5       0            7.092732e+00 pr    6.009759e+00    6.009759e+00

The meaning of each column is described below.

  • Node: the node number. If an integer feasible point was found at a given node, then it is marked with a star (*).
  • Left: the current number of active nodes left in the branch and bound tree.
  • Iinf: the number of integer infeasible variables at the current node solution.
  • Objective: the value of the objective function at the solution of the relaxed subproblem solved at the current node. If the subproblem was infeasible or failed, this is indicated. Additional symbols may be printed at some nodes if the node was pruned (pr), integer feasible (f), or an integer feasible point was found through rounding (r).
  • Best relaxatn: the value of the current best relaxation (lower bound on the solution if minimizing).
  • Best incumbent: the value of the current best integer feasible point (upper bound on the solution if minimizing).

Display of Termination Status

At the end of the run a termination message is printed indicating whether or not the optimal solution was found and if not, why Knitro stopped. The termination message typically starts with the word “EXIT”. If Knitro was successful in satisfying the termination test, the message will look as follows:

EXIT: Optimal solution found.

See the reference manual (Return codes) for a list of possible termination messages and a description of their meaning and the corresponding value returned by KN_solve().

Display of Final Statistics

Following the termination message, a summary of some final statistics on the run are printed.

Final Statistics for MIP
------------------------
Final objective value                =    6.00975890892825e+00
Final integrality gap (abs / rel)    =    0.00e+00 /     0.00e+00 (0.00%)
# of nodes processed                 =    5
# of subproblems solved              =    8
Total program time (secs)            =    0.09930 (0.099 CPU time)
Time spent in evaluations (secs)     =    0.00117

Display of Solution Vector and Constraints

If outlev equals 5 or 6, the values of the solution vector are printed after the final statistics. If outlev equals 6, the constraint values at the solution are also printed.

Solution Vector
---------------
x[0] =   1.30097589089e+00
x[1] =   0.00000000000e+00
x[2] =   1.00000000000e+00
x[3] =   0.00000000000e+00      (binary variable)
x[4] =   1.00000000000e+00      (binary variable)
x[5] =   0.00000000000e+00      (binary variable)

Knitro can produce additional information which may be useful in debugging or analyzing MIP performance. If outlev is positive and mip_debug = 1, then the file named kdbg_mip.log is created which contains detailed information on the MIP performance. In addition, if mip_outsub = 1, this file will contain extensive output for each subproblem solve in the MIP solution process. The information produced by mip_debug is primarily intended for developers, and should not be used in a production setting.

Getting information programmatically in callable library

Important solution information from Knitro can be retrieved through special API function calls.

Information related to the final statistics can be retrieved through the following function calls. The precise meaning of each function is described in the reference manual (Callable library API reference).

int  KNITRO_API KN_get_number_FC_evals (const KN_context_ptr  kc,
                                              int * const     numFCevals);
int  KNITRO_API KN_get_number_GA_evals (const KN_context_ptr  kc,
                                              int * const     numGAevals);
int  KNITRO_API KN_get_number_H_evals (const KN_context_ptr  kc,
                                             int * const     numHevals);
int  KNITRO_API KN_get_number_HV_evals (const KN_context_ptr  kc,
                                              int * const     numHVevals);
int  KNITRO_API KN_get_solution (const KN_context_ptr  kc,
                                       int    * const  status,
                                       double * const  obj,
                                       double * const  x,
                                       double * const  lambda);
int  KNITRO_API KN_get_obj_value (const KN_context_ptr  kc,
                                        double * const  obj);
int  KNITRO_API KN_get_con_values (const KN_context_ptr  kc,
                                   const KNINT           nC,
                                   const KNINT  * const  indexCons,
                                         double * const  c);
int  KNITRO_API KN_get_rsd_values (const KN_context_ptr  kc,
                                   const KNINT           nR,
                                   const KNINT  * const  indexRsds,
                                         double * const  r);

Continuous problems

int  KNITRO_API KN_get_number_iters (const KN_context_ptr  kc,
                                           int * const     numIters);
int  KNITRO_API KN_get_number_cg_iters (const KN_context_ptr  kc,
                                              int * const     numCGiters);
int  KNITRO_API KN_get_abs_feas_error (const KN_context_ptr  kc,
                                             double * const  absFeasError);
int  KNITRO_API KN_get_rel_feas_error (const KN_context_ptr  kc,
                                             double * const  relFeasError);
int  KNITRO_API KN_get_abs_opt_error (const KN_context_ptr  kc,
                                            double * const  absOptError);
int  KNITRO_API KN_get_rel_opt_error (const KN_context_ptr  kc,
                                            double * const  relOptError);
int  KNITRO_API KN_get_objgrad_nnz  (const KN_context_ptr  kc,
                                           KNINT  * const  nnz);
int  KNITRO_API KN_get_objgrad_values (const KN_context_ptr  kc,
                                             KNINT  * const  indexVars,
                                             double * const  objGrad);
int  KNITRO_API KN_get_objgrad_values_all (const KN_context_ptr  kc,
                                                 double * const  objGrad);
int  KNITRO_API KN_get_jacobian_nnz    (const KN_context_ptr  kc,
                                              KNLONG * const  nnz);
int  KNITRO_API KN_get_jacobian_values (const KN_context_ptr  kc,
                                              KNINT  * const  indexCons,
                                              KNINT  * const  indexVars,
                                              double * const  jac);
int  KNITRO_API KN_get_rsd_jacobian_nnz    (const KN_context_ptr  kc,
                                                  KNLONG * const  nnz);
int  KNITRO_API KN_get_rsd_jacobian_values (const KN_context_ptr  kc,
                                                  KNINT  * const  indexRsds,
                                                  KNINT  * const  indexVars,
                                                  double * const  rsdJac);
int  KNITRO_API KN_get_hessian_nnz    (const KN_context_ptr  kc,
                                             KNLONG * const  nnz);
int  KNITRO_API KN_get_hessian_values (const KN_context_ptr  kc,
                                             KNINT  * const  indexVars1,
                                             KNINT  * const  indexVars2,
                                             double * const  hess);

Discrete or mixed integer problems

int  KNITRO_API KN_get_mip_number_nodes (const KN_context_ptr  kc,
                                               int * const     numNodes);
int  KNITRO_API KN_get_mip_number_solves (const KN_context_ptr  kc,
                                                int * const     numSolves);
int  KNITRO_API KN_get_mip_abs_gap (const KN_context_ptr  kc,
                                          double * const  absGap);
int  KNITRO_API KN_get_mip_rel_gap (const KN_context_ptr  kc,
                                          double * const  relGap);
int  KNITRO_API KN_get_mip_incumbent_obj (const KN_context_ptr  kc,
                                                double * const  incumbentObj);
int  KNITRO_API KN_get_mip_relaxation_bnd (const KN_context_ptr  kc,
                                                 double * const relaxBound);
int  KNITRO_API KN_get_mip_lastnode_obj (const KN_context_ptr  kc,
                                               double * const lastNodeObj);
int  KNITRO_API KN_get_mip_incumbent_x (const KN_context_ptr  kc,
                                              double * const  x);

Getting information programmatically in the object-oriented interface

Solution information can be retrieved after a call to KTRSolver::solve(). After solve() is called, KTRSolver::getObj() returns the objective function value, and KTRSolver::getXValues() and KTRSolver::getLambdaValues() return the final primal and and dual variable values, respectively. The solution status code is returned by KTRSolver::solve() method.

In addition, information related to the final statistics can be retrieved through the following KTRSolver methods. The precise meaning of each function is described in the reference manual (Callable library API reference).

int KTRSolver::getNumberFCEvals();
int KTRSolver::getNumberGAEvals();
int KTRSolver::getNumberHEvals();
int KTRSolver::getNumberHVEvals();
std::vector<double> KTRSolver::getConstraintValues();

Continuous problems

int KTRSolver::getNumberIters();
int KTRSolver::getNumberCGIters();
double KTRSolver::getAbsFeasError();
double KTRSolver::getRelFeasError();
double KTRSolver::getAbsOptError();
double KTRSolver::getRelOptError();
std::vector<double> KTRSolver::getObjgradValues();
std::vector<double> KTRSolver::getJacobianValues();
std::vector<double> KTRSolver::getHessianValues();

Discrete or mixed integer problems

int KTRSolver::getMipNumNodes();
int KTRSolver::getMipNumSolves();
double KTRSolver::getMipAbsGap();
double KTRSolver::getMipRelGap();
double KTRSolver::getMipIncumbentObj();
std::vector<double> KTRSolver::getMipIncumbentX );
double KTRSolver::getMipRelaxationBnd();
double KTRSolver::getMipLastnodeObj();

User-defined names in Knitro output

By default Knitro uses x for variable names and c for constraint names in the output. However, the user can define more meaningful and customized names for the objective function, the variables and the constraint functions through the the API functions KN_set_obj_name(), KN_set_var_names(), KN_set_con_names(), and KN_set_compcon_names() when using the callable library API.

When using the AMPL modeling language, you can have Knitro output objective function, variable and constraint names specified in the AMPL model by issuing the following command in the AMPL session:

option knitroampl_auxfiles rc;

Suppressing all output in AMPL

Even when setting the options:

ampl: option solver_msg 0;
ampl: option knitro_options "outlev=0";

in an AMPL session, AMPL will still print some basic information like the solver name and non-default user option settings to the screen. In order to suppress all AMPL and Knitro output you must change your AMPL solve commands to something like:

ampl: solve >scratch-file;

where scratch-file is the name of some temporary file where the unwanted output can be sent. Under Unix, “solve >/dev/null” automatically throws away the unwanted output and under Windows, “solve > NUL” does the same.

AMPL solution information through suffixes

Some Knitro solution information can be retrieved and displayed through AMPL using AMPL suffixes defined for Knitro (see AMPL suffixes defined for Knitro). In particular, when solving a MIP using Knitro/AMPL, the best relaxation bound and the incumbent solution can be displayed using the relaxbnd and incumbent suffixes. For example, if the objective function is named obj, then:

ampl: display obj.relaxbnd;

give the current relaxation bound and:

ampl: display obj.incumbent;

will give the current incumbent solution (if one exists).

AMPL presolve

AMPL will often perform a reordering of the variables and constraints defined in the AMPL model. The AMPL presolver may also simplify the form of the problem by eliminating certain variables or constraints. The output printed by Knitro corresponds to the reordered, reformulated problem. To view final variable and constraint values in the original AMPL model, use the AMPL display command after Knitro has completed solving the problem.

It is possible to correlate Knitro variables and constraints with the original AMPL model. You must type an extra command in the AMPL session:

option knitroampl_auxfiles rc;

and set Knitro option presolve_dbg = 2. Then the solver will print the variables and constraints that Knitro receives, with their upper and lower bounds, and their AMPL model names. The extra AMPL command causes the model names to be passed to the Knitro/AMPL solver.

The output below is obtained with the example file testproblem.mod supplied with the distribution. The center column of variable and constraint names are those used by Knitro, while the names in the right-hand column are from the AMPL model:

ampl: model testproblem.mod;
ampl: option solver knitroampl;
ampl: option knitroampl_auxfiles rc;
ampl: option knitro_options "presolve_dbg=2 outlev=0";

Knitro 11.0.0: presolve_dbg=2
outlev=0
----- AMPL problem for Knitro -----
Objective name:  obj
   0.000000e+00  <=  x[   0]  <=     1.000000e+20  x[1]
   0.000000e+00  <=  x[   1]  <=     1.000000e+20  x[2]
   0.000000e+00  <=  x[   2]  <=     1.000000e+20  x[3]

   2.500000e+01  <=  c[   0]  <=     1.000000e+20  c2  (general)
   5.600000e+01  <=  c[   1]  <=     5.600000e+01  c1  (linear)
-----------------------------------
Knitro 11.0.0: Locally optimal or satisfactory solution.
objective 935.9999978; feasibility error 6.74e-08
5 iterations; 7 function evaluations