gpt4 book ai didi

matrix - 如何在 Julia 中使用 JuMP 提取优化问题矩阵 A,b,c

转载 作者:行者123 更新时间:2023-12-02 19:22:56 24 4
gpt4 key购买 nike

我使用符号变量和约束在 Julia-JuMP 中创建了一个优化模型,例如下面

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 在传递给求解器 CPLEX 之前以最小化 c'*x subj to Ax < b 的形式创建问题。我想提取矩阵A,b,c。在上面的示例中,我期望类似的内容:

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

有没有 JuMP 函数可以做到这一点?

最佳答案

据我所知,这并不容易实现。

问题存储在底层 MathOptInterface (MOI) 特定数据结构中。例如,约束始终存储为 MOI.AbstractFunction - in - MOI.AbstractSetMOI.ObjectiveFunction 也是如此。 (参见 MOI 文档:https://jump.dev/MathOptInterface.jl/dev/apimanual/#Functions-1)

但是,您可以尝试以矩阵向量形式重新计算目标函数项和约束。

例如,假设您仍然拥有 JuMP.Model Mod,您可以通过键入以下内容来更仔细地检查目标函数:

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 执行类似的操作。约束

# list all the constraints present in the model
cons = MOI.get(Mod, MOI.ListOfConstraints())
@show(cons)

在这种情况下,我们只有一种类型的约束,即 (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 有两个约束。让我们仔细研究一下其中的第一个:

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] 矩阵。该行由以下公式给出:

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的约束集:

s = MOI.get(moi_backend, MOI.ConstraintSet(), ci1)
@show(s) # MathOptInterface.LessThan{Float64}(100.0)
b1 = s.upper

我希望这能让您对如何以 MathOptInterface 格式存储数据有一些直观的了解。

您必须对所有约束和所有约束类型执行此操作,并将它们作为行堆叠在约束矩阵 A 和向量 b 中。

关于matrix - 如何在 Julia 中使用 JuMP 提取优化问题矩阵 A,b,c,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62800012/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com