Задачи линейной и целочисленной оптимизации
|
Страница в процессе перевода. |
Пример: краткосрочное финансирование
Ниже показано, как решить задачу линейной оптимизации с помощью оптимизатора HiGHS. Этот пример взят из документации по JuMP.
Краткосрочные денежные обязательства представляют постоянную проблему для корпораций. Давайте рассмотрим пример ситуации, чтобы лучше понять, в чем она заключается.
Возьмем следующие ежемесячные чистые потребности в денежных средствах, представленные в тысячах долларов.
| Месяц | Янв | Фев | Мар | Апр | Май | Июн |
|---|---|---|---|---|---|---|
Чистый объем денежных средств |
--150 |
--100 |
200 |
--200 |
50 |
300 |
Для удовлетворения этих финансовых потребностей наша гипотетическая компания обращается к различным источникам финансирования:
-
Кредитная линия: компания может использовать кредитную линию на сумму до 100 000 долларов по процентной ставке 1 % в месяц.
-
Выпуск биржевых облигаций: в любой из первых трех месяцев компания может выпустить 90-дневные биржевые облигации с общей процентной ставкой 2 % за три месяца.
-
Инвестиция излишков средств: излишки средств можно инвестировать под процентную ставку 0,3 % в месяц.
Задача состоит в том, чтобы определить наиболее выгодный способ использования этих источников финансирования так, чтобы размер доступных компании к концу июня средств был максимальным.
Для моделирования этой задачи введем следующие переменные решения:
-
u_i: сумма, которая берется по кредитной линии вi-й месяц. -
v_i: стоимость биржевых облигаций, выпущенных вi-й месяц. -
w_i: излишки средств вi-й месяц.
Необходимо учитывать следующие ограничения.
-
В каждом месяце поступление денежных средств должно быть равно их расходу.
-
Для обеспечения соблюдения лимита по кредитной линии должны быть установлены верхние границы для
u_i. -
Переменные решения
u_i,v_iиw_iдолжны быть неотрицательными.
Конечная цель — максимизировать капитал компании в июне, представленный переменной m.
using Optimization, OptimizationMOI, ModelingToolkit, HiGHS, LinearAlgebra
@variables u[1:5] [bounds = (0.0, 100.0)]
@variables v[1:3] [bounds = (0.0, Inf)]
@variables w[1:5] [bounds = (0.0, Inf)]
@variables m [bounds = (0.0, Inf)]
cons = [u[1] + v[1] - w[1] ~ 150 # Январь
u[2] + v[2] - w[2] - 1.01u[1] + 1.003w[1] ~ 100 # Февраль
u[3] + v[3] - w[3] - 1.01u[2] + 1.003w[2] ~ -200 # Март
u[4] - w[4] - 1.02v[1] - 1.01u[3] + 1.003w[3] ~ 200 # Апрель
u[5] - w[5] - 1.02v[2] - 1.01u[4] + 1.003w[4] ~ -50 # Май
-m - 1.02v[3] - 1.01u[5] + 1.003w[5] ~ -300]
@named optsys = OptimizationSystem(m, [u..., v..., w..., m], [], constraints = cons)
optsys = complete(optsys)
optprob = OptimizationProblem(optsys,
vcat(fill(0.0, 13), 300.0);
grad = true,
hess = true,
sense = Optimization.MaxSense)
sol = solve(optprob, HiGHS.Optimizer())
retcode: Success
u: 14-element Vector{Float64}:
100.0
100.0
100.0
100.0
100.0
50.0
8274.735079210432
195.09803921568627
0.0
8173.735079210433
8592.35432366375
8366.131386634737
0.0
0.0
Частично целочисленная нелинейная оптимизация
Мы выбрали пример из файла сведений Juniper.jl, чтобы продемонстрировать частично целочисленную нелинейную оптимизацию с помощью Optimization.jl. Задачу можно сформулировать следующим образом:
что подразумевает задачу максимизации двоичных переменных с целевой функцией в виде скалярного произведения v и u при квадратичном ограничении на u.
using Juniper, Ipopt
v = [10, 20, 12, 23, 42]
w = [12, 45, 12, 22, 21]
objective = (u, p) -> (v = p[1:5]; dot(v, u))
cons = (res, u, p) -> (w = p[6:10]; res .= [sum(w[i] * u[i]^2 for i in 1:5)])
optf = OptimizationFunction(objective, Optimization.AutoSymbolics(), cons = cons)
optprob = OptimizationProblem(optf,
zeros(5),
vcat(v, w);
sense = Optimization.MaxSense,
lb = zeros(5),
ub = ones(5),
lcons = [-Inf],
ucons = [45.0],
int = fill(true, 5))
nl_solver = OptimizationMOI.MOI.OptimizerWithAttributes(Ipopt.Optimizer,
"print_level" => 0)
minlp_solver = OptimizationMOI.MOI.OptimizerWithAttributes(Juniper.Optimizer,
"nl_solver" => nl_solver)
sol = solve(optprob, minlp_solver)
retcode: Success
u: 5-element Vector{Float64}:
0.0
0.0
0.0
1.0
1.0