User guide · 2.0 development
Understanding SHOT output¶
SHOT reports how it prepares the model, improves objective bounds, searches for
feasible solutions, and finally terminates. This guide explains the normal
terminal output, also saved in SHOT.log by the command-line program. The same
reporting is used by SHOTpy and C++; modeling systems may surround it with their
own output.
For running the executable and choosing result files, see command-line usage. For the meaning of model statuses and safe result retrieval, see solver results. For intermediate models and diagnostic files, see debugging SHOT.
The parts of a solve¶
Sections can be absent when the selected solution strategy does not need them. Read the selected strategy in the Options section before comparing logs.
Section |
What it tells you |
|---|---|
Header |
SHOT version, Git revision, and build date. Record these when reporting a problem. |
Modeling system |
Input interface and, for file input, the problem filename. |
Bound tightening |
Variable bounds tightened on the original and reformulated problems, passes, elapsed time, and initial objective bounds. These objective bounds do not mean a feasible solution has been found. |
Problem instance |
Classification, objective direction and type, constraint and variable counts, and transformations. Compare Original and Reformulated to see the effect of auxiliary variables and rewritten expressions. |
Options |
Non-default settings and their sources, dual strategy, cut algorithm, MIP solver and threads, and primal NLP solver. The selected primal solver can still be reported as unused if no NLP call is needed. |
Interior point search |
An auxiliary search for a point strictly inside the nonlinear constraints, used to generate ESH hyperplanes. Its objective and iteration counter belong to that auxiliary problem. |
Main iteration step |
Progress of dual subproblems, primal NLP searches, and, where applicable, callbacks, repairs, and reduction cuts. |
Solution report |
Why SHOT stopped, what was established about the original model, globally valid bounds and gaps, criteria, counts, and timings. |
Result paths |
Where the executable wrote the solution and log. |
SHOT introduces auxiliary variables and linking constraints when partitioning nonlinear expressions and reformulating individual terms, in both the objective and constraints. These transformations explain increases in model size and can also make a nonlinear objective linear in the auxiliary variables. The transformation breakdown shows which reformulations were used. See modeling and reformulation for examples.
The source tags in Non-default options explain why an effective value differs
from its default. For example, [solver (compatibility)] beside
Dual.TreeStrategy = 0 means that backend capabilities required multi-tree.
See configuration and precedence.
Interior-point table¶
The cutting-plane minimax search can print a table like this:
Iteration │ Time │ Cuts │ Objective value │ Objective diff.
#: type │ tot. │ + | tot. │ problem | line srch │ abs. | rel.
1: LP 0.05 -1e+12 | -1e+12 inf. | inf.
2: LP 0.05 2 | 2 -5.49861 | 0.467842 6.0e+00 | 1.1e+00
3: LP 0.05 2 | 4 -1.36005 | -0.0102125 1.3e+00 | 9.9e-01
Valid interior point with constraint deviation -0.010 found.
The table has two header rows: the first names column groups and the second
names the columns within each group. Under Objective value, problem is
the LP approximation’s objective value and line srch is the auxiliary
objective value at the point obtained by a line search.
The auxiliary objective measures the maximum nonlinear constraint deviation. A negative deviation supplies an interior point for the nonlinear constraints. This point need not satisfy integrality and does not by itself establish a primal bound for the MINLP.
Under Objective diff., abs. is the absolute difference between the two
auxiliary objective values and rel. divides it by 1e-10 + abs(problem).
These differences are not the original model’s optimality gap. The first row
has no line search and no calculated objective difference.
Very loose early LP values, such as -1e+12, concern this auxiliary relaxation.
The main iteration counter starts separately afterwards.
Main iteration columns¶
For minimization, the main header is:
Iteration │ Time │ Dual cuts │ Objective value │ Objective gap │ Current solution
#: type │ tot. │ + | tot. │ dual | primal │ abs. | rel. │ obj.fn. | max.err.
Column |
Interpretation |
|---|---|
|
Counter for this operation and its row label. Dual solves, NLP calls, repairs, and reduction-cut updates have separate counters. |
|
Cumulative elapsed seconds, including preparation, rather than the duration of this row. |
|
Number of hyperplanes added and accumulated total for the associated dual iteration. Blank when the added count is zero. NLP rows can repeat the dual iteration’s counts; do not add the counts across printed rows. |
|
Bound from the current dual problem. It is distinct from the objective of that problem’s returned solution. See the global-bound caveat below. |
|
Best accepted feasible objective for the original model (the incumbent). For minimization it is an upper bound; for maximization it is a lower bound. |
|
Distance between the relevant dual bound and incumbent. |
|
Objective of the point associated with this row. A relaxation point can violate the original nonlinear model and need not improve the incumbent. |
|
Constraint index followed by its signed deviation at that point, for example |
For maximization, the bound columns are ordered primal | dual, so the lower bound remains on the left and the upper bound on the right.
Constraint indices are zero-based. Dual and callback rows refer to the
reformulated problem; NLP rows refer to the original or reformulated problem
identified by their O or R suffix. Compare with the matching problem dump
when using debug mode. For a constraint L <= f(x) <= U, the signed deviation
is max(L - f(x), f(x) - U); despite its internal name, it is not divided by
the constraint magnitude. If no nonlinear constraints remain in the reformulated
problem, the report prints 0 in the error column instead of an indexed value.
An infinite primal bound and gap normally mean no feasible solution has been
accepted yet. A blank current objective with inf. in the error column means
that the row has no reported objective/point, for example after an unsuccessful
NLP call. It does not prove that the original model is infeasible.
A worked main-iteration example¶
These selected rows come from test/data/synthes1.osil, run from the repository
with HiGHS and Ipopt:
./build/SHOT test/data/synthes1.osil --mip=highs --nlp=ipopt --threads=1 \
Output.Console.Iteration.Detail=0
Times, iteration paths, and last digits can change with the build and subsolvers.
1: LP-O 0.05 -37.8684 | inf. inf. | inf. -37.8684 | 11: 2.11e+01
6: MILP-SL1 0.17 2 | 12 0.716245 | 14.9066 1.4e+01 | 9.5e-01 7.92975 | 10: 5.92e-01
1: NLPSOLPT-R 0.19 2 | 12 0.716245 | 10 9.3e+00 | 9.3e-01 10 | 1: 9.61e-09
2: NLPFEASP-R 0.19 2 | 12 0.716245 | 6.00976 5.3e+00 | 8.8e-01 6.00976 | 1: 9.94e-09
10: MILP-O 0.47 6.00976 | 6.00976 0.0e+00 | 0.0e+00 6.00976 | 3: 9.87e-11
LP-Osolves a continuous relaxation optimally. Its nonlinear constraint deviation is large and no feasible MINLP solution has been accepted.MILP-SL1reaches the MIP solution limit of one. The dual bound is0.716245; the current MIP point has objective7.92975and violates a nonlinear constraint. A different, accepted point supplies the incumbent14.9066. A solution limit is an intentional way of limiting early MIP work.NLPSOLPT-Rfixes integers from the first MIP solution and solves an NLP on the reformulated model. It improves the incumbent to10. The row number restarts at one because it counts NLP solves.NLPFEASP-Ruses another solution-pool candidate and improves the incumbent again, to about6.00976.MILP-Ocloses the gap. The final solution report confirms global optimality within tolerances. Rounded iteration values are not a substitute for that report: here the final reported absolute gap was about2.68e-7.
Dual subproblem labels¶
The prefix describes the subproblem: LP, QP, QCQP, MILP, MIQP, or
MIQCQP (mixed-integer quadratically constrained quadratic programming).
Continuous relaxation rows can therefore appear during the solution of an
integer model.
Suffix |
Subproblem outcome |
|---|---|
|
Optimal solution of this subproblem. This does not alone prove optimality of the original MINLP. |
|
Feasible subproblem solution returned without an optimality proof. |
|
Solution limit reached; the number is the limit used. Limits above 100 are printed without the number. |
|
Time limit reached. |
|
Iteration limit reached. |
|
Node limit reached. |
|
Subproblem reported infeasible; interpret the final original-model status separately. |
|
Subproblem reported unbounded; an early relaxation can be unbounded even if the original model is bounded. |
|
Numerical issue. |
|
Solver error. |
|
Solve aborted. |
Fixed-integer NLP labels¶
These rows report primal searches with discrete variables fixed. Their labels
describe the source of the starting candidate, rather than the NLP termination
status. The final -O means original problem, and -R means reformulated
problem; the O here has a different meaning from a dual row’s optimal suffix.
Label before |
Candidate source |
|---|---|
|
First MIP solution point. |
|
Another MIP solution-pool point. |
|
An infeasible MIP solution candidate. |
|
MIP candidate with the smallest nonlinear constraint deviation. |
|
First MIP solution associated with a dual-bound update. |
|
Enumeration of discrete variable assignments. |
|
Given starting point. |
An NLP call need not find or improve a primal solution. Check whether the primal
bound changes, and enable Output.Console.PrimalSolver.Show=true or debug logging
when you need details of an NLP failure.
Single-tree callback rows¶
CB and CB (th: ...) report progress from MIP solver callbacks in the
single-tree strategy, supported by CPLEX and Gurobi. The optional th identifies
the callback thread. For example, a label 12: CB refers to a callback-related
iteration inside one branch-and-cut search, rather than the twelfth independent
MIP solve. Several events can share an iteration number. Cuts are added during
that tree and returned MIP points still need the nonlinear feasibility checks.
For example, a single-tree run of the same model produced these selected rows:
17: CB 0.04 3 | 48 5.84339 | 7.09273 1.2e+00 | 1.8e-01 5.86587 | 3: 7.54e-02
20: CB 0.04 3 | 54 5.84339 | 6.00974 1.7e-01 | 2.8e-02 6.00974 | 11: 1.39e-05
21: MILP-O 0.05 6.00974 | 6.00974 0.0e+00 | 0.0e+00 6.00974 | 0: 0.00e+00
The callback rows show progress inside the tree, including an improved
incumbent. The final MILP-O row reports the completed MIP solve. Default
filtering can omit callback rows between the ones shown.
Repair and reduction-cut rows¶
These rows replace the usual bound and gap fields with a description of the action. Their counters are separate from dual iterations.
Label |
Action |
|---|---|
|
Infeasibility repair succeeded in relaxing the dual problem. It does not mean a feasible original-model solution was found. |
|
Infeasibility repair failed; the suffix counts main repair attempts. |
|
Nonconvex cuts were removed to restart cut generation after repeated points. |
|
Repeated-point repair handling detected a loop. |
|
Objective cutoff was tightened in an attempt to find an improved primal solution. The suffix counts successive updates without improvement. |
Relaxed constraints is the repair count; Obj.cut is the objective cutoff.
The following Total primal improvements after repair / reduction cut line
counts improvements associated with those strategies.
Bounds, gaps, and the asterisk¶
With primal bound p and dual bound d, SHOT calculates:
absolute gap = abs(d - p)
relative gap = abs(d - p) / (1e-10 + abs(p))
If either bound is unavailable, the gap is infinite. A primal objective near zero makes the relative gap sensitive, so also consider the absolute tolerance. Meeting either objective-gap tolerance is sufficient for gap termination.
For nonconvex problems, cuts or repairs can make the current dual problem cease
to be a globally valid relaxation. SHOT marks the displayed current dual bound
with *. Its proximity to the incumbent then does not prove global optimality.
For example, a schematic display 5* | 10 can coexist with a final globally
valid interval [0, 10]: the working bound 5 is not the certificate.
Ordinary dual-solve rows use the current bound for their gaps. NLP and
callback rows use the global bound for their gaps, although their displayed
dual-value column still shows the current bound. The Solution report and
the public objective-gap getters use the global bound. Consequently, when *
is present, recalculating a row’s gap from its displayed bound columns may not
reproduce the printed gap. Use getGlobalDualBound() when reporting a valid
bound programmatically.
If convexity is asserted by the user, the report describes that assumption; any optimality guarantee depends on its correctness. See user-specified convexity.
Reading the solution report¶
Read both the termination reason and the model-status sentence. For example,
Terminated since absolute gap met requirements together with Globally optimal primal solution found is different from reaching a time limit with a feasible
solution. A limit can also be reached without finding any primal solution.
The objective interval is [dual, primal] for minimization and [primal, dual]
for maximization. The report uses the globally valid dual bound. The Fulfilled
and Unfulfilled termination criteria list shows the tested values and
tolerances; it is not a requirement that all criteria be fulfilled. In
particular, time and iteration limits are alternative stopping conditions.
Counts distinguish dual solves, interior-point LPs, fixed-integer NLPs, and accepted primal solutions. These need not equal the number of printed rows. Timing categories include subcategories and can overlap, so do not sum every printed timing to reconstruct the total.
The warning about a solution at maximum variable bounds means SHOT’s artificial bound limits may affect the answer. Check actual model bounds before treating that point as an optimum of the intended model.
A successful process exit (0) means the executable completed the run; inspect
the model status and solution availability before using variable values. See
results and termination.
Choosing output detail¶
Output.Console.Iteration.Detail controls which progress rows are generated:
Value |
Rows shown |
|---|---|
|
All progress rows. |
|
Bound updates, plus the first iteration, selected exceptional events, and periodic progress after more than 100 suppressed calls or more than two seconds. |
|
The default selection plus all primal NLP calls. |
Both console and file logging receive the rows that survive this selection.
Lowering the file log level cannot recover suppressed rows; use detail 0 for
a complete iteration history.
Logging severity is independent: Output.Console.LogLevel and
Output.File.LogLevel accept integers 0 (Trace), 1 (Debug), 2 (Info,
default), 3 (Warning), 4 (Error), 5 (Critical), and 6 (Off). Normal tables
are Info messages. Trace messages compiled out of Release builds cannot be
enabled by changing the setting.
Output.Console.DualSolver.Show=true enables MIP solver output and forces full
iteration detail. Output.Console.PrimalSolver.Show=true enables NLP solver
output. These backend logs have their own tables and status conventions; lines
routed through SHOT’s output stream are prefixed with |.
See configuration recipes for commands that combine these controls.