How to obtain dual variables (shadow price) for a set of constraints

Hello,

I have time-related constraints and I modeled it as

for time in 1:nTime
    @constraint(model, a[time] + b[time] == c[time], base_name = "cons" 
end

The model is solved and I want to obtain the dual variables, thus, how to obtain them by the above constraint formulation method?

BTW, I know there are two other ways to obtain the dual:

@constraint(model, cons1, a[1] + b[1] == c[1])
@constraint(model, cons2, a[2] + b[2] == c[2])
...
shadow_price(cons1)
...

and

cons = @constraints(model, [time in 1:nTime], a[time] + b[time] == c[time])
shodow_price(cons)

(My model contains other parameters, so that the top modeling method is preferred for me. )

1 Like

Sorry, my method is

for time in 1:nTime
    @constraint(model, a[time] + b[time] == c[time], 
    base_name = "cons$(time)")
end

The dual variables can be obtained by:

for time in 1:nTime
    shadow_price(constraint_by_name(model, "cons$(time)")
end
1 Like

You should always keep in mind that JuMP variables and constraints are just regular Julia objects.

That means you can use them with any other data structure in Julia. Iā€™d write your model as:

cons = []
for time in 1:nTime
    c = @constraint(model, a[time] + b[time] == c[time], base_name = "cons") 
    push!(cons, c)
end
shadow_price.(cons)

or perhaps

cons = map(1:nTime) do time
    # Stuff here
    return @constraint(model, a[time] + b[time] == c[time], base_name = "cons")
end
shadow_price.(cons)

Your constraint_by_name approach also works, but it involves a couple of lookups and relies on base_name being unique. So having an explicit vector of constraints might be better.

1 Like

Indeed, this method could be better, as it returns a vector, which is better for using dual variables.

1 Like