Giter Club home page Giter Club logo

Comments (3)

odow avatar odow commented on August 16, 2024

Okay. So, if you use the MOI interface, then the round-trip order of variable indices is preserved via MOI.get(model, MOI.ListOfVariableIndices()), and, assuming you don't do anything unusual like deleting a variable, the index mapping is one-to-one.

julia> import MathOptInterface as MOI

julia> model = MOI.FileFormats.CBF.Model()
A Conic Benchmark Format (CBF) model

julia> x = MOI.add_variables(model, 3)
3-element Vector{MathOptInterface.VariableIndex}:
 MOI.VariableIndex(1)
 MOI.VariableIndex(2)
 MOI.VariableIndex(3)

julia> t = MOI.add_variable(model)
MOI.VariableIndex(4)

julia> MOI.add_constraint(
           model,
           MOI.Utilities.operate(vcat, Float64, sum(1.0 * x[i] for i in 1:3) - 1.0),
           MOI.Zeros(1),
       )
MathOptInterface.ConstraintIndex{MathOptInterface.VectorAffineFunction{Float64}, MathOptInterface.Zeros}(1)

julia> MOI.add_constraint(model, MOI.VectorOfVariables([t; x]), MOI.SecondOrderCone(4))
MathOptInterface.ConstraintIndex{MathOptInterface.VectorOfVariables, MathOptInterface.SecondOrderCone}(1)

julia> MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE)

julia> MOI.set(model, MOI.ObjectiveFunction{MOI.VariableIndex}(), t)

julia> MOI.write_to_file(model, "/tmp/model.cbf")

julia> m = MOI.FileFormats.CBF.Model()
A Conic Benchmark Format (CBF) model

julia> MOI.read_from_file(m, "/tmp/model.cbf")

julia> print(model)
Minimize VariableIndex:
 v[4]

Subject to:

VectorOfVariables-in-SecondOrderCone
 ┌    ┐
 │v[4]│
 │v[1]│
 │v[2]│
 │v[3]│
 └    ┘  SecondOrderCone(4)

VectorAffineFunction{Float64}-in-Zeros
 ┌                                     ┐
 │-1.0 + 1.0 v[1] + 1.0 v[2] + 1.0 v[3]│
 └                                     ┘  Zeros(1)

julia> MOI.get(model, MOI.ListOfVariableIndices())
4-element Vector{MathOptInterface.VariableIndex}:
 MOI.VariableIndex(1)
 MOI.VariableIndex(2)
 MOI.VariableIndex(3)
 MOI.VariableIndex(4)

julia> print(m)
Minimize ScalarAffineFunction{Float64}:
 0.0 + 1.0 v[4]

Subject to:

VectorAffineFunction{Float64}-in-Zeros
 ┌                                     ┐
 │-1.0 + 1.0 v[1] + 1.0 v[2] + 1.0 v[3]│
 └                                     ┘  Zeros(1)

VectorAffineFunction{Float64}-in-SecondOrderCone
 ┌              ┐
 │0.0 + 1.0 v[4]│
 │0.0 + 1.0 v[1]│
 │0.0 + 1.0 v[2]│
 │0.0 + 1.0 v[3]│
 └              ┘  SecondOrderCone(4)

julia> MOI.get(m, MOI.ListOfVariableIndices())
4-element Vector{MathOptInterface.VariableIndex}:
 MOI.VariableIndex(1)
 MOI.VariableIndex(2)
 MOI.VariableIndex(3)
 MOI.VariableIndex(4)

This is not the case in JuMP (note that t is the last variable in model and the first in m). This is because there are other layers between JuMP and the writer, so copy_to etc does not preserve the ordering.

julia> using JuMP

julia> model = Model()
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.

julia> @variable(model, x[1:3])
3-element Vector{VariableRef}:
 x[1]
 x[2]
 x[3]

julia> @variable(model, t)
t

julia> @constraint(model, sum(x) == 1)
x[1] + x[2] + x[3] = 1

julia> @constraint(model, [t; x] in SecondOrderCone())
[t, x[1], x[2], x[3]]  MathOptInterface.SecondOrderCone(4)

julia> @objective(model, Min, t)
t

julia> write_to_file(model, "/tmp/model.cbf")

julia> m = read_from_file("/tmp/model.cbf")
A JuMP Model
Minimization problem with:
Variables: 4
Objective function type: AffExpr
`Vector{AffExpr}`-in-`MathOptInterface.Zeros`: 1 constraint
`Vector{AffExpr}`-in-`MathOptInterface.SecondOrderCone`: 1 constraint
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.

julia> print(model)
Min t
Subject to
 x[1] + x[2] + x[3] = 1
 [t, x[1], x[2], x[3]]  MathOptInterface.SecondOrderCone(4)

julia> print(m)
Min _[1]
Subject to
 [_[2] + _[3] + _[4] - 1]  MathOptInterface.Zeros(1)
 [_[1], _[2], _[3], _[4]]  MathOptInterface.SecondOrderCone(4)

julia> all_variables(model)
4-element Vector{VariableRef}:
 x[1]
 x[2]
 x[3]
 t

julia> all_variables(m)
4-element Vector{VariableRef}:
 _[1]
 _[2]
 _[3]
 _[4]

Fixing the JuMP issue seems hard, if not impossible, because we'd need to return a mapping between variables and their index in the file format, and some formats don't have the concept of a column ordering (e.g., the LP file format).

So I think the answer is: if you want control, use the MOI interface directly.

@rbassett3: you should probably implement a writer optimizer like: https://github.com/jump-dev/AmplNLWriter.jl/blob/master/src/AmplNLWriter.jl, but for CBF files instead of NL.

from mathoptinterface.jl.

odow avatar odow commented on August 16, 2024

For JuMP, you can use

julia> using JuMP

julia> begin
           model = Model()
           @variable(model, x[1:3])
           @variable(model, t)
           @constraint(model, sum(x) == 1)
           @constraint(model, [t; x] in SecondOrderCone())
           @objective(model, Min, t)
       end
t

julia> function write_cbf(model::Model, filename::String)
           src = MOI.instantiate(MOI.FileFormats.CBF.Model; with_bridge_type = Float64)
           index_map = MOI.copy_to(src, model)
           return Dict(x => index_map[index(x)].value for x in all_variables(model))
       end
write_cbf (generic function with 1 method)

julia> x_to_column = write_cbf(model, "/tmp/model.cbf")
Dict{VariableRef, Int64} with 4 entries:
  x[3] => 4
  t    => 1
  x[2] => 3
  x[1] => 2

from mathoptinterface.jl.

odow avatar odow commented on August 16, 2024

Closing as won't fix. This is hard to do in general at the JuMP level, it works at the MOI level, and there are work-arounds for the few users who need it.

from mathoptinterface.jl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.