KNITRO.jl and Complementarity Constraints

Hi,
I’m modeling a system with complementarity constraints.Namely, a flow S has a negative S^- and positive S^+ component:

S=S^+ - S^-
0 \leq S^+
0 \leq S^-

and of course complementary to each other: S^+ \perp S^-.
There are several ways to model this in JuMP. The continuous non-linear form is:

@variables(model, begin
S_lower <= S <= S_upper
S_plus >= 0
S_minus >= 0
end)
@constraints(model, begin
S_plus - S_minus == S
S_plus * S_minus == 0
end)

One could also use binary variables:

@variables(model, begin
S_lower <= S <= S_upper
S_plus >= 0
S_minus >= 0
bS, Bin
end)
@constraints(model, begin
S_plus - S_minus == S
S_plus <= (1-bS) * S_upper
S_plus <= -bS * S_lower 
end)

or

@variables(model, begin
S_lower <= S <= S_upper, # S_lower <= 0
S_plus >= 0
S_minus >= 0
b\^+, Bin
b\^-, Bin
end)
@constraints(model, begin
S_plus - S_minus == S
S_plus <= b^+ * S_upper
S_plus <=  - b^- * S_lower 
b^- + b^+ <= 1
end)

or even with indicator or complementarity constraints macros.

Anyway here is the question. What’s the best way to implement this when using KNITRO.jl?

Since the solver has support for all these implementations in JuMP AND native complementarity constraints in AMPL and others.
Besides the obvious answer of “try all of them, depends on your problem”, has anyone had experience with this before? I’m also sending the same enquiry to Artelys for their recommendation.

I have to confess I am not familiar with the support that Knitro has for complementarity constraints, but I guess that none of the code snippets that you give here helps Knitro recognise that these are complementarity constraints. In their manual entry for complementarity constraints, which you also link, they mention that when called through various API (AMPL, Matlab, C, C++), special syntax is provided to inform Knitro about these special constraints. Why not then rely on a similar dedicated syntax for complementarity constraints in Julia/JuMP (you also linked it) too?

1 Like

If the solver supports complementarity constraints, which KINTRO.jl does, then you should use;

using JuMP
model = Model()
@variable(model, S_plus >= 0)
@variable(model, S_minus >= 0)
@expression(model, S, S_plus - S_minus)
@constraint(model, S_plus ⟂ S_minus)