User guide · 2.0 development
Quadratic Problems¶
SHOT can handle quadratic objectives and constraints (QCQP):
\[\begin{split}
\begin{aligned}
\text{minimize} \quad & x^2 + y^2 \\
\text{subject to} \quad & x + y \geq 2 \\
& x, y \geq 0
\end{aligned}
\end{split}\]
# Create problem
solver = SHOTpy.Solver()
problem = SHOTpy.Problem(solver)
# Variables
x = problem.addVariable("x", SHOTpy.VariableType.Real, 0.0, 10.0)
y = problem.addVariable("y", SHOTpy.VariableType.Real, 0.0, 10.0)
# Quadratic objective: x^2 + y^2
problem.setObjective(x**2 + y**2, SHOTpy.ObjectiveDirection.Minimize)
# Linear constraint: x + y >= 2
problem.addConstraint(x + y >= 2, "sum_constraint")
# Solve
problem.finalize()
assert solver.setProblem(problem)
assert solver.solveProblem()
assert solver.getModelReturnStatus() == SHOTpy.ModelReturnStatus.OptimalGlobal
sol = solver.getPrimalSolution()
print(f"Optimal objective value: {sol.objValue:.4f}")
print(f"Optimal solution: x = {sol.point[0]:.4f}, y = {sol.point[1]:.4f}")
# The optimum is x = 1, y = 1
assert abs(sol.objValue - 2.0) < 1e-3
Quadratic Constraints¶
You can also add quadratic constraints, such as circles or ellipses:
# Problem: minimize x + y subject to x^2 + y^2 <= 4 (inside a circle)
solver = SHOTpy.Solver()
problem = SHOTpy.Problem(solver)
x = problem.addVariable("x", SHOTpy.VariableType.Real, -10.0, 10.0)
y = problem.addVariable("y", SHOTpy.VariableType.Real, -10.0, 10.0)
# Linear objective
problem.setObjective(x + y, SHOTpy.ObjectiveDirection.Minimize)
# Quadratic constraint: x^2 + y^2 <= 4
problem.addConstraint(x**2 + y**2 <= 4, "circle")
# Solve
problem.finalize()
assert solver.setProblem(problem)
assert solver.solveProblem()
assert solver.getModelReturnStatus() == SHOTpy.ModelReturnStatus.OptimalGlobal
sol = solver.getPrimalSolution()
print(f"Optimal objective value: {sol.objValue:.4f}")
print(f"Optimal solution: x = {sol.point[0]:.4f}, y = {sol.point[1]:.4f}")
print(f"Distance from origin: {(sol.point[0]**2 + sol.point[1]**2)**0.5:.4f}")
# The optimum is x = y = -sqrt(2), on the circle
assert abs(sol.objValue + 2 * math.sqrt(2)) < 1e-3