#julia #julia-jump
#джулия #julia-jump
Вопрос:
У меня есть несколько целевых функций для одной и той же модели в Julia JuMP, созданных с использованием @optimize в цикле for . Что значит иметь несколько целевых функций в Julia? Какая цель минимизируется, или все цели сводятся к минимуму совместно? Как совместно минимизируются цели?
using JuMP
using MosekTools
K = 3
N = 2
penalties = [1.0, 3.9, 8.7]
function fac1(r::Number, i::Number, l::Number)
fac1 = 1.0
for m in 0:r-1
fac1 *= (i-m)*(l-m)
end
return fac1
end
function fac2(r::Number, i::Number, l::Number, tau::Float64)
return tau ^ (i l - 2r 1)/(i l - 2r 1)
end
function Q_r(i::Number, l::Number, r::Number, tau::Float64)
if i >= r amp;amp; l >= r
return 2 * fac1(r, i, l) * fac2(r, i, l, tau)
else
return 0.0
end
end
function Q(i::Number, l::Number, tau::Number)
elem = 0
for r in 0:N
elem = penalties[r 1] * Q_r(i, l, r, tau)
end
return elem
end
# discrete segment starting times
mat = Array{Float64, 3}(undef, K, N 1, N 1)
function Q_mat()
for k in 0:K-1
for i in 1:N 1
for j in 1:N 1
mat[k 1, i, j] = Q(i, j, convert(Float64, k))
end
end
return mat
end
end
function A_tau(r::Number, n::Number, tau::Float64)
fac = 1
for m in 1:r
fac *= (n - (m - 1))
end
if n >= r
return fac * tau ^ (n - r)
else
return 0.0
end
end
function A_tau_mat(tau::Float64)
mat = Array{Float64, 2}(undef, N 1, N 1)
for i in 1:N 1
for j in 1:N 1
mat[i, j] = A_tau(i, j, tau)
end
end
return mat
end
function A_0(r::Number, n::Number)
if r == n
fac = 1
for m in 1:r
fac *= r - (m - 1)
end
return fac
else
return 0.0
end
end
m = Model(optimizer_with_attributes(Mosek.Optimizer, "QUIET" => false, "INTPNT_CO_TOL_DFEAS" => 1e-7))
@variable(m, A[i=1:K 1,j=1:K,k=1:N 1,l=1:N 1])
@variable(m, p[i=1:K 1,j=1:N 1])
# constraint difference might be a small fractional difference.
# assuming that time difference is 1 second starting from 0.
for i in 1:K
@constraint(m, -A_tau_mat(convert(Float64, i-1)) * p[i] . A_tau_mat(convert(Float64, i-1)) * p[i 1] .== [0.0, 0.0, 0.0])
end
for i in 1:K 1
@constraint(m, A_tau_mat(convert(Float64, i-1)) * p[i] .== [1.0 12.0 13.0])
end
@constraint(m, A_tau_mat(convert(Float64, K 1)) * p[K 1] .== [0.0 0.0 0.0])
for i in 1:K 1
@objective(m, Min, p[i]' * Q_mat()[i] * p[i])
end
optimize!(m)
println("p value is ", value.(p))
println(A_tau_mat(0.0), A_tau_mat(1.0), A_tau_mat(2.0))
Комментарии:
1. Пожалуйста, укажите ссылку при перекрестной публикации: discourse.julialang.org/t /. … Это позволяет избежать того, чтобы несколько человек отвечали на один и тот же вопрос.
Ответ №1:
При стандартном переходе вы можете иметь только одну целевую функцию одновременно. Запуск другого @objective
макроса просто перезаписывает предыдущую целевую функцию. Рассмотрим следующий код:
julia> m = Model(GLPK.Optimizer);
julia> @variable(m,x >= 0)
x
julia> @objective(m, Max, 2x)
2 x
julia> @objective(m, Min, 2x)
2 x
julia> println(m)
Min 2 x
Subject to
x >= 0.0
Очевидно, что осталась только одна целевая функция.
Однако действительно существует область оптимизации, называемая многокритериальной оптимизацией. Цель здесь — найти барьер Парето. Существует пакет Julia для обработки MC, и он назван MultiJuMP
. Вот пример кода:
using MultiJuMP, JuMP
using Clp
const mmodel = multi_model(Clp.Optimizer, linear = true)
const y = @variable(mmodel, 0 <= y <= 10.0)
const z = @variable(mmodel, 0 <= z <= 10.0)
@constraint(mmodel, y z <= 15.0)
const exp_obj1 = @expression(mmodel, -y 0.05 * z)
const exp_obj2 = @expression(mmodel, 0.05 * y - z)
const obj1 = SingleObjective(exp_obj1)
const obj2 = SingleObjective(exp_obj2)
const multim = get_multidata(mmodel)
multim.objectives = [obj1, obj2]
optimize!(mmodel, method = WeightedSum())
Эта библиотека также поддерживает построение границы Парето.
Недостатком является то, что на сегодняшний день он, похоже, не поддерживается активно (однако он работает с текущими версиями Julia и JuMP).