如何在 Julia 中使用 JuMP 提取优化问题矩阵 A、b、c [英] How to extract optimization problem matrices A,b,c using JuMP in Julia
问题描述
我在 Julia-JuMP 中使用符号变量和约束创建了一个优化模型,例如下面
I create an optimization model in Julia-JuMP using the symbolic variables and constraints e.g. below
using JuMP
using CPLEX
# model
Mod = Model(CPLEX.Optimizer)
# sets
I = 1:2;
# Variables
x = @variable( Mod , [I] , base_name = "x" )
y = @variable( Mod , [I] , base_name = "y" )
# constraints
Con1 = @constraint( Mod , [i in I] , 2 * x[i] + 3 * y[i] <= 100 )
# objective
ObjFun = @objective( Mod , Max , sum( x[i] + 2 * y[i] for i in I) ) ;
# solve
optimize!(Mod)
我猜 JuMP 会以最小化 c'*x subj to Ax < 的形式产生问题.b 在传递给求解器 CPLEX 之前.我想提取矩阵 A,b,c.在上面的例子中,我希望是这样的:
I guess JuMP creates the problem in the form minimize c'*x subj to Ax < b before it is passes to the solver CPLEX. I want to extract the matrices A,b,c. In the above example I would expect something like:
A
2×4 Array{Int64,2}:
2 0 3 0
0 2 0 3
b
2-element Array{Int64,1}:
100
100
c
4-element Array{Int64,1}:
1
1
2
2
在 MATLAB 中,函数 prob2struct 可以做到这一点 https://www.mathworks.com/help/optim/ug/optim.problemdef.optimizationproblem.prob2struct.html
In MATLAB the function prob2struct can do this https://www.mathworks.com/help/optim/ug/optim.problemdef.optimizationproblem.prob2struct.html
有没有可以做到这一点的 JuMP 函数?
In there a JuMP function that can do this?
推荐答案
据我所知,这并不容易.
This is not easily possible as far as I am aware.
问题存储在底层 MathOptInterface
(MOI) 特定数据结构中.例如,约束总是存储为 MOI.AbstractFunction
- in - MOI.AbstractSet
.MOI.ObjectiveFunction
也是如此.(参见 MOI 文档:https://jump.dev/MathOptInterface.jl/dev/apimanual/#Functions-1)
The problem is stored in the underlying MathOptInterface
(MOI) specific data structures. For example, constraints are always stored as MOI.AbstractFunction
- in - MOI.AbstractSet
. The same is true for the MOI.ObjectiveFunction
. (see MOI documentation: https://jump.dev/MathOptInterface.jl/dev/apimanual/#Functions-1)
但是,您可以尝试以矩阵向量形式重新计算目标函数项和约束.
You can however, try to recompute the objective function terms and the constraints in matrix-vector-form.
例如,假设您仍有 JuMP.Model
Mod
,您可以通过键入以下内容来更仔细地检查 目标函数:
For example, assuming you still have your JuMP.Model
Mod
, you can examine the objective function closer by typing:
using MathOptInterface
const MOI = MathOptInterface
# this only works if you have a linear objective function (the model has a ScalarAffineFunction as its objective)
obj = MOI.get(Mod, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}())
# take a look at the terms
obj.terms
# from this you could extract your vector c
c = zeros(4)
for term in obj.terms
c[term.variable_index.value] = term.coefficient
end
@show(c)
这确实给出了:c = [1.;1.;2.;2.]
.
您可以对基础 MOI 执行类似的操作.约束.
You can do something similar for the underlying MOI.constraints.
# list all the constraints present in the model
cons = MOI.get(Mod, MOI.ListOfConstraints())
@show(cons)
在这种情况下,我们只有一种类型的约束,即 (MOI.ScalarAffineFunction{Float64}
in MOI.LessThan{Float64})
in this case we only have one type of constraint, i.e. (MOI.ScalarAffineFunction{Float64}
in MOI.LessThan{Float64})
# get the constraint indices for this combination of F(unction) in S(et)
F = cons[1][1]
S = cons[1][2]
ci = MOI.get(Mod, MOI.ListOfConstraintIndices{F,S}())
你得到两个约束索引(存储在数组 ci
中),因为这种组合 F - in - S 有两个约束.让我们仔细研究其中的第一个:
You get two constraint indices (stored in the array ci
), because there are two constraints for this combination F - in - S.
Let's examine the first one of them closer:
ci1 = ci[1]
# to get the function and set corresponding to this constraint (index):
moi_backend = backend(Mod)
f = MOI.get(moi_backend, MOI.ConstraintFunction(), ci1)
f
再次属于 MOI.ScalarAffineFunction
类型,它对应于 A = [a1; 中的一行
矩阵.该行由以下给出:a1
...;am]
f
is again of type MOI.ScalarAffineFunction
which corresponds to one row a1
in your A = [a1; ...; am]
matrix. The row is given by:
a1 = zeros(4)
for term in f.terms
a1[term.variable_index.value] = term.coefficient
end
@show(a1) # gives [2.0 0 3.0 0] (the first row of your A matrix)
获取你的b = [b1; 对应的第一个条目
向量,你得看下同一个约束索引b1
...;bm]ci1
的约束集:
To get the corresponding first entry b1
of your b = [b1; ...; bm]
vector, you have to look at the constraint set of that same constraint index ci1
:
s = MOI.get(moi_backend, MOI.ConstraintSet(), ci1)
@show(s) # MathOptInterface.LessThan{Float64}(100.0)
b1 = s.upper
我希望这能让您直观了解数据是如何以 MathOptInterface
格式存储的.
I hope this gives you some intuition on how the data is stored in MathOptInterface
format.
您必须对所有约束和所有约束类型执行此操作,并将它们作为行堆叠在约束矩阵 A
和向量 b
中.
You would have to do this for all constraints and all constraint types and stack them as rows in your constraint matrix A
and vector b
.
这篇关于如何在 Julia 中使用 JuMP 提取优化问题矩阵 A、b、c的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!