How to merge two `JuMP` models?

For example, there are two JuMP models named M1 and M2:

using JuMP

M1 = Model()
@variable(M1, x <= 3)
@variable(M1, y <= 3)
@objective(M1, Max, x + y)

M2 = Model()
@variable(M2, x >= 1)
@variable(M2, y >= 1)
@constraint(M2,  x + y <= 3)

How to merge M2 into M1, and if they have variables with the same names, rename the corresponding variables from M2 (except the variable is x)?

Thanks!

1 Like

I don’t know about JuMP.jl specifically, however I’ll note that JuMP is just a convenient higher-level interface for MathOptInterface.jl, and the latter might be better suited for your needs if you’re having these kinds of issues. Personally I never use JuMP, instead relying on MOI directly.

2 Likes

Just so I understand your problem, how exactly this would work? Only one of the models has an objective function? (Otherwise, you would need some way to merge objective functions.) But if only the variables of one model appear in the objective function, and the variables of the two models are disjunct (you rename so they are not the same), then what you have in reality is really two models (not one).

2 Likes

Could you elaborate a bit on what this should mathematically mean?
As far as I understand you would like to rename the x in M2 “before marging”. So let’s call it z.

If I would “merge” these into M1, I would still be able to choose y and (now) z freely, since the objective does only depend on (M1s) x.
So that merge would mathematically have zero effect compared to just considering M1.

1 Like

I’m very sorry for not expressing my intention correctly. :pray: :pray: I have edited the OP.

You cannot merge two JuMP models, and there is no work-around.

At a higher level, what are you trying to achieve? Why do you need to build to models and then merge them?

3 Likes

For example, there may be a main model that is open to the user to allow them to add some other constraints w.r.t. some certain variable such as the model M1 and the variable x in the OP.

Perhaps it can be written within the following function:

using JuMP

function fun(M2::Moldel)
    M1 = Model()
    @variable(M1, x <= 3)
    @variable(M1, y <= 3)
    @objective(M1, Max, x + y)

    # Merge M2 into M1 here.

    optimize!(M1)
    return value(x)
end

Of course, I can’t expect how the users would model the constraints w.r.t. x. Maybe they would introduce other variables like y as auxiliary variables. But do you think it would be the developer’s duty to make sure the auxiliary variables from the input model (M2) don’t conflict with the internal main model (M1)?

Won’t that be a legitimate need, or will there be any work-around?

Thanks for your attention.

You could write your example as:

function fun(M::Model)
    x, y = M[:x], M[:y]
    @objective(M, Max, x + y)
    optimize!(M)
    return value(x)
end

But do you think it would be the developer’s duty to make sure the auxiliary variables from the input model (M2 ) don’t conflict with the internal main model (M1 )?

Yes. JuMP supports anonymous variables for this use-case.

function fun(M::Model)
    x = M[:x]
    y = @variable(M, upper_bound = 3)
    # This y is not the other y
    @objective(M, Max, x + y)
    optimize!(M)
    return value(x)
end

You should read the tutorial:

4 Likes