2

I’m trying to be able to use values put in a Dictionary to weight the variables that are going to be minimized in a JuMP objective function.

The dictionnary is implemented as follow :

Dicopond = Dict(0=> 1, 1 => 2, 2 => 4, 3 => 8, 4 => 16, 5 => 32, 6 => 64, 7 => 128)

The variable :

@variable(model, absolute[y=1:10])

And the objective function :

@objective(model, Min, sum((absolute[y])*Dicopond[(absolute[y])] for y=1:10))

Absolute[y] will only take the values between 0 and 7.

However, I get the Error “LoadError: KeyError: key absolute[1] not found in expression starting at…”

Is there a way to make the dictionnary get the actual value that will be assigned to absolute[y] ?

I’ve tried different ways to be able to put a weight to the decision variable and this was the one that seemed to be the most likely to work.

Thank you for your help!

EDIT : Cross-posted on : https://discourse.julialang.org/t/use-dictionary-value-in-objective-function/59119

rox
  • 21
  • 2

1 Answers1

1

Since your absolute variable for each y=1:10 can take values from 0 to 7. You need to convert it into a binary indicator variable (and hence for each absolute[y] you need to have 8 levels).

Hence your model needs to be rewritten to (node that for each y=1:10 the indicator variable needs to sum to 1):

model = Model(optimizer_with_attributes(Cbc.Optimizer, "Sec"=>480.0))
discopond = Dict(0=> 1, 1 => 2, 2 => 4, 3 => 8, 4 => 16, 5 => 32, 6 => 64, 7 => 128)
@variable(model, absolute[y=1:10, d=0:7],Bin)
@constraint(model,[y=1:10], sum(absolute[y, :])==1)
@objective(model, Min, sum( sum(d*absolute[y,d]*discopond[d] for d in 0:7) for y=1:10))
optimize!(model)
Przemyslaw Szufel
  • 40,002
  • 3
  • 32
  • 62
  • @rox Please provide a link when cross-posting: https://discourse.julialang.org/t/use-dictionary-value-in-objective-function/59119. It avoids this situation where we both answer at the same time in two places. – Oscar Dowson Apr 12 '21 at 20:30
  • @OscarDowson Sorry ! Will do. i'm new to posting questions on forums. – rox Apr 13 '21 at 13:27
  • @Przemyslaw Szufel Thank you for your reply ! I deleted the "d*" in sum( sum(d*absolute[y,d]*discopond[d] for d in 0:7) for y=1:10), as it multiplies unnecessarily the sum if i'm not mistaken ? And may I ask what's the "Sec"=480.00 ? I didn't manage to find any doc with it. Sadly, my code won't find a solution with theses modification but you put me in the good direction. Thank you for your help ! – rox Apr 13 '21 at 14:58
  • The exact model specs depends on your needs - I do not know your model and your optimization. However, replacing a variable with a binary one is very standard practice so you can easily find many examples. `"Sec"=>480.0` is an upper time limit for `Cbc`. I always use time liimits when working with solvers - it is just a good practice. – Przemyslaw Szufel Apr 13 '21 at 15:04
  • @Przemyslaw Szufel Alright thank you ! I was using maxNodes and maxSolutions up till now, the Sec seems less quality-damaging. I'll find a way to make my implementation work with that ! Thank you a lot, have a nice day. – rox Apr 13 '21 at 15:16