Документация Engee

MathOptInterface.jl

Страница в процессе перевода.

MathOptInterface — это уровень абстракции Julia для взаимодействия с различными решателями математических задач оптимизации.

Установка: OptimizationMOI.jl

Чтобы использовать этот пакет, установите пакет OptimizationMOI:

import Pkg;
Pkg.add("OptimizationMOI");

Подробные сведения

На данный момент интерфейс Optimization для MathOptInterface реализует только общий именованный аргумент maxtime.

OptimizationMOI поддерживает аргумент mtkize, который принимает логическое значение (по умолчанию false), что позволяет автоматически генерировать символьные выражения. Это позволяет использовать любой бэкенд автоматического дифференцирования с решателями или интерфейсами, такими как AmplNLWriter, которым требуется граф выражений целевой функции и ограничений. В случае с AutoSymbolics adtype это всегда происходит автоматически.

Оптимизатор, поддерживающий API MathOptInterface, можно вызвать напрямую, если не требуется определять параметры оптимизатора.

Например, при использовании оптимизатора Ipopt.jl:

using OptimizationMOI, Ipopt
sol = solve(prob, Ipopt.Optimizer())

Параметры оптимизатора обрабатываются одним из двух способов. Они могут задаваться либо посредством OptimizationMOI.MOI.OptimizerWithAttributes(), либо как именованные аргументы функции solve.

Например, при использовании оптимизатора Ipopt.jl:

using OptimizationMOI, Ipopt
opt = OptimizationMOI.MOI.OptimizerWithAttributes(Ipopt.Optimizer,
    "option_name" => option_value, ...)
sol = solve(prob, opt)

sol = solve(prob, Ipopt.Optimizer(); option_name = option_value, ...)

Оптимизаторы

Ipopt.jl (MathOptInterface)

KNITRO.jl (MathOptInterface)

Juniper.jl (MathOptInterface)

  • Juniper.Optimizer

  • Juniper требует указания нелинейного оптимизатора в параметре nl_solver, причем это должен быть оптимизатор на основе MathOptInterface. Дополнительные сведения см. в документации по Juniper.

using Optimization, OptimizationMOI, Juniper, Ipopt
rosenbrock(x, p) = (p[1] - x[1])^2 + p[2] * (x[2] - x[1]^2)^2
x0 = zeros(2)
_p = [1.0, 100.0]

f = OptimizationFunction(rosenbrock, Optimization.AutoForwardDiff())
prob = Optimization.OptimizationProblem(f, x0, _p)

opt = OptimizationMOI.MOI.OptimizerWithAttributes(Juniper.Optimizer,
    "nl_solver" => OptimizationMOI.MOI.OptimizerWithAttributes(Ipopt.Optimizer,
        "print_level" => 0))
sol = solve(prob, opt)
retcode: Success
u: 2-element Vector{Float64}:
 0.9999999999999899
 0.9999999999999792

Использование целочисленных ограничений

Ниже показано, как использовать целочисленное линейное программирование в Optimization. Мы решим классическую задачу о рюкзаке с помощью Juniper.jl.

  • Juniper.Optimizer

  • Juniper требует указания нелинейного оптимизатора в параметре nl_solver, причем это должен быть оптимизатор на основе MathOptInterface. Дополнительные сведения см. в документации по Juniper.

  • Целочисленная область определения выводится на основе границ переменной:

    • Установка нижней границы, равной нулю, а верхней границы, равной единице, соответствует MOI.ZeroOne() или двоичной переменной решения.

    • Указание других границ или их отсутствие соответствует MOI.Integer().

v = [1.0, 2.0, 4.0, 3.0]
w = [5.0, 4.0, 3.0, 2.0]
W = 4.0
u0 = [0.0, 0.0, 0.0, 1.0]

optfun = OptimizationFunction((u, p) -> -v'u, cons = (res, u, p) -> res .= w'u,
    Optimization.AutoForwardDiff())

optprob = OptimizationProblem(optfun, u0; lb = zero.(u0), ub = one.(u0),
    int = ones(Bool, length(u0)),
    lcons = [-Inf;], ucons = [W;])

nl_solver = OptimizationMOI.MOI.OptimizerWithAttributes(Ipopt.Optimizer,
    "print_level" => 0)
minlp_solver = OptimizationMOI.MOI.OptimizerWithAttributes(Juniper.Optimizer,
    "nl_solver" => nl_solver)

res = solve(optprob, minlp_solver)
retcode: Success
u: 4-element Vector{Float64}:
 0.0
 0.0
 1.0
 0.0