This package uses JuMP, PolyJuMP and HomotopyContinuation.jl to compute the central paths associated to a given algebraic optimization problem.
The algorithm proceeds as follows:
- it transcribes the central path equations as a semi-algebraic set, parameterized by a barrier parameter
mu; - the semi-algebraic set is passed to HomotopyContinuation.jl, which computes the set of solutions for multiple barrier parameters using homotopy continuation.
The algorithm works only for very small instances, and has mostly a pedagogical purpose. Furthermore, the algorithm works only if the KKT conditions of the problem writes as a system of polynomial equations defining a semi-algebraic set. This is the case for LPs, QPs, and NLPs formulated with polynomial expressions.
We take the LP from this article (Figure 2), whose central path exhibits a very sharp turn close to the solution.
using JuMP using PolyJuMP using HomotopyContinuation using CentralPath model = Model(optimizer_with_attributes( PolyJuMP.KKT.Optimizer, "solver" => HomotopyContinuation.SemialgebraicSetsHCSolver(), )) # Define LP with JuMP eps = 3e-1 @variable(model, 0 <= x <= 1) @variable(model, 0 <= y <= 1) @constraint(model, x + 2*y >= eps) @objective(model, Min, 2*x + 5*y) # Barrier values mu_vals = [10^f for f in -9:0.1:5] # Solve with homotopy continuation MOI.Utilities.attach_optimizer(model) solver = JuMP.unsafe_backend(model) results = CentralPath.compute_central_path(solver, mu_vals)
We consider the instance HS15 from the Hock & Schittkowski collection. The problem is non-convex but is semi-algebraic. It has two distinct central paths.
using JuMP using PolyJuMP using HomotopyContinuation using CentralPath model = Model(optimizer_with_attributes( PolyJuMP.KKT.Optimizer, "solver" => HomotopyContinuation.SemialgebraicSetsHCSolver(), )) # Define non-convex NLP with JuMP @variable(model, x1 <= 0.5) @variable(model, x2) @objective(model, Min, 100.0 * (x2 - x1^2)^2 + (1.0 - x1)^2) @constraint(model, x1 * x2 >= 1.0) @constraint(model, x1 + x2^2 >= 0.0) # Barrier values mu_vals = [10^f for f in -9:0.1:9] # Solve with homotopy continuation MOI.Utilities.attach_optimizer(model) solver = JuMP.unsafe_backend(model) results = CentralPath.compute_central_path(solver, mu_vals)

