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

查看:15
本文介绍了如何在 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 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屋!

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