dev(lp): diminish the number of pivots of primal by sorting the columns
Signed-off-by: Lev Nachmanson <levnach@microsoft.com>
This commit is contained in:
parent
61eaef0183
commit
ff8213a6a9
5 changed files with 37 additions and 19 deletions
|
@ -56,14 +56,6 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::fill_non_basis
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename X> void lp_dual_core_solver<T, X>::print_nb(std::ostream & out) {
|
|
||||||
out << "this is nb " << std::endl;
|
|
||||||
for (auto l : this->m_factorization->m_non_basic_columns) {
|
|
||||||
out << l << " ";
|
|
||||||
}
|
|
||||||
out << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename X> void lp_dual_core_solver<T, X>::restore_non_basis() {
|
template <typename T, typename X> void lp_dual_core_solver<T, X>::restore_non_basis() {
|
||||||
auto & nb = this->m_factorization->m_non_basic_columns;
|
auto & nb = this->m_factorization->m_non_basic_columns;
|
||||||
nb.clear();
|
nb.clear();
|
||||||
|
|
|
@ -49,8 +49,6 @@ public:
|
||||||
|
|
||||||
void fill_non_basis_with_only_able_to_enter_columns();
|
void fill_non_basis_with_only_able_to_enter_columns();
|
||||||
|
|
||||||
void print_nb(std::ostream & out);
|
|
||||||
|
|
||||||
void restore_non_basis();
|
void restore_non_basis();
|
||||||
|
|
||||||
bool update_basis(int entering, int leaving);
|
bool update_basis(int entering, int leaving);
|
||||||
|
|
|
@ -8,17 +8,41 @@
|
||||||
#include "util/lp/lp_primal_core_solver.h"
|
#include "util/lp/lp_primal_core_solver.h"
|
||||||
namespace lean {
|
namespace lean {
|
||||||
|
|
||||||
|
|
||||||
// This core solver solves (Ax=b, low_bound_values \leq x \leq upper_bound_values, maximize costs*x )
|
// This core solver solves (Ax=b, low_bound_values \leq x \leq upper_bound_values, maximize costs*x )
|
||||||
// The right side b is given implicitly by x and the basis
|
// The right side b is given implicitly by x and the basis
|
||||||
|
template <typename T, typename X>
|
||||||
|
void lp_primal_core_solver<T, X>::sort_non_basis() {
|
||||||
|
for (unsigned j : this->m_non_basic_columns) {
|
||||||
|
T const & da = this->m_d[j];
|
||||||
|
m_steepest_edge_coefficients[j] = da * da / this->m_column_norms[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(this->m_non_basic_columns.begin(), this->m_non_basic_columns.end(), [this](unsigned a, unsigned b) {
|
||||||
|
return m_steepest_edge_coefficients[a] > m_steepest_edge_coefficients[b];
|
||||||
|
});
|
||||||
|
// reinit m_basis_heading
|
||||||
|
for (int j = 0; j < this->m_non_basic_columns.size(); j++)
|
||||||
|
this->m_basis_heading[this->m_non_basic_columns[j]] = - j - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T, typename X>
|
template <typename T, typename X>
|
||||||
int lp_primal_core_solver<T, X>::choose_entering_column(unsigned number_of_benefitial_columns_to_go_over) { // at this moment m_y = cB * B(-1)
|
int lp_primal_core_solver<T, X>::choose_entering_column(unsigned number_of_benefitial_columns_to_go_over) { // at this moment m_y = cB * B(-1)
|
||||||
lean_assert(number_of_benefitial_columns_to_go_over);
|
lean_assert(number_of_benefitial_columns_to_go_over);
|
||||||
unsigned offset_in_nb = my_random() % this->m_non_basic_columns.size();
|
if (m_sort_columns_counter == 0) {
|
||||||
|
sort_non_basis();
|
||||||
|
m_sort_columns_counter = 20;
|
||||||
|
} else {
|
||||||
|
m_sort_columns_counter--;
|
||||||
|
}
|
||||||
|
lean_assert(m_sort_columns_counter>=0);
|
||||||
|
unsigned offset_in_nb = 0;
|
||||||
unsigned initial_offset_in_non_basis = offset_in_nb;
|
unsigned initial_offset_in_non_basis = offset_in_nb;
|
||||||
T steepest_edge = zero_of_type<T>();
|
T steepest_edge = zero_of_type<T>();
|
||||||
int entering = -1;
|
int entering = -1;
|
||||||
do {
|
do {
|
||||||
unsigned j = this->m_factorization->m_non_basic_columns[offset_in_nb];
|
unsigned j = this->m_non_basic_columns[offset_in_nb];
|
||||||
push_forward_offset_in_non_basis(offset_in_nb);
|
push_forward_offset_in_non_basis(offset_in_nb);
|
||||||
if (m_forbidden_enterings.find(j) != m_forbidden_enterings.end()) {
|
if (m_forbidden_enterings.find(j) != m_forbidden_enterings.end()) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -225,7 +249,8 @@ template <typename T, typename X> lp_primal_core_solver<T, X>:: lp_primal_core
|
||||||
column_type_array,
|
column_type_array,
|
||||||
low_bound_values,
|
low_bound_values,
|
||||||
upper_bound_values),
|
upper_bound_values),
|
||||||
m_beta(A.row_count()) {
|
m_beta(A.row_count()),
|
||||||
|
m_steepest_edge_coefficients(A.column_count()) {
|
||||||
this->m_status = UNKNOWN;
|
this->m_status = UNKNOWN;
|
||||||
this->m_column_norm_update_counter = settings.column_norms_update_frequency;
|
this->m_column_norm_update_counter = settings.column_norms_update_frequency;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +275,8 @@ lp_primal_core_solver(static_matrix<T, X> & A,
|
||||||
column_type_array,
|
column_type_array,
|
||||||
m_low_bound_values_dummy,
|
m_low_bound_values_dummy,
|
||||||
upper_bound_values),
|
upper_bound_values),
|
||||||
m_beta(A.row_count()) {
|
m_beta(A.row_count()),
|
||||||
|
m_steepest_edge_coefficients(A.column_count()) {
|
||||||
m_converted_harris_eps = convert_struct<T, double>::convert(this->m_settings.harris_feasibility_tolerance);
|
m_converted_harris_eps = convert_struct<T, double>::convert(this->m_settings.harris_feasibility_tolerance);
|
||||||
lean_assert(initial_x_is_correct());
|
lean_assert(initial_x_is_correct());
|
||||||
m_low_bound_values_dummy.resize(A.column_count(), zero_of_type<T>());
|
m_low_bound_values_dummy.resize(A.column_count(), zero_of_type<T>());
|
||||||
|
@ -504,8 +530,8 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::push_forw
|
||||||
offset_in_nb = 0;
|
offset_in_nb = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::get_number_of_non_basic_column_to_try_for_enter() {
|
template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::get_number_of_non_basic_column_to_try_for_enter() {
|
||||||
unsigned ret = this->m_factorization->m_non_basic_columns.size();
|
unsigned ret = this->m_non_basic_columns.size();
|
||||||
if (this->m_status == TENTATIVE_UNBOUNDED)
|
if (this->m_status == TENTATIVE_UNBOUNDED)
|
||||||
return ret; // we really need to find entering with a large reduced cost
|
return ret; // we really need to find entering with a large reduced cost
|
||||||
if (ret > 300) {
|
if (ret > 300) {
|
||||||
|
@ -594,7 +620,7 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::delete_fa
|
||||||
}
|
}
|
||||||
|
|
||||||
// according to Swietanowski, " A new steepest edge approximation for the simplex method for linear programming"
|
// according to Swietanowski, " A new steepest edge approximation for the simplex method for linear programming"
|
||||||
template <typename T, typename X> void lp_primal_core_solver<T, X>::init_column_norms() {
|
template <typename T, typename X> void lp_primal_core_solver<T, X>::init_column_norms() {
|
||||||
m_column_norm_update_counter = 0;
|
m_column_norm_update_counter = 0;
|
||||||
for (unsigned j : this->m_non_basic_columns)
|
for (unsigned j : this->m_non_basic_columns)
|
||||||
this->m_column_norms[j] = 1;
|
this->m_column_norms[j] = 1;
|
||||||
|
|
|
@ -48,7 +48,9 @@ public:
|
||||||
std::vector<T> m_costs_backup;
|
std::vector<T> m_costs_backup;
|
||||||
bool m_current_x_is_feasible;
|
bool m_current_x_is_feasible;
|
||||||
T m_converted_harris_eps = convert_struct<T, double>::convert(this->m_settings.harris_feasibility_tolerance);
|
T m_converted_harris_eps = convert_struct<T, double>::convert(this->m_settings.harris_feasibility_tolerance);
|
||||||
|
unsigned m_sort_columns_counter = 0;
|
||||||
|
std::vector<T> m_steepest_edge_coefficients;
|
||||||
|
void sort_non_basis();
|
||||||
int choose_entering_column(unsigned number_of_benefitial_columns_to_go_over);
|
int choose_entering_column(unsigned number_of_benefitial_columns_to_go_over);
|
||||||
|
|
||||||
int find_leaving_and_t_precisely(unsigned entering, X & t);
|
int find_leaving_and_t_precisely(unsigned entering, X & t);
|
||||||
|
|
|
@ -646,7 +646,7 @@ row_eta_matrix<T, X> *lu<T, X>::get_row_eta_matrix_and_set_row_vector(unsigned r
|
||||||
#endif
|
#endif
|
||||||
!m_settings.abs_val_is_smaller_than_pivot_tolerance((m_row_eta_work_vector[lowest_row_of_the_bump] - pivot_elem_for_checking) / denom)) {
|
!m_settings.abs_val_is_smaller_than_pivot_tolerance((m_row_eta_work_vector[lowest_row_of_the_bump] - pivot_elem_for_checking) / denom)) {
|
||||||
set_status(LU_status::Degenerated);
|
set_status(LU_status::Degenerated);
|
||||||
std::cout << "diagonal element is off" << std::endl;
|
// std::cout << "diagonal element is off" << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
#ifdef LEAN_DEBUG
|
#ifdef LEAN_DEBUG
|
||||||
|
|
Loading…
Reference in a new issue