Closed yakyak462 closed 4 years ago
Anonymous state variables aren't supported. There is an issue for a better error message though: https://github.com/JuliaOpt/JuMP.jl/issues/1938.
The bigger question is why you need a dict? Does it not suffice to go
@variable(subproblem, x[name=NAMES], SDDP.State, lower_bound=0, initial_value=0)
@blegat, is there a way to have anonymous JuMP extension variables?
The reason I was trying to use dictionaries is that I wanted "triangular indexing" (to use the language of the JuMP manual) as well as string indices. In my non-SDDP version of the program in Python, I used multi-layer dictionaries, e.g. varDict["A"]["B"]["X"]
. It wasn't clear to me how to do this with SparseAxisArrays. I also considered using tuple indices ("A", "B", "X")
, but this is also inconvenient because I frequently need to sum over some level [e.g. all ("A", "B", i)
variables must sum to something].
By the way -- thank you for your ongoing help.
Triangular indexing works with strings as well, so it should be possible.
using JuMP
m = Model()
A = ["a", "b"]
@variable(m, x[a = A, b=1:4, c=b:4])
JuMP.Containers.SparseAxisArray{VariableRef,3,Tuple{Any,Any,Any}} with 20 entries:
[a, 1, 1] = x[a,1,1]
[b, 1, 2] = x[b,1,2]
[a, 1, 2] = x[a,1,2]
[a, 3, 3] = x[a,3,3]
[a, 2, 4] = x[a,2,4]
[b, 2, 3] = x[b,2,3]
[b, 2, 2] = x[b,2,2]
[b, 2, 4] = x[b,2,4]
[a, 2, 3] = x[a,2,3]
[a, 1, 3] = x[a,1,3]
[b, 4, 4] = x[b,4,4]
[a, 2, 2] = x[a,2,2]
[b, 3, 3] = x[b,3,3]
[b, 3, 4] = x[b,3,4]
[a, 4, 4] = x[a,4,4]
[b, 1, 3] = x[b,1,3]
[b, 1, 1] = x[b,1,1]
[a, 1, 4] = x[a,1,4]
[b, 1, 4] = x[b,1,4]
[a, 3, 4] = x[a,3,4]
For reference: @https://github.com/JuliaOpt/JuMP.jl/issues/2052
I got above to mostly work by defining separate functions f, g @variable(m, x[a = A, b=f(a), c=g(a, b)])
.
The only other downside of this approach is that I need to do
@variable(m, x[a = A, b=f(a), c=g(a, b)], SDDP.State, initial_value = 0)
@variable(m, y[a = A, b=f(a), c=g(a, b)], SDDP.State, initial_value = 0)
@variable(m, z[a = A, b=f(a), c=g(a, b)], SDDP.State, initial_value = 0)
# Different constraints for x, y, z
Not the end of the world, but I was planning with the dictionaries to create a function to encapsulate this logic, which I don't know how to do with named JuMP variables. Namely, something like
function createVar(m, varName::String)
@variable(m, varName[a = A, b=f(a), c=g(a, b)], SDDP.State, initial_value = 0)
end
Does this work?
function create_variable(model, var_name)
x = @variable(
model,
[a = A, b=f(a), c=g(a, b)], SDDP.State,
initial_value = 0, base_name = "$var_name_$a_$b_$c")
model[Symbol(var_name)] = x
return x
end
It's not obvious that you need an encapsulating function for the sake of the three lines you have above. One reason that I haven't developed better support is that the number of state variables should be modest. Having x
, y
, and z
each be indexed by three things is starting to look a little scary in terms of what the algorithm can handle.
Thanks! A good to know about state variable constraints, may have to lower scope of problem. Will try it out.
A good to know about state variable constraints, may have to lower scope of problem. Will try it out.
Yes, try it out. It can be problem-specific as hit depends on a few things. The current library is only single-threaded. It's possible to write a parallel version which gives big speed-ups, but I don't have the development time at the moment.
A useful thing to remember is that SDDP works by approximating a convex function of the state-variables. If you have a lot of state variables, then we're approximating a high-dimensional function and that's computationally expensive.
Closing since this is an upstream issue.
Dear developers,
I reopen this issue because I would like to reuse the above but for a single variable only, such as: x = @variable( model, ?, SDDP.State, initial_value = 0, base_name = "$var_name")
the trick I found is to use x = @variable( model, _, SDDP.State, initial_value = 0, base_name = "$varname") unregister(model, :)
Are there more "clean ways"?
Why do you need anonymous state variables?
To create a flexible model where the model of each component is constructed "on-demand" based on external files, but the type of model is not known in advance.
Please open a new issue with a minimal working example of what you are trying to achieve and we can scope out what to do.
I want to store my state variables in dictionaries. In normal JuMP, you can store variables in dictionaries using anonymous variables. However, when I try this with SDDP, I think it is trying to interpret SDDP as a variable.
Am I misunderstanding something/is there a workaround?