Documentation

Get started

Install SHOT, solve a first problem from the interface you already use, and set its options.

Install

The SHOTpy wheels include SHOT with the open-source subsolvers Cbc, Ipopt and HiGHS, and need Python 3.11 or later. They are built for Linux (x86-64 and ARM64), macOS (Apple silicon, macOS 14 and later), and Windows x64. The package also installs the SHOT command. On platforms without a matching wheel, building from source needs the compiler and dependencies in the compilation instructions.

pip install SHOTpy

The public wheels do not include CPLEX, Gurobi, GAMS or CONOPT. If one of them is installed and licensed on your computer, build SHOTpy from source with it:

terminal
pip install SHOTpy --no-binary SHOTpy \
    --config-settings=cmake.define.HAS_GUROBI=on \
    --config-settings=cmake.define.GUROBI_DIR=/path/to/gurobi

Use the same pattern with HAS_CPLEX and CPLEX_DIR, or HAS_GAMS and GAMS_DIR.

Subsolvers

SHOT needs a MIP solver for its dual strategy (CPLEX, Gurobi, Cbc or HiGHS) and an NLP solver for its primal strategy (Ipopt, Uno, CONOPT, SHOT itself, or one in GAMS). A fully open-source setup works out of the box.

Solve a problem

example.py
import SHOTpy

solver = SHOTpy.Solver()
problem = SHOTpy.Problem(solver)

x = problem.addVariable("x", SHOTpy.VariableType.Real, 0.0, 10.0)
y = problem.addVariable("y", SHOTpy.VariableType.Integer, 0.0, 10.0)

problem.setObjective(SHOTpy.exp(x) + (y - 2.5)**2)
problem.addConstraint(x + y >= 3, "c")
problem.finalize()

solver.setProblem(problem)
solver.solveProblem()

print(solver.getModelReturnStatus())
if solver.hasPrimalSolution():
    print(solver.getPrimalSolution().point)

Build the problem with the API, or read it from a file with solver.setProblem("problem.nl"), which also accepts .gms and .osil files. The tutorial notebook covers nonlinear expressions, settings and callbacks.

SHOTpy tutorial

Set options

Any setting can be given on the command line as Name=value, without spaces around the =. Names are case sensitive. Unknown names are ignored, and SHOT lists them in a warning.

terminal
./SHOT problem.nl Termination.TimeLimit=100.0 Termination.ObjectiveGap.Relative=0.001

In SHOTpy and C++, use updateSetting before setProblem. Settings can also be read from a file with --opt [file] (GAMS style) or --osol [file] (OSoL); without a file name, SHOT reads the default file if it exists, otherwise it writes a template. Common settings have shorthand flags:

FlagEffect
--convexAssume that the problem is convex
--mip=<cbc|highs|cplex|gurobi>Select the MIP solver of the dual strategy
--nlp=<ipopt|gams|shot|uno|conopt>Select the NLP solver of the primal strategy
--tree=<single|multi>Single-tree (branch and cut, CPLEX and Gurobi) or multi-tree strategy
--threads=<n>Maximum number of threads
--absgap=<value>Absolute objective gap tolerance
--relgap=<value>Relative objective gap tolerance
--timelimit=<value>Time limit in seconds
--debug[=<directory>]Write intermediate problems and solutions

All settings

./SHOT --docs writes options.md with every setting, its type, default value and description, generated from the build you run. It is the authoritative reference for your version. See the configuration guide for settings precedence, tolerances and logging recipes.

Read the results

Console

Preparation statistics, selected progress rows, and a final solution report. Set Output.Console.Iteration.Detail=0 for all progress rows. Output.Console.LogLevel independently controls message severity, from 0 (trace) to 6 (off).

Log

SHOT.log in the current directory, or --log file.

Solution

Always in OSrL format, problem.osrl or --osrl file. Add --trc for a GAMS trace file and --sol for an AMPL solution file.

Exit code

0 when the run succeeded, whatever the model status; the status is in the result files.

For minimization, the dual bound is a lower bound and the best feasible objective is an upper bound; for maximization the directions reverse. A relative gap of 0.001 means 0.1%. An iteration label such as MILP-O describes a subproblem. Read the final model status to see whether the original problem was solved to global optimality.

selected rows · spacing and values simplified
#: type        time     cuts + / total     dual / primal     abs. / rel. gap     current obj. / error
6: MILP-SL1    0.17       2 / 12        0.716245 / 14.9066     14.2 / 0.95         7.92975 / 0.592
1: NLPSOLPT-R  0.19       2 / 12        0.716245 / 10           9.3 / 0.93         10 / 9.61e-9

Here the MIP solve reaches a solution limit, then a fixed-integer NLP call improves the feasible objective to 10. The NLP counter starts at one. Its final R means the reformulated model. A * beside a dual bound means it is a working bound without a global guarantee; use the final report's global bound when reporting results. Check that a primal solution exists before reading its values.

Understand solver output Results and status Command-line reference Debugging SHOT