say, I have a (pretty useless - just to illustrate the problem) MIP model in JuMP
using JuMP
using Cbc
model = Model(Cbc.Optimizer)
@variable(model, x[1:100000, 1:10, 1:2], Bin)
@constraint(model, c[i=1:100000], sum(x[i,:,:]) == 1)
The model solves. What I want to do now is to find out, which items in x are 1. My (most likely wrong) approach is to loop through the values of x:
for i in 1:100000
for j in 1:10
for k in 1:2
if value(model[:x][i,j,k]) == 1
println("Yippie!")
end
end
end
end
While this works in principle, it takes forever. In fact, it takes much much longer to extract the result from the model than to solve it (8 seconds for solving, more than 20 minutes for result extraction). Therefore I think, that I’m doing something fundamentally wrong. What is the best way to find the value with a 1 in x after the model has been solved?
Ideally, JuMP.jl should offer some way to query values from a list of variables simultaneously. I have discussed this with @odow in the past but I do not remember if it was ever implemented (or it was only implemented for deletion, that was my problem at the time).
However, I also have the feeling that you are iterating the matrix in the worst order (inner to outer instead of outer to inner), you can try reversing the nesting of the loops (so the innermost loop is i and the outermost is k), or use axes (or any other function that gives your all the indexes, like CartesianIndices). This should you some time if the matrix is large and page faults are frequent.
Finally, println is slow, I believe your example is not representative of your real problem, but printing a line (and not to a temporary buffer but directly to the output) is probably even slower than retrieving the value.