How to get the variables/constraint names using MathProgBase?

Is there any method for getting the variables/constraint name not a just index from the MPS file format?
I just want to make a dictionary for “variable name - index, constraint name - index”

model = MathProgBase.LinearQuadraticModel(ClpSolver())
MathProgBase.loadproblem!(model,"test.mps")
c = MathProgBase.getobj(model)
A = MathProgBase.getconstrmatrix(model)
nrow,ncol = size(A)
xlb = MathProgBase.getvarLB(model)
xub = MathProgBase.getvarUB(model)
l = MathProgBase.getconstrLB(model)
u = MathProgBase.getconstrUB(model)
t = MathProgBase.getvartype(model)
  • wirteLP package is not available in Julia ver 1.0<

or

I want to make a sparse matrix for constraint from the JuMP.read_from_file("test.mps")

From the model returned by read_from_file, you can get the list of variables with all_variables and then for each one you can get the name wirh name.
Then you can get the list of constraint types with list_of_constraint_types and the list of constraints for given types with all_constraints. For each constraint, you can get the name with name.

Thank you for answering.

I already know the read_from_file and I have tried that…
However, I couldn’t make a constraint sparse matrix.
Exactly, I couldn’t find the way to make a list for each constraint as like this, [coefficient, variable].

m = read_from_file("example.mps")
optimizer=optimizer_with_attributes(Cbc.Optimizer,  "maxSolutions" => 1, "logLevel "=>1, "seconds" => 300,"allowableGap "=>70)
set_optimizer(m, optimizer)

The type of constraint is followed

julia> list_of_constraint_types(m)
7-element Array{Tuple{DataType,DataType},1}:
 (GenericAffExpr{Float64,VariableRef}, MathOptInterface.EqualTo{Float64})    
 (GenericAffExpr{Float64,VariableRef}, MathOptInterface.GreaterThan{Float64})
 (GenericAffExpr{Float64,VariableRef}, MathOptInterface.LessThan{Float64})   
 (VariableRef, MathOptInterface.EqualTo{Float64})                            
 (VariableRef, MathOptInterface.Interval{Float64})                           
 (VariableRef, MathOptInterface.Integer)                                     
 (VariableRef, MathOptInterface.ZeroOne) 

If I get one of MOI.LessThan{Float64} constraint,

julia> less_than_constraints = all_constraints(m, GenericAffExpr{Float64,VariableRef}, MOI.LessThan{Float64})

julia>less_than_constraints[1]
HSBAL_CNYIT1701W_DEHAM1701E_004_OUTER : -1.0e6 HSBAL_CNYIT1701W_DEHAM1701E_004_OUTER + BSBAL_CNYIT1701W_DEHAM_004C1 + BSBAL_CNYIT1701W_DEHAM_004S1 + BSBAL_CNYIT1701W_DEHAM_004C2 ≤ 0.0

Here, I couldn’t extract the constraint name, coefficient and variable, sense, rhs.
I want to make a sparse matrix like as

[HSBAL_CNYIT1701W_DEHAM1701E_004_OUTER, HSBAL_CNYIT1701W_DEHAM1701E_004_OUTER] =  -1.0e6
[HSBAL_CNYIT1701W_DEHAM1701E_004_OUTER, BSBAL_CNYIT1701W_DEHAM_004C1] = 1.0
[HSBAL_CNYIT1701W_DEHAM1701E_004_OUTER, BSBAL_CNYIT1701W_DEHAM_004S1] = 1.0
[HSBAL_CNYIT1701W_DEHAM1701E_004_OUTER, BSBAL_CNYIT1701W_DEHAM_004C2] = 1.0

I want to handle the ConstraintRef

    1. Extracting the constraint name
    1. Extraicting the coefficient and variables
julia> typeof(less_than_constraints[1])
ConstraintRef{Model,MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64},MathOptInterface.LessThan{Float64}},ScalarShape}

julia>less_than_constraints[1]
HSBAL_CNYIT1701W_DEHAM1701E_004_OUTER : -1.0e6 HSBAL_CNYIT1701W_DEHAM1701E_004_OUTER + BSBAL_CNYIT1701W_DEHAM_004C1 + BSBAL_CNYIT1701W_DEHAM_004S1 + BSBAL_CNYIT1701W_DEHAM_004C2 ≤ 0.0

# Extracting the name
julia> name(less_than_constraints[1])
"HSBAL_CNYIT1701W_DEHAM1701E_004_OUTER"

# How can extract the variables and coefficient?
julia> constraint_object(less_than_constraints[1]).func
-1.0e6 HSBAL_CNYIT1701W_DEHAM1701E_004_OUTER + BSBAL_CNYIT1701W_DEHAM_004C1 + BSBAL_CNYIT1701W_DEHAM_004S1 + BSBAL_CNYIT1701W_DEHAM_004C2

julia> constraint_object(less_than_constraints[1]).func[1]
ERROR: MethodError: no method matching getindex(::GenericAffExpr{Float64,VariableRef}, ::Int64)
Stacktrace:
 [1] top-level scope at none:0

I think MathProgBase package is the better option for me…
So I want to know the extract the “variable name” from the MathProgBase.

MathProgBase is deprecated and as a matter of fact its support has been removed from Cbc.jl
We are adding the possibility to build JuMP models from matrix format and to retrieve matrix formats from JuMP in https://github.com/JuliaOpt/MatrixOptInterface.jl
In your example, you do f[1] where f = constraint_object(less_than_constraints[1]).func.
This does not work but you can do terms[1] where terms = collect(linear_terms(f))

1 Like

Oh…! Thanks a lot!!!
Thank you for appreciate!!! :joy:

Unfortunately… I have one more question…
Then how can I get value for interval…?

julia> constraint_object(all_constraints(m, VariableRef, MathOptInterface.Interval{Float64})[1]).set
MathOptInterface.Interval{Float64}(0.0, 2.0)

sorry… :cry:
It is too difficult to me…

It has fields .lower and .upper. You can see what fields a type has using fieldnames, e.g., fieldnames(MOI.Interval{Float64}).

1 Like

Thanks a lot! :smiling_face_with_three_hearts:

Thanks a lot.
Finally, It was success!

I uploaded my code at Github!

I want to share my code for everybody :blush:

You can also use the QPSReader package.

Read an MPS file with

using QPSReader

qps = readqps("example.mps")

and you can then access all the problem data, for instance:

using SparseArrays

# Constraint matrix
A = sparse(qps.arows, qps.acols, qps.avals, qps.ncon, qps.nvar)

# Index --> variable name 
qps.varnames

# Variable name --> index
qps.varindices
1 Like

@mtanneau Thanks for the reply above with QPS Reader. I was trying to extract constraint matrix and this helped. Is there a way to extract RHS as well?
I actually have a solver to which I have to pass A, b, C, d according to constraint sets Ax == b and Cx <= d where A, C are matrices and b, d are vectors. Is there a way I can extract all 4 from a mps file using QPS or any other library?
Sorry if the question seems dumb, I’m new to julia and still figuring out syntaxes…

Hi!

QPSReader represents a problem in the form

\begin{array}{rl} \min \quad & \frac{1}{2} x^{\top} Q x + c^{\top} x + c_{0}\\ s.t. \quad & b_{l} \leq A x \leq b_{u},\\ & l ≤ x ≤ u, \end{array}

You can get the values of A, b_{l}, b_{u}, l, u from the QPSData struct that is returned by readqps.
It is documented here: GitHub - JuliaSmoothOptimizers/QPSReader.jl: A reader for MPS and QPS files.

To get to the form you mentioned, you will need to extract equality constraints (that’s the easy part because they have the same RHS).
Then, replace all two-side constraints (which have finite lower bound and a finite upper bound) with two inequalities, and re-arrange all the inequalities to match the Cx \leq d form.
Don’t forget variable bounds int he process.

Hi!
Thanks for the response. It helped a lot. I found a much simple workaround, although computationally it would cost. The constraints are of the form

b_l ≤ Ax ≤ b_u

So I convert them to

Ax ≤ b_u and  -Ax ≤ -b_l

And then use vcat(A,-A) and vcat(b_u, -b_l) in just inequalities. This would implicitly capture all the equalities and inequalities, although there are twice the number of equations. But for small problems, this seems to be working for me.