Finding all binding constraints using JuMP

Is this the correct way to find all the binding constraints in JuMP?
I figure it is only binding of it has a nonzero shadow-price.
However shadow_price only works for <, > and == constraints so I am not sure i am going about this the right way.
Is there a better way that would also find when a Conic constraint was binding?

function binding_constraints(model, threshold=1e-8)
    binding_cons = ConstraintRef[]
    for (F, S) in list_of_constraint_types(model)  
        # only these relations are supported by shadow_price
        S <: Union{MOI.EqualTo, MOI.LessThan, MOI.GreaterThan} || continue
        
        for con in all_constraints(model, F, S)
            if abs(shadow_price(con)) > threshold || continue
                push!(binding_cons, con)
            end
        end
    end
    return binding_cons
end

Use dual instead of shadow_price. shadow_price is just for convenience for linear programs. (JuMP uses a different convention, so a lot of classes will teach “shadow price” instead of conic duality.)

What constraints do you want to check though?

Not sure yet.
Really I want to tweak my model until one particular constraint is binding.
Which probably means finding other ones that are binding and relaxing them.

So

function binding_constraints(model, threshold=1e-8)
    binding_cons = ConstraintRef[]
    for (F, S) in list_of_constraint_types(model)  
        for con in all_constraints(model, F, S)
            if abs(dual(con)) > threshold || continue
                push!(binding_cons, con)
            end
        end
    end
    return binding_cons
end

Careful with that abs(dual(con)): if you have conic constraints, dual(con) will be a Vector, and abs will error. I would suggest you use norm instead.

A more mathematical note (for completeness; probably not news to you): one the one hand, if the dual is non-zero, then the constraint will be tight (assuming your solution satisfies complementary slackness). Nothing new here.
On the other hand, however, there may exist a constraint a^{T}x \geq b such that, at the optimum, a^{T}x^{*} = b, but the corresponding dual is zero. This is not restricted to linear constraints, and it may happen when you have redundant constraints and/or multiple optimal solutions.

2 Likes