-
Notifications
You must be signed in to change notification settings - Fork 115
Several bug fixes #786
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release/26.02
Are you sure you want to change the base?
Several bug fixes #786
Changes from all commits
a1eb6b8
8116fea
115a0b1
d50c064
a0a1d93
9f0fe29
aa15d8e
d604cb6
628c22b
6956bbc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1308,6 +1308,8 @@ lp_status_t branch_and_bound_t<i_t, f_t>::solve_root_relaxation( | |
| } | ||
|
|
||
| if (root_crossover_solution_set_.load(std::memory_order_acquire)) { | ||
| settings_.log.printf("\nRunning crossover\n\n"); | ||
|
|
||
| // Crush the root relaxation solution on converted user problem | ||
| std::vector<f_t> crushed_root_x; | ||
| crush_primal_solution( | ||
|
|
@@ -1338,23 +1340,24 @@ lp_status_t branch_and_bound_t<i_t, f_t>::solve_root_relaxation( | |
| root_crossover_soln_, | ||
| crossover_vstatus_); | ||
|
|
||
| if (crossover_status == crossover_status_t::OPTIMAL) { | ||
| settings_.log.printf("Crossover status: %d\n", crossover_status); | ||
| } | ||
|
|
||
| // Check if crossover was stopped by dual simplex | ||
| if (crossover_status == crossover_status_t::OPTIMAL) { | ||
| settings_.log.printf("\nCrossover found an optimal solution for the root relaxation\n\n"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is where we should indicate that PDLP/Barrier won. Can you use the is_pdlp_solution to determine which of them won and print it here?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did not find a way to get the winner solver from the |
||
| root_solver_type_ = root_solver_type_t::CROSSOVER; | ||
|
|
||
| set_root_concurrent_halt(1); // Stop dual simplex | ||
| root_status = root_status_future.get(); | ||
| // Override the root relaxation solution with the crossover solution | ||
| root_relax_soln_ = root_crossover_soln_; | ||
| root_vstatus_ = crossover_vstatus_; | ||
| root_status = lp_status_t::OPTIMAL; | ||
| } else { | ||
| root_status = root_status_future.get(); | ||
| root_status = root_status_future.get(); | ||
| root_solver_type_ = root_solver_type_t::DUAL_SIMPLEX; | ||
| } | ||
| } else { | ||
| root_status = root_status_future.get(); | ||
| root_status = root_status_future.get(); | ||
| root_solver_type_ = root_solver_type_t::DUAL_SIMPLEX; | ||
| } | ||
| return root_status; | ||
| } | ||
|
|
@@ -1414,14 +1417,13 @@ mip_status_t branch_and_bound_t<i_t, f_t>::solve(mip_solution_t<i_t, f_t>& solut | |
|
|
||
| root_relax_soln_.resize(original_lp_.num_rows, original_lp_.num_cols); | ||
|
|
||
| settings_.log.printf("Solving LP root relaxation\n"); | ||
|
|
||
| lp_status_t root_status; | ||
| simplex_solver_settings_t lp_settings = settings_; | ||
| lp_settings.inside_mip = 1; | ||
| lp_settings.concurrent_halt = get_root_concurrent_halt(); | ||
| // RINS/SUBMIP path | ||
| if (!enable_concurrent_lp_root_solve()) { | ||
| settings_.log.printf("\nSolving LP root relaxation with dual simplex\n"); | ||
| root_status = solve_linear_program_advanced(original_lp_, | ||
| exploration_stats_.start_time, | ||
| lp_settings, | ||
|
|
@@ -1430,6 +1432,7 @@ mip_status_t branch_and_bound_t<i_t, f_t>::solve(mip_solution_t<i_t, f_t>& solut | |
| edge_norms_); | ||
|
|
||
| } else { | ||
| settings_.log.printf("\nSolving LP root relaxation in concurrent mode\n"); | ||
| root_status = solve_root_relaxation(lp_settings); | ||
| } | ||
|
|
||
|
|
@@ -1540,10 +1543,11 @@ mip_status_t branch_and_bound_t<i_t, f_t>::solve(mip_solution_t<i_t, f_t>& solut | |
| original_lp_, | ||
| log); | ||
|
|
||
| settings_.log.printf("Exploring the B&B tree using %d threads (best-first = %d, diving = %d)\n", | ||
| settings_.num_threads, | ||
| settings_.num_bfs_workers, | ||
| settings_.num_threads - settings_.num_bfs_workers); | ||
| settings_.log.printf( | ||
| "\nExploring the B&B tree using %d threads (best-first = %d, diving = %d)\n\n", | ||
| settings_.num_threads, | ||
| settings_.num_bfs_workers, | ||
| settings_.num_threads - settings_.num_bfs_workers); | ||
|
|
||
| exploration_stats_.nodes_explored = 0; | ||
| exploration_stats_.nodes_unexplored = 2; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,6 +70,9 @@ struct bnb_stats_t { | |
| template <typename i_t, typename f_t> | ||
| class branch_and_bound_t { | ||
| public: | ||
| // Specify which solver was used for solving the root LP relaxation | ||
| enum class root_solver_type_t { NONE = 0, CROSSOVER = 1, DUAL_SIMPLEX = 2 }; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need this? Can we just determine who won in |
||
|
|
||
| branch_and_bound_t(const user_problem_t<i_t, f_t>& user_problem, | ||
| const simplex_solver_settings_t<i_t, f_t>& solver_settings); | ||
|
|
||
|
|
@@ -82,16 +85,24 @@ class branch_and_bound_t { | |
| const std::vector<f_t>& reduced_costs, | ||
| f_t objective, | ||
| f_t user_objective, | ||
| i_t iterations) | ||
| i_t iterations, | ||
| f_t solve_time) | ||
| { | ||
| root_crossover_soln_.x = primal; | ||
| root_crossover_soln_.y = dual; | ||
| root_crossover_soln_.z = reduced_costs; | ||
| root_objective_ = objective; | ||
| root_crossover_soln_.objective = objective; | ||
| root_crossover_soln_.user_objective = user_objective; | ||
| root_crossover_soln_.iterations = iterations; | ||
| root_crossover_solution_set_.store(true, std::memory_order_release); | ||
| if (root_solver_type_ == root_solver_type_t::NONE) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's move this printing to inside Otherwise we could tell the user we have found a solution with PDLP/Barrier. And then the user could wait a long time only to have us use the dual simplex solution because we either: a) failed in crossover, or b) crossover took a very long time. |
||
| settings_.log.printf( | ||
| "\nRoot relaxation solution found in %d iterations and %.2fs by PDLP/Barrier\n", | ||
| iterations, | ||
| solve_time); | ||
| settings_.log.printf("Root relaxation objective = %+.8e\n", user_objective); | ||
| root_crossover_soln_.x = primal; | ||
| root_crossover_soln_.y = dual; | ||
| root_crossover_soln_.z = reduced_costs; | ||
| root_objective_ = objective; | ||
| root_crossover_soln_.objective = objective; | ||
| root_crossover_soln_.user_objective = user_objective; | ||
| root_crossover_soln_.iterations = iterations; | ||
| root_crossover_solution_set_.store(true, std::memory_order_release); | ||
| } | ||
| } | ||
|
|
||
| // Set a solution based on the user problem during the course of the solve | ||
|
|
@@ -162,6 +173,7 @@ class branch_and_bound_t { | |
| std::atomic<bool> root_crossover_solution_set_{false}; | ||
| bool enable_concurrent_lp_root_solve_{false}; | ||
| std::atomic<int> root_concurrent_halt_{0}; | ||
| std::atomic<root_solver_type_t> root_solver_type_{root_solver_type_t::NONE}; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this need to be an atomic? I think we can never have a race condition because we write to this var only when one of the solves is optimal which means the other solver returned with halt status. |
||
|
|
||
| // Pseudocosts | ||
| pseudo_costs_t<i_t, f_t> pc_; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove this print. I don't think we want to interrupt the dual simplex logs for the root solve, unless we know that crossover was successful.