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

SciPy.jl

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

SciPy — это развитая библиотека Python, предлагающая обширное семейство алгоритмов оптимизации, поиска корней и линейного программирования. OptimizationSciPy.jl предоставляет доступ к этим подпрограммам через унифицированный интерфейс Optimization.jl, как и к любому собственному оптимизатору Julia.

Note Пакет OptimizationSciPy.jl использует PythonCall. При первом использовании минимальный дистрибутив Python с SciPy устанавливается автоматически, поэтому настраивать Python вручную не требуется.

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

import Pkg
Pkg.add("OptimizationSciPy")

Методы

Ниже приведен перечень семейств решателей, предоставляемых OptimizationSciPy.jl, вместе с их удобными конструкторами. Все они принимают обычные именованные аргументы maxiters, maxtime, abstol, reltol, callback, progress в дополнение к относящимся к SciPy параметрам (передаваемым в функцию solve в точности через именованные аргументы).

Локальный оптимизатор

Без вычисления производных

  • ScipyNelderMead() — симплексный алгоритм Нелдера — Мида

  • ScipyPowell() — поиск Пауэлла по сопряженным направлениям

  • ScipyCOBYLA() — линейная аппроксимация ограничений (поддерживает нелинейные ограничения)

На основе градиента

  • ScipyCG() — нелинейный сопряженный градиент

  • ScipyBFGS() — квазиньютоновский алгоритм BFGS

  • ScipyLBFGSB() — алгоритм BFGS с ограниченной памятью и простыми границами

  • ScipyNewtonCG() — ньютоновский сопряженный градиент (требуются произведения гессиана на вектор)

  • ScipyTNC() — усеченный метод Ньютона с границами

  • ScipySLSQP() — последовательное программирование методом наименьших квадратов (поддерживает ограничения)

  • ScipyTrustConstr() — метод доверительной области для нелинейных ограничений

На основе гессиана или с доверительной областью

  • ScipyDogleg(), ScipyTrustNCG(), ScipyTrustKrylov(), ScipyTrustExact() — алгоритмы доверительной области, возможно, с использованием или созданием информации о гессиане

Глобальный оптимизатор

  • ScipyDifferentialEvolution() — дифференциальная эволюция (требуются границы)

  • ScipyBasinhopping() — локально-прыжковая оптимизация (Basin-Hopping)

  • ScipyDualAnnealing() — алгоритм имитации отжига с двойным отжигом

  • ScipyShgo() — глобальная оптимизация симплициальной гомологии (поддерживает ограничения)

  • ScipyDirect() — детерминированный алгоритм DIRECT (требуются границы)

  • ScipyBrute() — поиск по сетке методом перебора (требуются границы)

Линейное и частично целочисленное программирование

  • ScipyLinprog("highs") — решатели линейного программирования из проекта HiGHS и устаревшие методы внутренней точки / симплекса

  • ScipyMilp() — частично целочисленное линейное программирование методом ветвей и границ HiGHS

Нахождение корней и нелинейный метод наименьших квадратов (экспериментальная функция)

Поддержка ScipyRoot, ScipyRootScalar и ScipyLeastSquares доступна в неявном виде и будет задокументирована после приведения API в устойчивую форму.

Примеры

Минимизация без ограничений

using Optimization, OptimizationSciPy

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.AutoZygote())
prob = OptimizationProblem(f, x0, p)

sol = solve(prob, ScipyBFGS())
@show sol.objective   # ≈ 0 в точке оптимума
7.717288356613562e-13

Оптимизация с ограничениями с помощью COBYLA

using Optimization, OptimizationSciPy

# Целевая функция
obj(x, p) = (x[1] + x[2] - 1)^2

# Единственное нелинейное ограничение: x₁² + x₂² ≈ 1 (с небольшим допуском)
cons(res, x, p) = (res .= [x[1]^2 + x[2]^2 - 1.0])

x0 = [0.5, 0.5]
prob = OptimizationProblem(
    OptimizationFunction(obj; cons = cons),
    x0, nothing, lcons = [-1e-6], ucons = [1e-6])  # Небольшой допуск вместо точного равенства

sol = solve(prob, ScipyCOBYLA())
@show sol.u, sol.objective
([0.9999995099640485, 1.1653740143742524e-5], 1.2462829129061485e-10)

Дифференциальная эволюция (глобальная) с пользовательскими параметрами

using Optimization, OptimizationSciPy, Random, Statistics
Random.seed!(123)

ackley(x, p) = -20exp(-0.2*sqrt(mean(x .^ 2))) - exp(mean(cos.(2π .* x))) + 20 + ℯ
x0 = zeros(2)                    # начальное предположение при дифференциальной эволюции игнорируется
prob = OptimizationProblem(ackley, x0; lb = [-5.0, -5.0], ub = [5.0, 5.0])

sol = solve(prob, ScipyDifferentialEvolution(); popsize = 20, mutation = (0.5, 1))
@show sol.objective
4.440892098500626e-16

Передача параметров, относящихся к решателю

Все именованные аргументы, не распознанные пакетом Optimization.jl, передаются напрямую в SciPy. Полный список параметров см. в документации по API оптимизации SciPy.

sol = solve(prob, ScipyTrustConstr(); verbose = 3, maxiter = 10_000)

Устранение неполадок

Исходный объект результата Python прикрепляется к решению в поле original:

sol = solve(prob, ScipyBFGS())
println(sol.original)  # SciPy OptimizeResult

Если SciPy выдает ошибку, она выдается повторно как исключение Julia ErrorException с сообщением из Python, поэтому сначала обратите внимание на него.

Сотрудничество

Сообщения об ошибках и запросы функций оставляйте в системе отслеживания ошибок Optimization.jl. Приветствуются любые запросы на вытягивание, улучшающие оболочку Julia или документацию.