Polyhedra.jl
Polyhedra.jl copied to clipboard
[feature] Support MOI.VectorAffineFunction
Would it be costly to support MOI.VectorAffineFunction
also?
https://github.com/JuliaPolyhedra/Polyhedra.jl/blob/3b289ddf7ab4c8626c87eaf8a42f0e73cc2d7e26/src/lphrep.jl#L3-L5
It is already supported through bridges:
https://github.com/JuliaPolyhedra/Polyhedra.jl/blob/3b289ddf7ab4c8626c87eaf8a42f0e73cc2d7e26/src/lphrep.jl#L21
full_bridge_optimizer
adds many bridges including http://www.juliaopt.org/MathOptInterface.jl/dev/apireference/#MathOptInterface.Bridges.ScalarizeBridge which transforms VectorAffineFunction
to ScalarAffineFunction
.
@blegat Thanks. My problem seems to be that I haven't been able to understand the manual of MOI...
To be concrete, consider the linear program max c x s.t. A x <= b, where
A = [1 1; -1 0; 0 -1]
b = [1, 0, 0]
c = [1, 0]
Let's use CDDLib.Optimizer
:
T = Float64 # or Rational{BigInt}
optimizer = CDDLib.Optimizer{T}()
x = MOI.add_variables(optimizer, length(c))
MOI.set(optimizer, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(),
MOI.ScalarAffineFunction{T}(MOI.ScalarAffineTerm{T}.(c, x), 0))
MOI.set(optimizer, MOI.ObjectiveSense(), MOI.MAX_SENSE)
I know the following works:
for i in 1:size(A, 1)
MOI.add_constraint(
optimizer,
MOI.ScalarAffineFunction{T}(
MOI.ScalarAffineTerm{T}.(A[i, :], x), 0
),
MOI.LessThan{T}(b[i])
)
end
MOI.optimize!(optimizer)
2-element Array{Float64,1}:
1.0
0.0
But it feels a bit stupid to pass the content of the matrix A
row by row, so I wanted to pass A
itself (along with b
) without decomposing it. Is it possible? The following doesn't work:
MOI.add_constraint(
optimizer,
MOI.VectorAffineFunction{T}(A, -b),
MOI.Nonpositives(length(b))
)
MethodError: no method matching Array{MathOptInterface.VectorAffineTerm{Float64},1}(::Array{Int64,2})
See this discourse post for how to formulate the constraint with VectorAffineFunction.
Ah sorry, I should have read that thread carefully.
Now the issue seems to be that MOI.Nonpositives
is not supported:
T = Float64 # or Rational{BigInt}
optimizer = CDDLib.Optimizer{T}()
x = MOI.add_variables(optimizer, length(c))
MOI.set(optimizer, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(),
MOI.ScalarAffineFunction{T}(MOI.ScalarAffineTerm{T}.(c, x), 0))
MOI.set(optimizer, MOI.ObjectiveSense(), MOI.MAX_SENSE)
terms = MOI.VectorAffineTerm{T}.(
1:size(A, 1), MOI.ScalarAffineTerm{T}.(A, reshape(x, 1, length(x)))
)
f = MOI.VectorAffineFunction{T}(vec(terms), -b)
MOI.add_constraint(optimizer, f, MOI.Nonpositives(size(A, 1)))
MathOptInterface.UnsupportedConstraint{MathOptInterface.VectorAffineFunction{Float64},MathOptInterface.Nonpositives}: `MathOptInterface.VectorAffineFunction{Float64}`-in-`MathOptInterface.Nonpositives` constraints is not supported by the model.
You should do optimizer = MOI.Bridges.full_bridge_optimiezr(CDDLib.Optimizer{T}(), T)
Great, that works now.
In PR #171 I added a description of the usage to the documentation.