# Relaxation of MIP in order to use getdual

Hey everyone,

I have a modular optimisation problem that can be LP or MIP depending on the setting. To get the shadow price I query via `JuMP.has_duals(model)` whether I can receive the shadow price with the corresponding JuMP (`JuMP.shadow_price`) function.

If this is not the case, I have found the possibility to relax the problem via various forum entries.
Unfortunately, I get this error with the following shadow price query:

However, it appears to me that there is a dual result…

I have already tried various solutions, including using relax_integrality(). Nevertheless, the error message remains the same. I’m using Gurobi as a Solver for both problems.

Here is the corresponding source code to relax the MIP:

``````"""
get_fixed_model(model::Model)
takes the MIP Problem and fixes all binary and integer variables to the solutions and returns a copy of the model.
"""
function get_fixed_model(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)
end
end
new_model = copy(model)
set_optimizer(new_model, Gurobi.Optimizer)
return new_model
end

"""
creates a fixed copy of the model, runs an optimization and calculates the shadow prices from this.
"""
fixed_model = get_fixed_model(model)
#undo = relax_integrality(fixed_model);
JuMP.optimize!(fixed_model)
end
``````

Please provide a reproducible example, including the definition of the model.

Here is a minimal example which shows the described behaviour. I hope this will help!

``````using JuMP
using Gurobi

# create dummy model
model = Model(Gurobi.Optimizer)
# setup variables, constraints and objective
@variable(model, x)
@variable(model, a, Bin)
@constraint(model, reference, a * 2 * x >= 1)
@objective(model, Min, x)
# optimize
JuMP.optimize!(model)
JuMP.has_duals(model) # should return false
# new fixed model
#### test with fixed binaries
fixed_model = get_fixed_model(model)
#### alternative test with relax_integrality
#=
fixed_model = copy(model)
set_optimizer(fixed_model, Gurobi.Optimizer)
undo = relax_integrality(fixed_model);
set_optimizer_attributes(fixed_model, "NonConvex" => 2)
=#
JuMP.optimize!(fixed_model)
JuMP.has_duals(fixed_model) # returns false but expected to return true

function get_fixed_model(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)
end
end
new_model = copy(model)
set_optimizer(new_model, Gurobi.Optimizer)
return new_model
end
``````

`reference` belongs to your original model, not the copied one.

Use `fixed_model[:reference]`, or modify the original model in place rather than creating a copy.

Unfortunately, the error still occurs even if I use the ‘fixed_model[:reference]’.
The same behaviour remains even if I adjust the model itself.

Ah. Your constraint has `a * 2 * x`. When you fix a variable it does not replace it with a constant.

You need to set Gurobi’s QCPDual parameter:

``````fixed_model = get_fixed_model(model)
set_optimizer_attribute(fixed_model, "QCPDual", 1)
optimize!(fixed_model)

julia> has_duals(fixed_model)
true