Hi @anand.kumar, welcome to the forum
JuMP supports a particularly form of mixed complementarity problems in which a variable (or vector of variables) x
complements a function F(x)
.
See the documentation: Mixed complementarity problems · JuMP
Those particular constraints would need to be written as:
using JuMP
I = 1:4
J = 1;2
K = 1:3
L = 1:4
model = Model()
@variable(model, x[i in I], start = x0[i])
@variable(model, y[j in J, k in K], start = y0[j, k])
@variable(model, ll[l in L, k in K] >= 0, start = ll0[l, k])
@constraint(model, compl_1[k in K], x[1] - y[1,k] ⟂ ll[1, k])
@constraint(model, compl_2[k in K], x[2] - y[2,k] ⟂ ll[2, k])
@constraint(model, compl_3[k in K], y[1,k] - x[3] ⟂ ll[3, k])
@constraint(model, compl_4[k in K], y[2,k] - x[4] ⟂ ll[4, k])
Note the signs. Since ll >= 0
, then the complementing function F(x)
is 0
if ll > 0
and F(x) >= 0
if ll == 0
.
However, your larger example is an MPEC. Currently, JuMP is missing first-class support for converting MPECs into NLPs, . so you’ll need to use a library like Complementarity.jl:
using JuMP, Ipopt, Complementarity
I = 1:4
J = 1:2
K = 1:3
L = 1:4
x0 = [1, 1, -1, -1]
y0 = zeros(length(J), length(K))
ll0 = ones(length(L), length(K))
model = Model(Ipopt.Optimizer)
@variable(model, x[i in I], start = x0[i])
@variable(model, y[j in J, k in K], start = y0[j, k])
@variable(model, ll[l in L, k in K], start = ll0[l, k])
@objective(model, Max, (x[1] - x[3]) * (x[2] - x[4]))
@constraints(model, begin
-y[1,1] - y[2,1]^2 <= 0
y[1,2]/4 + y[2,2] - 3/4 <= 0
-y[2,3] - 1 <= 0
1 + ll[1,1] - ll[3,1] == 0
2*y[2,1] + ll[2,1] - ll[4,1] == 0
-1/4 + ll[1,2] - ll[3,2] == 0
-1 + ll[2,2] - ll[4,2] == 0
0 + ll[1,3] - ll[3,3] == 0
1 + ll[2,3] - ll[4,3] == 0
end)
for k in K
@complements(model, 0 >= y[1,k] - x[1], ll[1,k] >= 0)
@complements(model, 0 >= y[2,k] - x[2], ll[2,k] >= 0)
@complements(model, 0 >= - y[1,k] + x[3], ll[3,k] >= 0)
@complements(model, 0 >= - y[2,k] + x[4], ll[4,k] >= 0)
end
optimize!(model)
solution_summary(model)
value.(x)
value.(y)
value.(ll)
This gets a trivial solution with zero volume though, so I don’t know if I made a typo or something?