I would like to make my Julia/JuMP code more flexible and prepare it for larger test cases. For this I would need to
- Read in data from a given directory
- Build a model based on it - here since the model is large and has different functional parts I would like to use separate functions for this
- Solve the model and extract key result data
- Write the results into file
- Change the directory and start again (in a loop)
So this should be done for about 100+ test cases… and would really need to do this type of testing in loops (automatically). What I already tried was to create a function
#function 1: basic math model
create variables and constraints
#function 2: add special variables and constraints
create some new variables and constraints - also involving already created variables
#later I want to optimize it and read and store the values in another function
But the main problem is that in function 2, it does not recognize the variables I created in function 1… and I get errors such as “type Model has no field x” What is the best way to deal with this? There are quite a few variables involved so it can get complex. I googled for help but it is not trivial to find solutions following the new format (JuMP 0.19).
Thankful for any tips!
This should work - I assume you are not accessing variables
x the right way. Suppose you want to add a knapsack constraint in your second function. You should use something like:
@constraint( m, dot(w, m[:x]) <= C )
At least it works like that with JuMP 0.18. If this is not your problem please provide a more specific example.
Thank you for the note! How would I then use multidimensional variables? For instance
for i = 1:50
for j =1:48
@constraint(m, x[i,j] <= MaxValue*y[j])
model = function1()
expanded_model = function2(model)
Here it is not clear to me if I could do it just like m[:x[i,j]]…
Thank you in advance!
I’m not sure, but I think that
@constraint(m, m[:x][i][j] <= MaxValue*y[j])
should work. At least if
x was one-dimensional you could access a single coordinate with
m[:x][i]. So if the first suggestion does not work you could also try it with
I think you should also be able to do
x = m[:x] and then use
x directly from then on.
What I do in my code is to return not only the model but also the variables from the function that creates them. When there are too many variables, I will create a
struct to hold all of them, e.g.:
https://github.com/rschwarz/PipeLayout.jl/blob/master/src/models/gndstruct_discdiam/itergbd.jl#L31-L46 (for JuMP v0.18).
I implemented the suggestion by leethargo and it works like a charm