MathOptInterface and MultiObjectiveAlgorithms functionality to implement a multiobjective algorithm (AUGMECON)

Hi.

I’m currently working on adapting an AUGMECON implementation in JuMP to use the MultiObjectiveAlgorithms module as its base. As part of this process, I’m adjusting AUGMECON to follow the MOA structure and implementing the tests from the MOA package (only the basic tests, not those from vOptLib). However, I’m encountering a couple of errors trying to do so.

The first issue appears in test_vectornonlinearfunction (MOA). The AUGMECON method requires adding the sum of the surplus variables (s_i) to the main objective:

\max f_1 + \epsilon \sum_{i=2}^p \frac{s_i}{r_i}

The problem is that I’m trying to add a ScalarAffineFunction (the surplus sum) to a ScalarNonlinearFunction (f_1) as following:

    objective_term = -algorithm.penalty * sum(surplus_variables[o-1] / (ranges_set[o][1] - ranges_set[o][end]) for o in 2:m)

    MOI.set(inner, MOI.ObjectiveFunction{typeof(objs_set[1])}(), objs_set[1] + objective_term)

Which produces the error when I run the test_vectornonlinearfunction test from MOA:

MethodError: no method matching +(::MathOptInterface.ScalarNonlinearFunction, ::MathOptInterface.ScalarAffineFunction{Float64})

I looked at other algorithms implemented in MOA, but I still couldn’t find a clear way to construct a valid expression that combines f_1 with the sum of the surplus variables.

Also, for S-AUGMECON, I have \max f_1 + \epsilon \sum_{i=2}^p \frac{f_i}{r_i}. If the objective functions have different types, I anticipate that the same bug will appear. Would be the same solution than for AUGMECON?

The second issue is related to the time limit. Even when I set a time limit, the solver still runs until the problem is fully solved, apparently ignoring the limit:

MOI.set(model, MOI.TimeLimitSec(), 0.0).

I checked other algorithms in MOA and didn’t notice anything specific related to setting or enforcing time limits, so I assumed that this was something handled automatically rather than within the algorithm implementation. However, in my case it doesn’t seem to be working.

Could someone help me understand what might be missing in these two cases?

1 Like

Hi @Josa9321, please open an issue (or better yet, a pull request, don’t worry if it is only half-finished and not working) in MultiObjectiveAlgorithms.jl. It’ll be easier to discuss there.

objective_term = -algorithm.penalty * sum(surplus_variables[o-1] / (ranges_set[o][1] - ranges_set[o][end]) for o in 2:m)

The main issue is that you can’t use Julia’s operator overloading to construct expressions like this.

You need to do something like:

sum_terms = map(2:m) do o
    return MOI.ScalarAffineTerm{Float64}(
        -algorithm.penalty / (ranges_set[o][1] - ranges_set[o][end]),
        surplus_variables[o-1],
    )
end
objective_term = MOI.ScalarAffineFunction(sum_terms, 0.0)
new_obj = MOI.Utilities.operate(+, Float64, objs_set[1], objective_term)
MOI.set(inner, MOI.ObjectiveFunction{typeof(new_obj)}(), new_obj)

The second issue is related to the time limit. Even when I set a time limit, the solver still runs until the problem is fully solved, apparently ignoring the limit:

Are you calling _check_premature_termination(model)?