# Complementarity.jl with Path

**URL:** <https://discourse.julialang.org/t/complementarity-jl-with-path/103081>\
**Category:** Optimization (Mathematical)\
**Tags:** jump, error, complementarity\
**Created:** [August 22, 2023, 4:22pm UTC](https://discourse.julialang.org/t/complementarity-jl-with-path/103081 "2023-08-22T16:22:53Z")\
**Posts on this page:** 1\
**Showing post:** 7

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [September 28, 2023, 9:04pm UTC](https://discourse.julialang.org/t/complementarity-jl-with-path/103081/7 "2023-09-28T21:04:49Z")

</div>

Some good news is that you can stop using Complementarity.jl. We’ve recently added first-class support for mixed-complementarity problems to JuMP. See:

- [ANN: JuMP v1.15 is released](https://discourse.julialang.org/t/ann-jump-v1-15-is-released/103875)
- [Mixed complementarity problems · JuMP](https://jump.dev/JuMP.jl/stable/tutorials/nonlinear/complementarity/)

Here’s what the translation would look like:

```plaintext
using JuMP
import PATHSolver
A = [300, 350, 400, 450, 500]
theta = [0.2, 0.2, 0.2, 0.2, 0.2]
B = 1
I = 90
C = 60
Tau = 8760
technologies = [1, 2, 3, 4, 5]
m = Model(PATHSolver.Optimizer)
@variables(m, begin
    x[technologies] >= 0
    Q[technologies] >= 0
    alpha[technologies] >= 0
end)
for i in 2:length(technologies)
    @constraint(m, x[1] == x[i])
end
@constraints(m, begin
    max_capacity[i in technologies], x[i] - Q[i] ⟂ alpha[i]
    kkt_Q[i in technologies], Tau * sum(theta[j] * (C - A[j] + B * Q[j]) for j in technologies) + alpha[i] ⟂ Q[i]
    kkt_x[i in technologies], 1000 * I - alpha[i] ⟂ x[i]
end)
optimize!(m)
println("x = ", value.(x))
println("Q = ", value.(Q))

```

But if you run the code, you’ll get the error:

```julia
julia> for i in 2:length(technologies)
           @constraint(m, x[1] == x[i])
       end
ERROR: Constraints of type MathOptInterface.ScalarAffineFunction{Float64}-in-MathOptInterface.EqualTo{Float64} are not supported by the solver.

If you expected the solver to support your problem, you may have an error in your formulation. Otherwise, consider using a different solver.

The list of available solvers, along with the problem types they support, is available at https://jump.dev/JuMP.jl/stable/installation/#Supported-solvers.
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:33
 [2] _moi_add_constraint(model::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.GenericOptimizer{Float64, MathOptInterface.Utilities.ObjectiveContainer{Float64}, MathOptInterface.Utilities.VariablesContainer{Float64}, PATHSolver.OptimizerFunctionConstraints{Float64}}}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, f::MathOptInterface.ScalarAffineFunction{Float64}, s::MathOptInterface.EqualTo{Float64})
   @ JuMP ~/.julia/packages/JuMP/ToPd2/src/constraints.jl:679
 [3] add_constraint(model::Model, con::ScalarConstraint{AffExpr, MathOptInterface.EqualTo{Float64}}, name::String)
   @ JuMP ~/.julia/packages/JuMP/ToPd2/src/constraints.jl:706
 [4] macro expansion
   @ ~/.julia/packages/JuMP/ToPd2/src/macros.jl:1345 [inlined]
 [5] top-level scope
   @ ./REPL[14]:2

```

That’s because you cannot add equality constraints to a mixed-complementarity problem.

You need to do instead:

```julia
using JuMP
import PATHSolver
A = [300, 350, 400, 450, 500]
theta = [0.2, 0.2, 0.2, 0.2, 0.2]
B = 1
I = 90
C = 60
Tau = 8760
technologies = [1, 2, 3, 4, 5]
m = Model(PATHSolver.Optimizer)
@variables(m, begin
    x[technologies] >= 0
    Q[technologies] >= 0
    alpha[technologies] >= 0
    μ[technologies[2:end]] # !!! NEW !!!
end)
@constraints(m, begin
    [i=technologies[2:end]], x[1] - x[i] ⟂ μ[i] # !!! NEW !!!
    max_capacity[i in technologies], x[i] - Q[i] ⟂ alpha[i]
    kkt_Q[i in technologies], Tau * sum(theta[j] * (C - A[j] + B * Q[j]) for j in technologies) + alpha[i] ⟂ Q[i]
    kkt_x[i in technologies], 1000 * I - alpha[i] ⟂ x[i]
end)
optimize!(m)
println("x = ", value.(x))
println("Q = ", value.(Q))

```

and now I get the same solution as Complementarity.jl.

If this solution isn’t what you expect, then you have a mistake somewhere in your equations.

---

_[View the full topic](https://discourse.julialang.org/t/complementarity-jl-with-path/103081)._
