jump-dev / MathOptInterface.jl

A data structure for mathematical optimization problems
http://jump.dev/MathOptInterface.jl/
Other
392 stars 87 forks source link

Order of columns during copy_to #2493

Closed odow closed 3 months ago

odow commented 5 months ago

@mlubin and I have been discussing the following example:

julia> using JuMP

julia> function main()
           model = Model()
           @variable(model, x)
           @variable(model, y >= 0)
           @objective(model, Min, x + y)
           write_to_file(model, "file.mps")
           print(read("file.mps", String))
       end
main (generic function with 1 method)

julia> main()
NAME
ROWS
 N  OBJ
COLUMNS
    y         OBJ       1
    x         OBJ       1
RHS
RANGES
BOUNDS
 LO bounds    y         0
 PL bounds    y
 FR bounds    x
ENDATA

In JuMP, the columns are ordered x, y, but the MPS file, they are ordered as y, x.

Since the behavior of MIP solvers can depend on the column (and row) ordering, this can be undesirable.

The problem is:

https://github.com/jump-dev/MathOptInterface.jl/blob/bca8a31a50c208e6f05e009f3f328678ae3cda83/src/Utilities/copy.jl#L199-L234

https://github.com/jump-dev/MathOptInterface.jl/blob/bca8a31a50c208e6f05e009f3f328678ae3cda83/src/Utilities/copy.jl#L493-L497

which eagerly tries to constrain variables on creation based on their set type.

I wonder if we should:

1) not do this for scalar variables; or 2) use a better heuristic, that adds variables in the correct order, but puts them in a set iff they are consecutive in the VectorOfVariables function.

The original motivation for doing this is so that variable bridges can be preferentially used.

I don't really have an answer yet. I'll explore some stuff and report here.

odow commented 5 months ago

Okay. It's a bit more effort, but I think we can make this work out-of-the-box, just like we do for writing variable cones in the CBF writer.

See: https://github.com/jump-dev/MathOptInterface.jl/pull/2478

x-ref https://github.com/jump-dev/MathOptInterface.jl/pull/2494