Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cpp/src/branch_and_bound/branch_and_bound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1886,6 +1886,7 @@ lp_status_t branch_and_bound_t<i_t, f_t>::solve_root_relaxation(
root_crossover_settings,
original_lp_.lower,
original_lp_.upper,
exploration_stats_.start_time,
basic_list,
nonbasic_list,
crossover_vstatus_);
Expand Down Expand Up @@ -2285,6 +2286,7 @@ mip_status_t branch_and_bound_t<i_t, f_t>::solve(mip_solution_t<i_t, f_t>& solut
mutex_original_lp_.lock();
remove_cuts(original_lp_,
settings_,
exploration_stats_.start_time,
Arow_,
new_slacks_,
original_rows,
Expand Down
2 changes: 2 additions & 0 deletions cpp/src/branch_and_bound/branch_and_bound.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ class branch_and_bound_t {

void set_concurrent_lp_root_solve(bool enable) { enable_concurrent_lp_root_solve_ = enable; }

bool stop_for_time_limit(mip_solution_t<i_t, f_t>& solution);

// Repair a low-quality solution from the heuristics.
bool repair_solution(const std::vector<f_t>& leaf_edge_norms,
const std::vector<f_t>& potential_solution,
Expand Down
13 changes: 11 additions & 2 deletions cpp/src/branch_and_bound/pseudo_costs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,9 @@ void strong_branching(const user_problem_t<i_t, f_t>& original_problem,
pc.strong_branch_up.assign(fractional.size(), 0);
pc.num_strong_branches_completed = 0;

const f_t elapsed_time = toc(start_time);
if (elapsed_time > settings.time_limit) { return; }

if (settings.mip_batch_pdlp_strong_branching) {
settings.log.printf("Batch PDLP strong branching enabled\n");

Expand All @@ -334,10 +337,16 @@ void strong_branching(const user_problem_t<i_t, f_t>& original_problem,
fraction_values.push_back(original_root_soln_x[j]);
}

const auto mps_model = simplex_problem_to_mps_data_model(original_problem);
const auto mps_model = simplex_problem_to_mps_data_model(original_problem);
const f_t batch_elapsed_time = toc(start_time);
const f_t batch_remaining_time =
std::max(static_cast<f_t>(0.0), settings.time_limit - batch_elapsed_time);
if (batch_remaining_time <= 0.0) { return; }
pdlp_solver_settings_t<i_t, f_t> pdlp_settings;
pdlp_settings.time_limit = batch_remaining_time;
const raft::handle_t batch_pdlp_handle;
const auto solutions =
batch_pdlp_solve(&batch_pdlp_handle, mps_model, fractional, fraction_values);
batch_pdlp_solve(&batch_pdlp_handle, mps_model, fractional, fraction_values, pdlp_settings);
f_t batch_pdlp_strong_branching_time = toc(start_batch);

// Find max iteration on how many are done accross the batch
Expand Down
66 changes: 36 additions & 30 deletions cpp/src/cuts/cuts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2501,20 +2501,21 @@ i_t add_cuts(const simplex_solver_settings_t<i_t, f_t>& settings,
}

template <typename i_t, typename f_t>
void remove_cuts(lp_problem_t<i_t, f_t>& lp,
const simplex_solver_settings_t<i_t, f_t>& settings,
csr_matrix_t<i_t, f_t>& Arow,
std::vector<i_t>& new_slacks,
i_t original_rows,
std::vector<variable_type_t>& var_types,
std::vector<variable_status_t>& vstatus,
std::vector<f_t>& edge_norms,
std::vector<f_t>& x,
std::vector<f_t>& y,
std::vector<f_t>& z,
std::vector<i_t>& basic_list,
std::vector<i_t>& nonbasic_list,
basis_update_mpf_t<i_t, f_t>& basis_update)
i_t remove_cuts(lp_problem_t<i_t, f_t>& lp,
const simplex_solver_settings_t<i_t, f_t>& settings,
f_t start_time,
csr_matrix_t<i_t, f_t>& Arow,
std::vector<i_t>& new_slacks,
i_t original_rows,
std::vector<variable_type_t>& var_types,
std::vector<variable_status_t>& vstatus,
std::vector<f_t>& edge_norms,
std::vector<f_t>& x,
std::vector<f_t>& y,
std::vector<f_t>& z,
std::vector<i_t>& basic_list,
std::vector<i_t>& nonbasic_list,
basis_update_mpf_t<i_t, f_t>& basis_update)
{
std::vector<i_t> cuts_to_remove;
cuts_to_remove.reserve(lp.num_rows - original_rows);
Expand Down Expand Up @@ -2644,9 +2645,13 @@ void remove_cuts(lp_problem_t<i_t, f_t>& lp,
lp.A.col_start[lp.A.n]);

basis_update.resize(lp.num_rows);
basis_update.refactor_basis(
lp.A, settings, lp.lower, lp.upper, basic_list, nonbasic_list, vstatus);
i_t refactor_status = basis_update.refactor_basis(
lp.A, settings, lp.lower, lp.upper, start_time, basic_list, nonbasic_list, vstatus);
if (refactor_status == CONCURRENT_HALT_RETURN) { return CONCURRENT_HALT_RETURN; }
if (refactor_status == TIME_LIMIT_RETURN) { return TIME_LIMIT_RETURN; }
}

return 0;
}

template <typename i_t, typename f_t>
Expand Down Expand Up @@ -2793,20 +2798,21 @@ template int add_cuts(const simplex_solver_settings_t<int, double>& settings,
std::vector<variable_status_t>& vstatus,
std::vector<double>& edge_norms);

template void remove_cuts<int, double>(lp_problem_t<int, double>& lp,
const simplex_solver_settings_t<int, double>& settings,
csr_matrix_t<int, double>& Arow,
std::vector<int>& new_slacks,
int original_rows,
std::vector<variable_type_t>& var_types,
std::vector<variable_status_t>& vstatus,
std::vector<double>& edge_norms,
std::vector<double>& x,
std::vector<double>& y,
std::vector<double>& z,
std::vector<int>& basic_list,
std::vector<int>& nonbasic_list,
basis_update_mpf_t<int, double>& basis_update);
template int remove_cuts<int, double>(lp_problem_t<int, double>& lp,
const simplex_solver_settings_t<int, double>& settings,
double start_time,
csr_matrix_t<int, double>& Arow,
std::vector<int>& new_slacks,
int original_rows,
std::vector<variable_type_t>& var_types,
std::vector<variable_status_t>& vstatus,
std::vector<double>& edge_norms,
std::vector<double>& x,
std::vector<double>& y,
std::vector<double>& z,
std::vector<int>& basic_list,
std::vector<int>& nonbasic_list,
basis_update_mpf_t<int, double>& basis_update);

template void read_saved_solution_for_cut_verification<int, double>(
const lp_problem_t<int, double>& lp,
Expand Down
29 changes: 15 additions & 14 deletions cpp/src/cuts/cuts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,19 +461,20 @@ i_t add_cuts(const simplex_solver_settings_t<i_t, f_t>& settings,
std::vector<f_t>& edge_norms);

template <typename i_t, typename f_t>
void remove_cuts(lp_problem_t<i_t, f_t>& lp,
const simplex_solver_settings_t<i_t, f_t>& settings,
csr_matrix_t<i_t, f_t>& Arow,
std::vector<i_t>& new_slacks,
i_t original_rows,
std::vector<variable_type_t>& var_types,
std::vector<variable_status_t>& vstatus,
std::vector<f_t>& edge_norms,
std::vector<f_t>& x,
std::vector<f_t>& y,
std::vector<f_t>& z,
std::vector<i_t>& basic_list,
std::vector<i_t>& nonbasic_list,
basis_update_mpf_t<i_t, f_t>& basis_update);
i_t remove_cuts(lp_problem_t<i_t, f_t>& lp,
const simplex_solver_settings_t<i_t, f_t>& settings,
f_t start_time,
csr_matrix_t<i_t, f_t>& Arow,
std::vector<i_t>& new_slacks,
i_t original_rows,
std::vector<variable_type_t>& var_types,
std::vector<variable_status_t>& vstatus,
std::vector<f_t>& edge_norms,
std::vector<f_t>& x,
std::vector<f_t>& y,
std::vector<f_t>& z,
std::vector<i_t>& basic_list,
std::vector<i_t>& nonbasic_list,
basis_update_mpf_t<i_t, f_t>& basis_update);

} // namespace cuopt::linear_programming::dual_simplex
15 changes: 12 additions & 3 deletions cpp/src/dual_simplex/basis_solves.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ template <typename i_t, typename f_t>
i_t factorize_basis(const csc_matrix_t<i_t, f_t>& A,
const simplex_solver_settings_t<i_t, f_t>& settings,
const std::vector<i_t>& basic_list,
f_t start_time,
csc_matrix_t<i_t, f_t>& L,
csc_matrix_t<i_t, f_t>& U,
std::vector<i_t>& p,
Expand Down Expand Up @@ -383,15 +384,16 @@ i_t factorize_basis(const csc_matrix_t<i_t, f_t>& A,
settings,
settings.threshold_partial_pivoting_tol,
identity,
start_time,
S_col_perm,
SL,
SU,
S_perm_inv,
work_estimate);
if (settings.concurrent_halt != nullptr && *settings.concurrent_halt == 1) {
settings.log.printf("Concurrent halt\n");
return CONCURRENT_HALT_RETURN;
}
if (Srank < 0) { return Srank; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably better to handle the TIME_LIMIT case here explicitly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just propagates the error to the call stack. The callstack functions handle different return codes correctly(crossover.cpp and primal.coo). I can put a comment if you want?

if (Srank != Sdim) {
// Get the rank deficient columns
deficient.clear();
Expand Down Expand Up @@ -618,7 +620,14 @@ i_t factorize_basis(const csc_matrix_t<i_t, f_t>& A,
q.resize(m);
work_estimate += m;
f_t fact_start = tic();
rank = right_looking_lu(A, settings, medium_tol, basic_list, q, L, U, pinv, work_estimate);
rank =
right_looking_lu(A, settings, medium_tol, basic_list, start_time, q, L, U, pinv, work_estimate);
if (rank < 0) {
if (settings.concurrent_halt != nullptr && *settings.concurrent_halt == 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We check for concurrent halt below. So not sure this is necessary.

If you think it should be kept, please remove the check below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is when right_looking_lu returns some non-success code but concurrent LP has found. So this is to basically return the correct return code and logs.

return CONCURRENT_HALT_RETURN;
}
return rank;
}
inverse_permutation(pinv, p);
work_estimate += 3 * pinv.size();

Expand All @@ -638,7 +647,6 @@ i_t factorize_basis(const csc_matrix_t<i_t, f_t>& A,
work_estimate += 3 * (m - rank);
}
if (settings.concurrent_halt != nullptr && *settings.concurrent_halt == 1) {
settings.log.printf("Concurrent halt\n");
return CONCURRENT_HALT_RETURN;
}
if (verbose) {
Expand Down Expand Up @@ -938,6 +946,7 @@ template void get_basis_from_vstatus<int>(int m,
template int factorize_basis<int>(const csc_matrix_t<int, double>& A,
const simplex_solver_settings_t<int, double>& settings,
const std::vector<int>& basis_list,
double start_time,
csc_matrix_t<int, double>& L,
csc_matrix_t<int, double>& U,
std::vector<int>& p,
Expand Down
1 change: 1 addition & 0 deletions cpp/src/dual_simplex/basis_solves.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ template <typename i_t, typename f_t>
i_t factorize_basis(const csc_matrix_t<i_t, f_t>& A,
const simplex_solver_settings_t<i_t, f_t>& settings,
const std::vector<i_t>& basis_list,
f_t start_time,
csc_matrix_t<i_t, f_t>& L,
csc_matrix_t<i_t, f_t>& U,
std::vector<i_t>& p,
Expand Down
5 changes: 5 additions & 0 deletions cpp/src/dual_simplex/basis_updates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2343,6 +2343,7 @@ int basis_update_mpf_t<i_t, f_t>::refactor_basis(
const simplex_solver_settings_t<i_t, f_t>& settings,
const std::vector<f_t>& lower,
const std::vector<f_t>& upper,
f_t start_time,
std::vector<i_t>& basic_list,
std::vector<i_t>& nonbasic_list,
std::vector<variable_status_t>& vstatus)
Expand All @@ -2360,6 +2361,7 @@ int basis_update_mpf_t<i_t, f_t>::refactor_basis(
i_t status = factorize_basis(A,
settings,
basic_list,
start_time,
L0_,
U0_,
row_permutation_,
Expand All @@ -2369,6 +2371,7 @@ int basis_update_mpf_t<i_t, f_t>::refactor_basis(
slacks_needed,
work_estimate_);
if (status == CONCURRENT_HALT_RETURN) { return CONCURRENT_HALT_RETURN; }
if (status == TIME_LIMIT_RETURN) { return TIME_LIMIT_RETURN; }
if (status == -1) {
settings.log.debug("Initial factorization failed\n");
basis_repair(A,
Expand Down Expand Up @@ -2403,6 +2406,7 @@ int basis_update_mpf_t<i_t, f_t>::refactor_basis(
status = factorize_basis(A,
settings,
basic_list,
start_time,
L0_,
U0_,
row_permutation_,
Expand All @@ -2412,6 +2416,7 @@ int basis_update_mpf_t<i_t, f_t>::refactor_basis(
slacks_needed,
work_estimate_);
if (status == CONCURRENT_HALT_RETURN) { return CONCURRENT_HALT_RETURN; }
if (status == TIME_LIMIT_RETURN) { return TIME_LIMIT_RETURN; }
if (status == -1) {
#ifdef CHECK_L_FACTOR
if (L0_.check_matrix() == -1) { settings.log.printf("Bad L after basis repair\n"); }
Expand Down
1 change: 1 addition & 0 deletions cpp/src/dual_simplex/basis_updates.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ class basis_update_mpf_t {
const simplex_solver_settings_t<i_t, f_t>& settings,
const std::vector<f_t>& lower,
const std::vector<f_t>& upper,
f_t start_time,
std::vector<i_t>& basic_list,
std::vector<i_t>& nonbasic_list,
std::vector<variable_status_t>& vstatus);
Expand Down
Loading