Skip to content

Commit

Permalink
Fixed bug in presolve (#1127)
Browse files Browse the repository at this point in the history
* Fixed bug in presolve algorithm when the partial solution to fix contains deactivated variables

* Try to cover more lines
  • Loading branch information
rrsadykov committed Feb 2, 2024
1 parent 398d307 commit a70ad0a
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 7 deletions.
2 changes: 1 addition & 1 deletion docs/src/man/presolve.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

>### Ruslan Sadykov, 20/10/2023, revised 16/01/2024
The document presents the presolve algorithm implemented in _Coluna_. Is it particularly important to run the this algorithm after augmenting the partial solution in rounding and diving heuristics.
The document presents the presolve algorithm implemented in _Coluna_. It is particularly important to run this algorithm after augmenting the partial solution in rounding and diving heuristics.

## 1. Augmenting the partial solution

Expand Down
7 changes: 1 addition & 6 deletions src/Algorithm/presolve/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ function run!(
local_restr_partial_sol = propagate_partial_sol_into_master!(
reform, presolve_reform, input.partial_sol_to_fix, algo.verbose
)
isnothing(local_restr_partial_sol) && return PresolveOutput(false)

# Perform several rounds of presolve.
for i in 1:3
Expand Down Expand Up @@ -549,9 +550,3 @@ function _column_is_proper(col_id, sp_form)
end
return true
end

function column_is_proper(col_id, reform)
sp_id = getoriginformuid(col_id)
sp_form = get_dw_pricing_sps(reform)[sp_id]
return _column_is_proper(col_id, sp_form)
end
8 changes: 8 additions & 0 deletions src/Algorithm/presolve/propagation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ function get_partial_sol(
)
new_partial_sol = zeros(Float64, length(presolve_form.col_to_var))
for (var_id, value) in partial_sol_to_fix
if !haskey(presolve_form.var_to_col, var_id)
if iszero(value)
continue
else
return nothing
end
end
new_partial_sol[presolve_form.var_to_col[var_id]] += value
end
return new_partial_sol
Expand Down Expand Up @@ -251,6 +258,7 @@ function propagate_partial_sol_into_master!(
# Create the local partial solution from the restricted master presolve representation.
# This local partial solution must then be "fixed" & propagated.
local_restr_partial_sol = get_partial_sol(presolve_restricted_master, partial_sol_to_fix)
isnothing(local_restr_partial_sol) && return nothing

# Compute the rhs of all constraints.
# Non-robust and convexity constraints rhs can only be computed using this representation.
Expand Down
12 changes: 12 additions & 0 deletions test/unit/Presolve/presolve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,8 @@ function test_presolve_full()
x_3 + x_4 + 0.0 PricingSetupVar_sp_5
s.t.
1.0 x_3 + 1.0 x_4 >= 4.0
solutions
2.0 x_3 {MC_2}
continuous
pure
Expand Down Expand Up @@ -601,6 +603,16 @@ function test_presolve_full()
| MC_1 = [x_1 = 1.0 ] = 1.0
└ value = 1.00
"""


input = Coluna.Algorithm.PresolveInput(Dict(master_vars["MC_1"] => 0.0))
output = Coluna.Algorithm.run!(presolve_algorithm, env, reform, input)
@test output.feasible == true

input = Coluna.Algorithm.PresolveInput(Dict(master_vars["MC_1"] => 1.0))
output = Coluna.Algorithm.run!(presolve_algorithm, env, reform, input)
@test output.feasible == false

return nothing
end

Expand Down

0 comments on commit a70ad0a

Please sign in to comment.