Hello to all. I’m trying to solve some generation schedule problem and we need access to the dual variables for pricing. The problem is MILP and, since the dual variables are no available, we used some suggestion to fix integers and solving again (code below). This works fine for GLPK, but for example Cbc is not a LP solver, so we had to change to Clp solver. The problem we have is that when Clp initializes with the previous model, the MIP parameters are copied creating an exception in Clp.
I guess our questions are 2:

Is there a better way to solve the fixed problem? I know solvers like Xpress or Cplex have an API to do this in 1 instruction. But how to do it in JuMP?

How can we “remove” (or ask not to copy) these MIP parameters from model so CLP doesn’t throw an exception?
Thank you all

function solve_fixed_model!(model)
for v in all_variables(model)
if is_binary(v)
unset_binary(v)
val_v = JuMP.value(v)
set_lower_bound(v, val_v)
set_upper_bound(v, val_v)
end
end
JuMP.set_optimizer(model, Clp.Optimizer)
JuMP.optimize!(model)
end`

using JuMP, Cbc, Clp
function fix!(model::Model)
solution = Dict(
v => value(v) for v in all_variables(model)
)
for v in all_variables(model)
if is_binary(v)
unset_binary(v)
fix(v, solution[v]; force = true)
end
end
return
end
model = Model(Cbc.Optimizer)
@variable(model, x, Bin)
@objective(model, Max, 2 * x)
optimize!(model)
fix!(model)
set_optimizer(model, Clp.Optimizer)
optimize!(model)
dual(FixRef(x))

Thanks a lot @odow! Yes, it’s very similar but if you introduce a Cbc’s parameter you can’t “undo” that parameter. In other words, if you see in a copy of your own code below, I have only introduced a parameter “ratioGap”. And you can reproduce that function set_optimizer(model, Clp.Optimizer) throws an exception: “ERROR: LoadError: MathOptInterface.UnsupportedAttribute{MathOptInterface.RawParameter}(MathOptInterface.RawParameter(“ratioGap”), “”)”

It seems like when Clp initializes, it copies Cbc-specific parameters from model (and thus creating the exception). Any idea how to “remove” the Cbc-specific parameters from model so Clp can run?
Thanks a lot!

using JuMP, Cbc, Clp
function fix!(model::Model)
solution = Dict(
v => value(v) for v in all_variables(model)
)
for v in all_variables(model)
if is_binary(v)
unset_binary(v)
fix(v, solution[v]; force = true)
end
end
return
end
model = Model(Cbc.Optimizer)
set_optimizer_attribute(model, "ratioGap", 0.001) # <-CBC PARAMETER
@variable(model, x, Bin)
@objective(model, Max, 2 * x)
optimize!(model)
fix!(model)
set_optimizer(model, Clp.Optimizer)
optimize!(model)
dual(FixRef(x))

Thanks a lot @metab0t
It is very useful the relax_integrality(model) function. It works great with GLPK (as I mentioned). But not with Cbc because it does not compute the dual values. So that’s why we had to switch to Clp to solver the relaxed problem but the it throws an error if you (previously) introduced a Cbc-specific parameter. I guess there must be a way to tell Clp to ignore solver’s parameters but I haven’t figured out how.

model = Model()
set_optimizer(model, optimizer_with_attributes(Cbc.Optimizer, "ratioGap"=>0.001))
...
...

It seems that optimizer_with_attributes set the attributes to the Cbc.Optimizer directly while set_optimizer_attribute will cache the attribute in model.

Hello. I am trying to fix my MILP model with a simple instruction. Have you ever found a built-in function to do that? fixed_model(model) was supposed to work, but it gives an error, which I do not understand. I would really appreciate your help.

It works on my actual model. Thank you again for your suggestions. For reference, I have the following function:

function FixModel!(model::Model)
solution = Dict(
v => value(v) for v in all_variables(model)
)
for v in all_variables(model)
if is_binary(v)
unset_binary(v)
fix(v, solution[v]; force = true)
elseif is_integer(v)
unset_integer(v)
fix(v, solution[v]; force = true)
else
nothing
end
end
return
end