Gurobi how to get variable coefficients in constraints

I am trying to extract the variable coefficients in a constraint. According to Gurobi documentation, Model.getCoeff(), the function Model.getCoeff() should do the trick. However, this does not exist in Gurobi Julia package. The closest one I get is Gurobi.getcoeff(model::Gurobi.Model , cidx::Integer , vidx::Integer) at Gurobi\7YNJV\src\grb_constrs.jl:367. However, I can not make it work.
For example, in the following minimal code:

using Gurobi
using JuMP
# define a simple UC problem
n_u = 5
    n_t = 3
    U = collect(1:n_u) # num units
    T = collect(1:n_t) # num time steps
    p_g_min = round.(0.0*rand(n_u), digits=2)
    p_g_max = 1 .+ round.(rand(n_u), digits=2)
    cost_g = 10 .+ round.(10.0*rand(n_u), digits=1)
    cost_g0 = round.(1.0*rand(n_u), digits=1)
    d0 = rand((sum(p_g_min):.01:.6*sum(p_g_max)),n_t)

# basic_uc_model = Model(Gurobi.Optimizer)
basic_uc_model = direct_model(Gurobi.Optimizer())
    @variable(basic_uc_model, p_g_min[i] <= p_g[i in U, t in T] <= p_g_max[i])

    @variable(basic_uc_model, 0 <= I_g[i in U, t in T] <= 1)

    @constraint(basic_uc_model, lower_band[i in U, t in T], p_g[i,t] >= p_g_min[i]*I_g[i,t])
    @constraint(basic_uc_model, upper_band[i in U, t in T], p_g[i,t] <= p_g_max[i]*I_g[i,t])
    @constraint(basic_uc_model, demand[t in T], sum(p_g[i,t] for i in U) == d0[t])
    @objective(basic_uc_model, Min, sum(p_g[i,t]*cost_g[i] + I_g[i,t]*cost_g0[i] for i in U, t in T))

    set_optimizer_attribute(basic_uc_model, "PoolSearchMode", 1)

Gurobi.getcoeff(basic_uc_model, lower_band[1,1], p_g[1,1])

Error: MethodError: no method matching getcoeff(::Model, ::ConstraintRef{Model,MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.GreaterThan{Float64}},ScalarShape}, ::VariableRef)
in top-level scope at test_gurobi.jl:42

I think I am not using the correct formatting and I am not sure about cidx and vidx. I would appreciate any help.

You probably want something like

con = constraint_object(lower_band[1, 1])
coef = con.func.terms[p_g[1, 1]]

Gurobi.j wraps the C API, not the Python API:

However, I suggest you avoid using it if at all possible. It is mainly intended for callbacks, not for general users.

1 Like

Thanks that does the trick. I wonder if such option is implemented within JuMP itself?

It’s a known issue: Feature request: implement getindex for expressions · Issue #2371 · jump-dev/JuMP.jl · GitHub.

It’s a good intro issue if you want to help contribute to JuMP.

1 Like

Okay here is an interesting one. Your method returns an error if the constraint does not contain that variable. For example:

cc[1,1] # segment_power[1,1] : p_g_seg[1,1,1] + p_g_seg[1,2,1] + p_g_seg[1,3,1] - p_g[1,1] == 0.0
con = constraint_object(cc[1,1])
OrderedCollections.OrderedDict{VariableRef,Float64} with 4 entries:
  p_g_seg[1,1,1] => 1.0
  p_g_seg[1,2,1] => 1.0
  p_g_seg[1,3,1] => 1.0
  p_g[1,1]       => -1.0
haskey(con.func.terms, "p_g[1,1]") #false
haskey(con.func.terms, p_g[1,1]) #false
4-element Array{VariableRef,1}:
p_g[1,1] in collect(keys(con.func.terms)) #false
typeof(collect(keys(con.func.terms))[4]) #VariableRef
typeof(p_g[1,1]) #VariableRef
con.func.terms[p_g[1,1]] # -1.00
con.func.terms[p_g[1,2]] #KeyError: key p_g[1,2] not found

Besides your suggestion, I also found How do I extract the coefficients and RHS's of all constraints in a JuMP linear program? (Need for KKT) - #4 by odow and it suggested using some NLP package that returns “A” matrix. However, it is quite a challenge to figure out the ordering of that A matrix in large cases. Do you have any idea how to get around this issue?

con.func.terms is just a dictionary, so you can use get(con.func.terms, p_g[1, 2], 0.0) to have a default of 0.0 if the key is not present.

The NLP package and A matrix was for something different.

1 Like