Using anonymous and or symbols to create dynamic variable names?

Hello,
I’m resurrecting this 2022 thread because I’d like to be sure what you mean by “I really mean it” :wink:

Indeed, I read the JuMP doc section Design patterns for larger models (that you mentioned in another question related to variable name collision How to merge two `JuMP` models?) but also the very useful String names, symbolic names, and bindings section and at the end it says:

  • You can manually register names in the model via model[:key] = value

So my question is the following: in the context of a multi-stage optimization problem where each stage contains about the same variables and contraints, I’d be tempted to dynamically forge variable names like: variable x for stage 1 should be x1

Using anonymous variables + Dict containers (with names as keys), I can get such variables defined (and the String name attribute can be freely set as a bonus).

However, I’ve also tested the idea of manual registration using a dynamically created Symbol(variable_name). I understand that it’s not needed since I can already access variables in my Dicts, but this dynamic registration does work, so that’s why I’m asking your advice: is the manual registration of dynamically created Symbols:

  • a bad practice (due to potential name clashes)?
  • or it can seriously break some lower level JuMP layers?

Here is a code example to illustrate: I want to have variable x1 and x2 created dynamically:

using JuMP
using HiGHS

"add variable `name` to model `m` and to Dict `dat`, for optional `stage`"
function add_stage_variable!(m::Model, dat::Dict{String,Any}, name::String; stage="")
    name_suffix = "$name$stage"
    dat[name] = @variable(m, base_name=name_suffix) # here I can use name or name_suffix
    # Optional last line: finish the job by registering variable as name_suffix????
    m[Symbol(name_suffix)] = dat[name]
end

m = Model(HiGHS.Optimizer)
set_silent(m)
data1 = Dict{String,Any}() # container for 1st stage variables
data2 = Dict{String,Any}() # container for 2nd stage variables
add_stage_variable!(m, data1, "x"; stage=1)
add_stage_variable!(m, data2, "x"; stage=2)

and the end of this code, data1 gets printed as Dict{String, Any}("x" => x1). In fact, by modifying add_stage_variable!, it could have been "x" => x1, "x1" => x1, "x1" => x or "x" => x depending on taste, since there is no risk of clash with the content of data2.

And the model m prints as:

A JuMP Model
Feasibility problem with:
Variables: 2
Model mode: AUTOMATIC
CachingOptimizer state: EMPTY_OPTIMIZER
Solver name: HiGHS
Names registered in the model: x1, x2

and that last line disappears if I comment out the last line of add_stage_variable! function.

1 Like