Skip to content

Commit 0372302

Browse files
authored
[docs] add round_and_repair_heuristic in tolerances tutorial (#4115)
1 parent 8cd4504 commit 0372302

2 files changed

Lines changed: 29 additions & 2 deletions

File tree

docs/src/tutorials/getting_started/tolerances.jl

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ primal_feasibility_report(model, Dict(x => 1.0, y => 1e-6))
282282
# `value(x)` of an integer variable or `::Bool` for `value(x)` of a binary
283283
# variable.
284284

285-
# In most cases, it is safe to post-process the solution using
285+
# For some models, it is safe to post-process the solution using
286286
# `y_int = round(Int, value(y))`. However, in some cases "fixing" the
287287
# integrality like this can cause violations in primal feasibility that exceed
288288
# the primal feasibility tolerance. For example, if we rounded our
@@ -292,6 +292,33 @@ primal_feasibility_report(model, Dict(x => 1.0, y => 1e-6))
292292

293293
primal_feasibility_report(model, Dict(x => 1.0, y => 0.0))
294294

295+
# If strict integer feasibility matters to you, one heuristic that sometimes
296+
# works is to round and fix the integer variables, and then re-solve the problem
297+
# to find new values for the remaining continuous variables:
298+
299+
function round_and_repair_heuristic!(model)
300+
## Query all values first...
301+
vars = filter!(xi -> is_integer(xi) || is_binary(xi), all_variables(model))
302+
solution = round.(Int, value.(vars))
303+
## ...then modify the model
304+
fix.(vars, solution; force = true)
305+
optimize!(model)
306+
assert_is_solved_and_feasible(model)
307+
return
308+
end
309+
310+
# Here it is in action:
311+
312+
set_optimizer(model, HiGHS.Optimizer)
313+
set_silent(model)
314+
optimize!(model)
315+
assert_is_solved_and_feasible(model)
316+
round_and_repair_heuristic!(model)
317+
solution_summary(model)
318+
319+
# Note that this heuristic will fail if no feasible solution exists for the
320+
# rounded integer values.
321+
295322
# ### Why you shouldn't use a small tolerance
296323

297324
# Just like primal feasibility tolerances, using a smaller value for the

docs/src/tutorials/linear/mip_duality.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ dual_status(model)
6565
# can work around this problem by fixing the integer variables to their optimal
6666
# solution, relaxing integrality, and re-solving as a linear program.
6767

68-
discrete_values = value.(dispatch)
68+
discrete_values = round.(Int, value.(dispatch))
6969
fix.(dispatch, discrete_values; force = true)
7070
unset_binary.(dispatch)
7171
print(model)

0 commit comments

Comments
 (0)