如何在Julia中使用JuMP提取优化问题矩阵A,b,c [英] How to extract optimization problem matrices A,b,c using JuMP in Julia

查看:106
本文介绍了如何在Julia中使用JuMP提取优化问题矩阵A,b,c的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用符号变量和约束在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最小化为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.LessThan{Float64})中的(MOI.ScalarAffineFunction{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; ...; am]矩阵中的一行a1.该行由以下内容给出:

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; ...; bm]向量的相应第一项b1,您必须查看相同约束索引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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆