Как извлечь матрицы задач оптимизации A, b, c с помощью JuMP в Julia - PullRequest
1 голос
/ 08 июля 2020

Я создаю модель оптимизации в Julia-JuMP, используя переменные symboli c и ограничения, например, ниже

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 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, которая может выполнять это?

Ответы [ 2 ]

4 голосов
/ 08 июля 2020

Насколько мне известно, это сделать нелегко.

Проблема хранится в базовых структурах данных MathOptInterface (MOI) specifici c. Например, ограничения всегда сохраняются как MOI.AbstractFunction - in - MOI.AbstractSet. То же самое и с MOI.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} в 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, что соответствует одной строке a1 в вашей A = [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)

Чтобы получить соответствующую первую запись b1 вашего b = [b1; ...; bm] вектора, вы должны посмотреть на набор ограничений того же индекса ограничения ci1:

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

Надеюсь, это даст вам некоторое представление о том, как данные хранятся в формате MathOptInterface.

Вам нужно будет сделать это для всех ограничений и всех типов ограничений и сложить их в виде строк в вашей матрице ограничений A и векторе b.

0 голосов
/ 11 июля 2020

Сам не пробовал. Но пакет MathProgBase, похоже, может предоставить A, b и c в матричной форме.

...