While preparing the example below, I realised that I was actually using direct_model to initialise the model. This was necessary due to some additional adjustments of Gurobi. However, it is no longer needed. Switching to the Model constructor removes the bottleneck mentioned above. Still, I would be very interested in a more efficient solution here.
using JuMP, Gurobi
function main()
sto = TimerOutput()
var_1 = 1
var_2 = 1:100
var_3 = 1:10
var_4 = 1:144
var_5 = [:a]
var_6 = [1, 2, 3]
sets = Dict(
:A => [var_1],
:B => Dict(var_1 => collect(var_2)),
:C => Dict((i => collect(var_3) for i in var_2)...),
:D => collect(var_4),
:E => var_5,
:F => Dict(var_1 => [:b1, :b2, :b3]),
:G => Dict((j => var_6 for j in var_3)...),
:H => Dict((j => 100 + 10 * j) for j in var_3),
:I => Dict(((j, k) => 0.1 * k + 0.05 * j) for j in var_3 for k in var_6)
)
# model = Model(() -> Gurobi.Optimizer(GRB_ENV))
model = direct_model(Gurobi.Optimizer(GRB_ENV))
# variables
@variable(model, 0 <= X[sets[:A], i in sets[:B][var_1], j in sets[:C][i], t in sets[:D]] <= sets[:H][j])
@variable(model, 0 <= Y[sets[:A], n in sets[:E], br in sets[:F][var_1]] <= 100)
# expressions
@expression(model, Z[a in sets[:A], i in sets[:B][var_1], j in sets[:C][i], b in sets[:G][j], t in sets[:D]], X[a, i, j, t] * sets[:I][(j, b)])
@expression(model, W[a in sets[:A], n in sets[:E]], sum(Y[a, n, br] for br in sets[:F][var_1]))
# constraints
@constraint(model, U[a in sets[:A], b in var_6, t in sets[:D]], sum(Z[a, i, j, b, t] for i in sets[:B][var_1], j in sets[:C][i] if b in sets[:G][j]) == 0)
# ... a few moments later ...
calculated_parameter = 0.5
@expression(model, V[a in sets[:A], n in sets[:E]], calculated_parameter * W[a, n])
for a in sets[:A], t in sets[:D]
@timeit sto "get" constraint = constraint_object(model[:U][a, 1, t])
@timeit sto "del" delete(model, model[:U][a, 1, t])
@timeit sto "set" model[:U][a, 1, t] = @constraint(
model, constraint.func - V[a, :a] == 0.
)
end
print_timer(sto)
end
main()
With direct_model
:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Time Allocations
βββββββββββββββββββββββ ββββββββββββββββββββββββ
Tot / % measured: 42.1s / 93.1% 1.40GiB / 2.3%
Section ncalls time %tot avg alloc %tot avg
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
get 144 39.1s 99.7% 272ms 16.2MiB 49.9% 115KiB
set 144 105ms 0.3% 731ΞΌs 16.2MiB 50.0% 115KiB
del 144 16.1ms 0.0% 112ΞΌs 6.75KiB 0.0% 48.0B
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
With the Model
constructor:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Time Allocations
βββββββββββββββββββββββ ββββββββββββββββββββββββ
Tot / % measured: 2.97s / 0.8% 1.40GiB / 2.0%
Section ncalls time %tot avg alloc %tot avg
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
get 144 11.9ms 52.2% 82.4ΞΌs 12.3MiB 42.2% 87.2KiB
set 144 10.7ms 47.0% 74.3ΞΌs 16.7MiB 57.6% 119KiB
del 144 182ΞΌs 0.8% 1.26ΞΌs 38.7KiB 0.1% 275B
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ