2

I have multiple objective functions for the same model in Julia JuMP created using an @optimize in a for loop. What does it mean to have multiple objective functions in Julia? What objective is minimized, or is it that all the objectives are minimized jointly? How are the objectives minimized jointly?

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 && 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))

zendevil
  • 899
  • 4
  • 13
  • 26
  • Please provide a link when cross-posting: https://discourse.julialang.org/t/what-is-the-meaning-of-multiple-objective-functions/51857. It avoids multiple people answering the same question. – Oscar Dowson Dec 15 '20 at 20:42

1 Answers1

2

With the standard JuMP you can have only one goal function at a time. Running another @objective macro just overwrites the previous goal function. Consider the following code:

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

It can be obviously seen that there is only one goal function left.

However, indeed there is an area in optimization called multi-criteria optimization. The goal here is to find a Pareto-barrier. There is a Julia package for handling MC and it is named MultiJuMP. Here is a sample code:

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())

This library also supports plotting of the Pareto frontier. The disadvantage is that as of today it does not seem to be actively maintained (however it works with the current Julia and JuMP versions).

Przemyslaw Szufel
  • 40,002
  • 3
  • 32
  • 62