Write expressions in JuMP model based on condition

I want to add serval named expressions in a JuMP model that are conditional on the indices p (set P) and t (set T). X and I are the decision variable and set P consists of two subsets, P_1, P_2. I want the expressions to be named to be able to use them later on. After adding the expression “ex” for the first subset P_1, I am not able to add the expression for the second subset because I receive the following error:

ERROR: An object of name ex is already attached to this model.

How can I avoid this error and add the expression conditional on index value? Here is a MWE:

using JuMP, HiGHs

P_1 = ["a", "b", "c"]
P_2 = ["d", "e"]
P = vcat(P_1, P_2)
T = 1:10

model = JuMP.Model(HiGHs.Optimizer)

@variables model begin
    X[P,T], Bin
    I[P,T] >= 0
end

@expression(model, ex[p=P_1, t=T], I[p,t] * 5)
@expression(model, ex[p=P_2, t=T], I[p,t] * 7) 

Hi @mast-lfl, welcome to the forum.

Correct. You cannot define an expression with the same name twice. Take a read of Variables · JuMP (it is in the variables, section, but it applies equally to expressions).

One approach would be to write your model as:

@expression(
    model,
    ex[p=P, t=T],
    if p in P_1
        I[p,t] * 5
    else
        I[p,t] * 7
    end,
)

Another approach would be:

@expression(model, ex[p=P, t=T], I[p,t] * (p in P_1 ? 5 : 7))

Another approach would be:

data = Dict("a" => 5, "b" => 5, "c" => 5, "d" => 7, "e" => 7)
@expression(model, ex[p=P, t=T], I[p,t] * data[p])

This hints at the strength and weakness of JuMP: we are flexible in how to write things, but because there is more than one way it can be hard to know (or document) what is the “best.” The answer is problem-dependent.

1 Like