Skip to content

Commit

Permalink
[docs] fix benders_decomposition.jl (#3532)
Browse files Browse the repository at this point in the history
  • Loading branch information
odow authored Oct 8, 2023
1 parent 6f07624 commit 2368e63
Showing 1 changed file with 18 additions and 21 deletions.
39 changes: 18 additions & 21 deletions docs/src/tutorials/algorithms/benders_decomposition.jl
Original file line number Diff line number Diff line change
Expand Up @@ -239,34 +239,27 @@ y_optimal = optimal_ret.y
lazy_model = Model(GLPK.Optimizer)
@variable(lazy_model, x[1:dim_x] >= 0, Int)
@variable(lazy_model, θ >= M)
@objective(lazy_model, Min, θ)
@objective(lazy_model, Min, c_1' * x + θ)
print(lazy_model)

# What differs is that we write a callback function instead of a loop:

k = 0

"""
my_callback(cb_data)
A callback that implements Benders decomposition. Note how similar it is to the
inner loop of the iterative method.
"""
number_of_subproblem_solves = 0
function my_callback(cb_data)
global k += 1
status = callback_node_status(cb_data, lazy_model)
if status != MOI.CALLBACK_NODE_STATUS_INTEGER
## Only add the constraint if `x` is an integer feasible solution
return
end
x_k = callback_value.(cb_data, x)
θ_k = callback_value(cb_data, θ)
lower_bound = c_1' * x_k + θ_k
global number_of_subproblem_solves += 1
ret = solve_subproblem(x_k)
upper_bound = c_1' * x_k + c_2' * ret.y
gap = (upper_bound - lower_bound) / upper_bound
print_iteration(k, lower_bound, upper_bound, gap)
if gap < ABSOLUTE_OPTIMALITY_GAP
println("Terminating with the optimal solution")
return
if θ_k < (ret.obj - 1e-6)
## Only add the constraint if θ_k violates the constraint
cut = @build_constraint>= ret.obj + -ret.π' * A_1 * (x .- x_k))
MOI.submit(lazy_model, MOI.LazyConstraint(cb_data), cut)
end
cut = @build_constraint>= ret.obj + -ret.π' * A_1 * (x .- x_k))
MOI.submit(model, MOI.LazyConstraint(cb_data), cut)
return
end

Expand All @@ -276,8 +269,12 @@ set_attribute(lazy_model, MOI.LazyConstraintCallback(), my_callback)

optimize!(lazy_model)

# Note how this problem also takes 4 iterations to converge, but the sequence
# of bounds is different compared to the iterative method.
# For this model, the callback algorithm required more solves of the subproblem:

number_of_subproblem_solves

# But for larger problems, you can expect the callback algorithm to be more
# efficient than the iterative algorithm.

# Finally, we can obtain the optimal solution:

Expand Down

0 comments on commit 2368e63

Please sign in to comment.