Comments (3)
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.
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.
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)
- Issue with Precompilation on ARMv7l Architecture HOT 3
- MOF broken with new NLP backend HOT 2
- [Utilities] get_fallback assumes Float64
- Make FileFormats.MPS.Model an AbstractOptimizer HOT 5
- [FileFormats.MPS] store matrix for writing in column order HOT 1
- [FileFormats.MPS] Problem when reading generated MPS with CPLEX HOT 3
- [Nonlinear] add initialize timer HOT 1
- [FileFormats.NL] cannot read models with S section
- [FileFormats.NL] write free rows
- ReverseAD doesn't error for out-of-bound writes
- MOI slow to import and precompile HOT 4
- Improve performance of String names
- Reading .mps file with NAME HOT 2
- Add support for nonlinear sign(x) HOT 2
- Support for complex vector cones HOT 35
- Bug get/setting ConstraintSet with variable bridges HOT 9
- [FileFormats.CBF] add support for PSDVAR HOT 31
- Variational inequalities HOT 13
- [FileFormats.MPS] wrong result after parsing file HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mathoptinterface.jl.