diff --git a/cpp/src/dual_simplex/folding.cpp b/cpp/src/dual_simplex/folding.cpp index 913d86b0a..8628f69eb 100644 --- a/cpp/src/dual_simplex/folding.cpp +++ b/cpp/src/dual_simplex/folding.cpp @@ -1536,10 +1536,12 @@ void folding(lp_problem_t& problem, problem.lower = std::vector(reduced_cols, 0.0); problem.upper = std::vector(reduced_cols, inf); - presolve_info.folding_info.c_tilde = c_tilde; - presolve_info.folding_info.A_tilde = A_tilde; - presolve_info.folding_info.is_folded = true; - presolve_info.folding_info.num_upper_bounds = nz_ub; + presolve_info.folding_info.c_tilde = c_tilde; + presolve_info.folding_info.A_tilde = A_tilde; + presolve_info.folding_info.is_folded = true; + presolve_info.folding_info.num_upper_bounds = nz_ub; + presolve_info.folding_info.previous_free_variable_pairs = presolve_info.free_variable_pairs; + presolve_info.free_variable_pairs.clear(); settings.log.printf("Folding: time %.2f seconds\n", toc(start_time)); diff --git a/cpp/src/dual_simplex/presolve.cpp b/cpp/src/dual_simplex/presolve.cpp index e2790858e..8d80337c7 100644 --- a/cpp/src/dual_simplex/presolve.cpp +++ b/cpp/src/dual_simplex/presolve.cpp @@ -1419,9 +1419,10 @@ void uncrush_solution(const presolve_info_t& presolve_info, std::vector& uncrushed_y, std::vector& uncrushed_z) { - std::vector input_x = crushed_x; - std::vector input_y = crushed_y; - std::vector input_z = crushed_z; + std::vector input_x = crushed_x; + std::vector input_y = crushed_y; + std::vector input_z = crushed_z; + std::vector free_variable_pairs = presolve_info.free_variable_pairs; if (presolve_info.folding_info.is_folded) { // We solved a foled problem in the form // minimize c_prime^T x_prime @@ -1474,15 +1475,18 @@ void uncrush_solution(const presolve_info_t& presolve_info, input_y.resize(previous_rows - presolve_info.folding_info.num_upper_bounds); input_z = ztilde; input_z.resize(previous_cols - presolve_info.folding_info.num_upper_bounds); + + // If the original problem had free variables we need to reinstate them + free_variable_pairs = presolve_info.folding_info.previous_free_variable_pairs; } - const i_t num_free_variables = presolve_info.free_variable_pairs.size() / 2; + const i_t num_free_variables = free_variable_pairs.size() / 2; if (num_free_variables > 0) { settings.log.printf("Post-solve: Handling free variables %d\n", num_free_variables); // We added free variables so we need to map the crushed solution back to the original variables for (i_t k = 0; k < 2 * num_free_variables; k += 2) { - const i_t u = presolve_info.free_variable_pairs[k]; - const i_t v = presolve_info.free_variable_pairs[k + 1]; + const i_t u = free_variable_pairs[k]; + const i_t v = free_variable_pairs[k + 1]; input_x[u] -= input_x[v]; } input_z.resize(input_z.size() - num_free_variables); diff --git a/cpp/src/dual_simplex/presolve.hpp b/cpp/src/dual_simplex/presolve.hpp index fa8a8db58..bf0aab899 100644 --- a/cpp/src/dual_simplex/presolve.hpp +++ b/cpp/src/dual_simplex/presolve.hpp @@ -60,6 +60,7 @@ struct folding_info_t { c_tilde(0), A_tilde(0, 0, 0), num_upper_bounds(0), + previous_free_variable_pairs({}), is_folded(false) { } @@ -69,6 +70,7 @@ struct folding_info_t { std::vector c_tilde; csc_matrix_t A_tilde; i_t num_upper_bounds; + std::vector previous_free_variable_pairs; bool is_folded; };