User guide · 2.0 development
Configuring Solver Settings¶
SHOT provides extensive configuration options through its settings system.
Accessing and Modifying Settings¶
# Create the solver first
solver = SHOTpy.Solver()
# Create a simple problem
problem = SHOTpy.Problem(solver)
x = problem.addVariable("x", SHOTpy.VariableType.Real, 0.0, 10.0)
problem.setObjective(x)
problem.finalize()
solver.setProblem(problem)
# Get current values
print("Current Settings:")
time_limit = solver.getDoubleSetting("Termination.TimeLimit")
print(f" Time limit: {time_limit} seconds")
abs_gap = solver.getDoubleSetting("Termination.ObjectiveGap.Absolute")
print(f" Absolute gap tolerance: {abs_gap}")
# Modify settings
print("\nModifying settings...")
solver.updateSetting("Termination.TimeLimit", 300.0) # 5 minutes
solver.updateSetting("Termination.ObjectiveGap.Absolute", 1e-6)
# Verify changes
new_time = solver.getDoubleSetting("Termination.TimeLimit")
new_gap = solver.getDoubleSetting("Termination.ObjectiveGap.Absolute")
print(f" New time limit: {new_time} seconds")
print(f" New absolute gap: {new_gap}")
Common Settings¶
Change the settings before calling solver.setProblem(). That call reformulates the problem, chooses the solution
strategy, and creates the MIP and NLP solvers with their parameters, so most settings are fixed from then on: e.g.,
the MIP and NLP solvers, the tree strategy, the reformulation and bound tightening settings, and all subsolver
settings (Subsolver.*). A setting changed afterwards is accepted without a message, but may have no effect, or only
a partial one: e.g., a new Termination.ObjectiveGap.Relative is used by SHOT’s own termination check but not by the
MIP solver. Settings that SHOT only reads while solving, such as Termination.TimeLimit and the output settings, can
also be changed afterwards.
Here are some frequently used settings:
solver = SHOTpy.Solver()
# The settings are changed before setProblem(), which creates the solution strategy and the MIP and NLP solvers
# Termination criteria
solver.updateSetting("Termination.TimeLimit", 600.0) # Max time in seconds
solver.updateSetting("Termination.ObjectiveGap.Absolute", 1e-5) # Absolute gap
solver.updateSetting("Termination.ObjectiveGap.Relative", 1e-4) # Relative gap
# Output settings: 0 = Trace, 1 = Debug, 2 = Info, 3 = Warning, 4 = Error, 5 = Critical, 6 = Off
solver.updateSetting("Output.Console.LogLevel", 2)
# MIP solver selection, among those this build of SHOT has (convert enum to int)
for available, mipSolver in [(SHOTpy.HAS_GUROBI, SHOTpy.MIPSolver.Gurobi), (SHOTpy.HAS_CPLEX, SHOTpy.MIPSolver.Cplex),
(SHOTpy.HAS_HIGHS, SHOTpy.MIPSolver.Highs), (SHOTpy.HAS_CBC, SHOTpy.MIPSolver.Cbc)]:
if available:
solver.updateSetting("Dual.MIP.Solver", int(mipSolver))
break
# NLP solver selection
if SHOTpy.HAS_IPOPT:
solver.updateSetting("Primal.FixedInteger.Solver", int(SHOTpy.PrimalNLPSolver.Ipopt))
print("Settings configured successfully!")
# Verify some settings
print(f"Time limit: {solver.getDoubleSetting('Termination.TimeLimit')} seconds")
print(f"Log level: {solver.getIntSetting('Output.Console.LogLevel')}")
print(f"MIP solver: {SHOTpy.MIPSolver(solver.getIntSetting('Dual.MIP.Solver')).name}")
# The problem is then created, finalized and given to the solver
problem = SHOTpy.Problem(solver)
x = problem.addVariable("x", SHOTpy.VariableType.Real, 0.0, 10.0)
problem.setObjective(x)
problem.finalize()
assert solver.setProblem(problem)