Using anonymous and or symbols to create dynamic varible names?

Howdy, so I asked a question on stack overflow:julia - Define several JuMP variables names in loop based on iteration - Stack Overflow , and Oscar replied. I thought a bit more, and remember this board, and thought I’d see if this is possible by means of rephrasing the question.

I tried 2 ways: 1 seen below - define anonymous variables and then tried to use them in the objective (this did not work). Also I tried @variable(m,Symbol(“x$k”)[1:5],Bin), and this didn’t seen to work either. Are any of these ideas salvageable?

My final goal here was to be able to dynamically be able to create variable names, and assign properties to them like I would ussually, and then use them how one would in JuMP - instead of hard coding x1,x2…xn, make a loop and sort of do what I tried with the Symbol("x$k).

Thank you.

import JuMP


using Juniper
using Ipopt
using LinearAlgebra 
using Base.Threads
using Cbc

function obj(list)
    sum=0.0
    for k=1:length(list)
        println(list[k])
        sum = sum + sum(list[k])
    end
    return sum
end

optimizer = Juniper.Optimizer
nl_solver= optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0)
mip_solver = optimizer_with_attributes(Cbc.Optimizer, "logLevel" => 0, "threads"=>nthreads())
m = Model(optimizer_with_attributes(optimizer, "nl_solver"=>nl_solver, "mip_solver"=>mip_solver))
var_type = ["b","r","b"]
var_list=[]
for k=1:length(var_type)


if(var_type[k]=="b")
    x_k = @variable(m,[1:5],Bin)
end
if(var_type[k]=="r")
    x_k = @variable(m,[1:5])
end
append!(var_list,[x_k])
end

@objective(m, Min, obj(var_list))
optimize!(m)
for k=1:length(list)
    optimal_solution = value.(var_list[k])
    println(optimal_solution)

end
1 Like

From my answer on SO:

in no case can you dynamically create a binding like x_i

By this I really mean it. Don’t try interpolating expressions into the macros, don’t use Symbol(...), and don’t use eval (not that you have, but people have tried this in the past).

What you should do instead is create an appropriate data structure to hold the variables. That might be a Vector, a Dict, or some user-defined struct, but the choice is problem-dependent.

In your case, I would do something like this:

types = ["b","r","b"]

model = Model()
var_list = [
    @variable(model, [1:5], binary = t == "b") for t in types
]

model = Model()
@variable(model, var_list[t=1:3, [1:5]], binary = types[t] == "b")

Edit: “I thought a bit more, and remember this board” Great :smile: I prefer discourse for back-and-forth discussion. Conversations on SO can get shut-down by the mods.

3 Likes