I have Julia 1.1.1 and JuMP 0.19. I am solving a concave maximization problem with linear constraints with Ipopt. I am confused with what is happening to the signs of the Lagrange multipliers:
I’ve read the documentation a few times, but I find it less than clear, and I still don’t understand what’s happening.
My provisional conclusion is that I should be using the negatives of the duals.
Is this because I’m maximizing? And what about the shadow_prices?
Correct according to which definition ? We use the following definition: Manual · MathOptInterface
The dual does not depend on the objective sense (you can imagine it to be minimization) which is very useful when writing solver wrappers as you can swap the objective without having to worry about changing the dual.
You can see in the manual that the dual of a <= constraint (22) is a nonpositive variable (27) so what Ipopt returns makes sense.
My definition of “correct” is the textbook definition of the multipliers as sensitivity parameters. So with maximizing an objective and inequalities of the form <=, the corresponding multipliers should be >= 0.
I understand that JuMP doesn’t use the textbook definition, and I’m ok with that, as long as I understand what the proper “conversion” is. That’s why I asked if the negative of the dual is the right thing.
My definition of “correct” is the textbook definition of the multipliers as sensitivity parameters
Then the shadow_price should be what you are looking for, the difference in sign for the second equality constraint might be due to the following in JuMP doc: Constraints · JuMP
Relaxation of equality constraints (and hence the shadow price) is defined based on which sense of the equality constraint is active.
julia> using JuMP, Gurobi
julia> model = Model(with_optimizer(Gurobi.Optimizer, OutputFlag=0));
Academic license - for non-commercial use only
julia> @variable(model, x)
x
julia> @constraint(model, con, x == 2)
con : x = 2.0
julia> @objective(model, Min, x)
x
julia> optimize!(model)
Academic license - for non-commercial use only
julia> shadow_price(con)
-1.0
julia> @objective(model, Max, x)
x
julia> optimize!(model)
julia> shadow_price(con)
1.0
For a fixed problem, the correct multiplier for an equality constraint (according to the defn. I gave) can have either sign.
So it can’t be determined just by whether you’re minimizing or maximizing, which I think is what you are proposing.
What you need seems to be either dual if you are minimizing or -dual if you are maximizing. This is what shadow_price does except that shadow_price also does a correction for equality you don’t need so just use dual and multiply it by -1 if you are maximizing.
I was also confused about this some time ago. I remember the documentation mentioned JuMP is using conic dual, which may be different from the textbook dual. Is the sign difference a result of that?