Solve MCP problems with nonlinear constraints

Hello ! Ive been trying to solve an MCP problem with JuMP and non linear constraints/optimality condition but have not been able to do so.
Is there a way around this? or other package that might do the trick?
Thank you in advance!

Do you have an example? That might be easier to discuss than generalities.

KNITRO.jl supports MCP and nonlinear.

Complementarity.jl can reformulate some MPEC to nonlinear.

Otherwise PATH supports only MCP, so you’ll need to reformulate your problem to a pure MCP.

Hello @odow ! thank you very much for responding.

Yes I do have an example.

@variable(model, alpha >= 0)  
@variable(model, beta >= 0)  
@variable(model, gamma >= 0) 
@variable(model, delta >= 0) 
 
@constraint(model, kkt_beta, -P * delta * (1 + alpha) + gamma ⟂ beta)

@constraint(model, kkt_alpha, beta * delta * P - c * ((P - d)^2) ⟂ alpha)

@constraint(model, kkt_gamma, mean * (2 - d) - beta ⟂ gamma)

There rest are linear constraints
P, c , mean and d are parameters.

Other related question is that I tried to migrate this to Complementarity.jl but had some issues with a user-defined function that is being called in the @mapping . Error which I did not had using just JuMP MCP. By any chance, do you have any tip on that?

This should work with PATHSolver.jl. Something like:

using JuMP, PATHSolver

P, c, mean, d = 1.0, 1.0, 1.0, 1.0

model = Model(PATHSolver.Optimizer)

@variable(model, alpha >= 0)

@variable(model, beta >= 0)

@variable(model, gamma >= 0)

@variable(model, delta >= 0)

@constraint(model, kkt_beta, -P * delta * (1 + alpha) + gamma ⟂ beta)

@constraint(model, kkt_alpha, beta * delta * P - c * ((P - d)^2) ⟂ alpha)

@constraint(model, kkt_gamma, mean * (2 - d) - beta ⟂ gamma)

optimize!(model)

solution_summary(model)

value(alpha), value(beta), value(gamma), value(delta)

The thing is I get this error:

ERROR: LoadError: Constraints of type 
MathOptInterface.VectorQuadraticFunction{Float64}-in-
MathOptInterface.Complements are not supported by the solver.

But when I remove the variable multiplications from the restrictions, then it works.

What version of PATHSolver.jl do you have? Try updating your packages:

(mpec) pkg> st
Status `/private/tmp/mpec/Project.toml`
[4076af6c] JuMP v1.19.0
[f5f7c340] PATHSolver v1.7.2

julia> using JuMP, PATHSolver

julia> P, c, mean, d = 1.0, 1.0, 1.0, 1.0
(1.0, 1.0, 1.0, 1.0)

julia> model = Model(PATHSolver.Optimizer)
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: EMPTY_OPTIMIZER
Solver name: Path 5.0.03

julia> @variable(model, alpha >= 0)
alpha

julia> @variable(model, beta >= 0)
beta

julia> @variable(model, gamma >= 0)
gamma

julia> @variable(model, delta >= 0)
delta

julia> @constraint(model, kkt_beta, -P * delta * (1 + alpha) + gamma ⟂ beta)
kkt_beta : [-delta*alpha + gamma - delta, beta] ∈ MathOptInterface.Complements(2)

julia> @constraint(model, kkt_alpha, beta * delta * P - c * ((P - d)^2) ⟂ alpha)
kkt_alpha : [beta*delta, alpha] ∈ MathOptInterface.Complements(2)

julia> @constraint(model, kkt_gamma, mean * (2 - d) - beta ⟂ gamma)
kkt_gamma : [-beta + 1, gamma] ∈ MathOptInterface.Complements(2)

julia> optimize!(model)
Path 5.0.03 (Fri Jun 26 09:58:07 2020)
Written by Todd Munson, Steven Dirkse, Youngdae Kim, and Michael Ferris


Crash Log
major  func  diff  size  residual    step       prox   (label)
    0     0             0.0000e+00             0.0e+00 (f[    1])

Major Iteration Log
major minor  func  grad  residual    step  type prox    inorm  (label)
    0     0     1     1 0.0000e+00           I 0.0e+00 0.0e+00 (f[    1])

Major Iterations. . . . 0
Minor Iterations. . . . 0
Restarts. . . . . . . . 0
Crash Iterations. . . . 0
Gradient Steps. . . . . 0
Function Evaluations. . 1
Gradient Evaluations. . 1
Basis Time. . . . . . . 0.000002
Total Time. . . . . . . 0.090749
Residual. . . . . . . . 0.000000e+00

julia> solution_summary(model)
* Solver : Path 5.0.03

* Status
  Result count       : 1
  Termination status : LOCALLY_SOLVED
  Message from the solver:
  "The problem was solved"

* Candidate solution (result #1)
  Primal status      : FEASIBLE_POINT
  Dual status        : NO_SOLUTION
  Objective value    : 0.00000e+00

* Work counters
  Solve time (sec)   : 9.07490e-02


julia> value(alpha), value(beta), value(gamma), value(delta)
(0.0, 0.0, 0.0, 0.0)

I cant believe I did not check that in so long :sweat_smile: . Thank you very much @odow for always answering so fast!

But now another problem raised for me for a different MCP problem that was previously(before my pkg’s updates) Locally Solved but now gets a Termination status : SLOW_PROGRESS . I downgraded JuMP and found that the version v1.14.1 finds the feasible point again. It must be a something that breaks it on version v1.15.0.

I know this particular MCP problem is feasible because It is successfully solved in GAMS using PATH.

Maybe I failed in some part of the translation to Julia but strange that no error of syntax or something like that was raised and that the previos version of JuMP did give me the same solution than GAMS.

Has anyone got a similar issue that you remember? I am currently looking into the github issues to see if I find something.

Can you provide a reproducible example? Do you provide a starting point?

Set a start using the start keyword: @variable(model, alpha >= 0, start = 1).

Yes, that helped! Thank you.

1 Like