3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-18 09:12:16 +00:00

remove m_b from lar_core_solver

the column vector is pure overhead for the way the lar solver uses lp.
Some other solver modules use column vectors b and integrate with the lp_core_solver_base. The interaction model should be reviewed.
Unused solvers should be removed to make it easier to maintain this code.
This commit is contained in:
Nikolaj Bjorner 2023-02-28 17:35:54 -08:00
parent 1a9990a92f
commit 5974a2dc58
8 changed files with 67 additions and 113 deletions

View file

@ -66,6 +66,7 @@ public:
); );
lp_settings & settings() { return m_r_solver.m_settings;} lp_settings & settings() { return m_r_solver.m_settings;}
const lp_settings & settings() const { return m_r_solver.m_settings;} const lp_settings & settings() const { return m_r_solver.m_settings;}
int get_infeasible_sum_sign() const { return m_infeasible_sum_sign; } int get_infeasible_sum_sign() const { return m_infeasible_sum_sign; }
@ -340,6 +341,7 @@ public:
switch (m_column_types[j]) { switch (m_column_types[j]) {
case column_type::free_column: case column_type::free_column:
lp_assert(false); // unreachable lp_assert(false); // unreachable
break;
case column_type::upper_bound: case column_type::upper_bound:
s.m_x[j] = s.m_upper_bounds[j]; s.m_x[j] = s.m_upper_bounds[j];
break; break;
@ -365,7 +367,7 @@ public:
} }
} }
lp_assert(is_zero_vector(s.m_b)); // lp_assert(is_zero_vector(s.m_b));
s.solve_Ax_eq_b(); s.solve_Ax_eq_b();
} }
@ -463,7 +465,8 @@ public:
m_d_nbasis = m_r_nbasis; m_d_nbasis = m_r_nbasis;
delete m_d_solver.m_factorization; delete m_d_solver.m_factorization;
m_d_solver.m_factorization = nullptr; m_d_solver.m_factorization = nullptr;
} else { }
else {
prepare_solver_x_with_signature_tableau(signature); prepare_solver_x_with_signature_tableau(signature);
m_r_solver.start_tracing_basis_changes(); m_r_solver.start_tracing_basis_changes();
m_r_solver.find_feasible_solution(); m_r_solver.find_feasible_solution();

View file

@ -46,14 +46,10 @@ lar_core_solver::lar_core_solver(
column_names) { column_names) {
} }
void lar_core_solver::calculate_pivot_row(unsigned i) { void lar_core_solver::calculate_pivot_row(unsigned i) {
m_r_solver.calculate_pivot_row(i); m_r_solver.calculate_pivot_row(i);
} }
void lar_core_solver::prefix_r() { void lar_core_solver::prefix_r() {
if (!m_r_solver.m_settings.use_tableau()) { if (!m_r_solver.m_settings.use_tableau()) {
m_r_solver.m_copy_of_xB.resize(m_r_solver.m_n()); m_r_solver.m_copy_of_xB.resize(m_r_solver.m_n());
@ -67,7 +63,7 @@ void lar_core_solver::prefix_r() {
init_column_row_nz_for_r_solver(); init_column_row_nz_for_r_solver();
} }
m_r_solver.m_b.resize(m_r_solver.m_m()); // m_r_solver.m_b.resize(m_r_solver.m_m());
if (m_r_solver.m_settings.simplex_strategy() != simplex_strategy_enum::tableau_rows) { if (m_r_solver.m_settings.simplex_strategy() != simplex_strategy_enum::tableau_rows) {
if(m_r_solver.m_settings.use_breakpoints_in_feasibility_search) if(m_r_solver.m_settings.use_breakpoints_in_feasibility_search)
m_r_solver.m_breakpoint_indices_queue.resize(m_r_solver.m_n()); m_r_solver.m_breakpoint_indices_queue.resize(m_r_solver.m_n());
@ -78,7 +74,7 @@ void lar_core_solver::prefix_r() {
} }
void lar_core_solver::prefix_d() { void lar_core_solver::prefix_d() {
m_d_solver.m_b.resize(m_d_solver.m_m()); // m_d_solver.m_b.resize(m_d_solver.m_m());
m_d_solver.m_breakpoint_indices_queue.resize(m_d_solver.m_n()); m_d_solver.m_breakpoint_indices_queue.resize(m_d_solver.m_n());
m_d_solver.m_copy_of_xB.resize(m_d_solver.m_n()); m_d_solver.m_copy_of_xB.resize(m_d_solver.m_n());
m_d_solver.m_costs.resize(m_d_solver.m_n()); m_d_solver.m_costs.resize(m_d_solver.m_n());
@ -100,9 +96,8 @@ void lar_core_solver::fill_not_improvable_zero_sum_from_inf_row() {
unsigned bj = m_r_basis[m_r_solver.m_inf_row_index_for_tableau]; unsigned bj = m_r_basis[m_r_solver.m_inf_row_index_for_tableau];
m_infeasible_sum_sign = m_r_solver.inf_sign_of_column(bj); m_infeasible_sum_sign = m_r_solver.inf_sign_of_column(bj);
m_infeasible_linear_combination.clear(); m_infeasible_linear_combination.clear();
for (auto & rc : m_r_solver.m_A.m_rows[m_r_solver.m_inf_row_index_for_tableau]) { for (auto & rc : m_r_solver.m_A.m_rows[m_r_solver.m_inf_row_index_for_tableau])
m_infeasible_linear_combination.push_back(std::make_pair(rc.coeff(), rc.var())); m_infeasible_linear_combination.push_back(std::make_pair(rc.coeff(), rc.var()));
}
} }
void lar_core_solver::fill_not_improvable_zero_sum() { void lar_core_solver::fill_not_improvable_zero_sum() {
@ -115,26 +110,23 @@ void lar_core_solver::fill_not_improvable_zero_sum() {
m_infeasible_linear_combination.clear(); m_infeasible_linear_combination.clear();
for (auto j : m_r_solver.m_basis) { for (auto j : m_r_solver.m_basis) {
const mpq & cost_j = m_r_solver.m_costs[j]; const mpq & cost_j = m_r_solver.m_costs[j];
if (!numeric_traits<mpq>::is_zero(cost_j)) { if (!numeric_traits<mpq>::is_zero(cost_j))
m_infeasible_linear_combination.push_back(std::make_pair(cost_j, j)); m_infeasible_linear_combination.push_back(std::make_pair(cost_j, j));
}
} }
// m_costs are expressed by m_d ( additional costs), substructing the latter gives 0 // m_costs are expressed by m_d ( additional costs), substructing the latter gives 0
for (unsigned j = 0; j < m_r_solver.m_n(); j++) { for (unsigned j = 0; j < m_r_solver.m_n(); j++) {
if (m_r_solver.m_basis_heading[j] >= 0) continue; if (m_r_solver.m_basis_heading[j] >= 0) continue;
const mpq & d_j = m_r_solver.m_d[j]; const mpq & d_j = m_r_solver.m_d[j];
if (!numeric_traits<mpq>::is_zero(d_j)) { if (!numeric_traits<mpq>::is_zero(d_j))
m_infeasible_linear_combination.push_back(std::make_pair(-d_j, j)); m_infeasible_linear_combination.push_back(std::make_pair(-d_j, j));
}
} }
} }
unsigned lar_core_solver::get_number_of_non_ints() const { unsigned lar_core_solver::get_number_of_non_ints() const {
unsigned n = 0; unsigned n = 0;
for (auto & x : m_r_solver.m_x) { for (auto & x : m_r_solver.m_x)
if (x.is_int() == false) if (!x.is_int())
n++; n++;
}
return n; return n;
} }

View file

@ -8,8 +8,8 @@
namespace lp { namespace lp {
////////////////// methods ////////////////////////////////
static_matrix<double, double>& lar_solver::A_d() { return m_mpq_lar_core_solver.m_d_A; } static_matrix<double, double>& lar_solver::A_d() { return m_mpq_lar_core_solver.m_d_A; }
static_matrix<double, double > const& lar_solver::A_d() const { return m_mpq_lar_core_solver.m_d_A; } static_matrix<double, double > const& lar_solver::A_d() const { return m_mpq_lar_core_solver.m_d_A; }
lp_settings& lar_solver::settings() { return m_settings; } lp_settings& lar_solver::settings() { return m_settings; }
@ -18,7 +18,6 @@ namespace lp {
statistics& lar_solver::stats() { return m_settings.stats(); } statistics& lar_solver::stats() { return m_settings.stats(); }
void lar_solver::updt_params(params_ref const& _p) { void lar_solver::updt_params(params_ref const& _p) {
smt_params_helper p(_p); smt_params_helper p(_p);
set_track_pivoted_rows(p.arith_bprop_on_pivoted_rows()); set_track_pivoted_rows(p.arith_bprop_on_pivoted_rows());
@ -42,7 +41,6 @@ namespace lp {
} }
lar_solver::~lar_solver() { lar_solver::~lar_solver() {
for (auto t : m_terms) for (auto t : m_terms)
delete t; delete t;
} }
@ -1406,7 +1404,6 @@ namespace lp {
A_r().m_rows.pop_back(); A_r().m_rows.pop_back();
A_r().m_columns.pop_back(); A_r().m_columns.pop_back();
CASSERT("check_static_matrix", A_r().is_correct()); CASSERT("check_static_matrix", A_r().is_correct());
slv.m_b.pop_back();
} }
void lar_solver::remove_last_column_from_A() { void lar_solver::remove_last_column_from_A() {
@ -1716,8 +1713,6 @@ namespace lp {
m_terms.push_back(t); m_terms.push_back(t);
} }
// terms // terms
bool lar_solver::all_vars_are_registered(const vector<std::pair<mpq, var_index>>& coeffs) { bool lar_solver::all_vars_are_registered(const vector<std::pair<mpq, var_index>>& coeffs) {
for (const auto& p : coeffs) { for (const auto& p : coeffs) {
@ -1788,7 +1783,6 @@ namespace lp {
A_r().fill_last_row_with_pivoting(*term, A_r().fill_last_row_with_pivoting(*term,
j, j,
m_mpq_lar_core_solver.m_r_solver.m_basis_heading); m_mpq_lar_core_solver.m_r_solver.m_basis_heading);
m_mpq_lar_core_solver.m_r_solver.m_b.resize(A_r().column_count(), zero_of_type<mpq>());
} }
else { else {
fill_last_row_of_A_r(A_r(), term); fill_last_row_of_A_r(A_r(), term);

View file

@ -36,8 +36,8 @@ template lp::non_basic_column_value_position lp::lp_core_solver_base<lp::mpq, lp
template lp::non_basic_column_value_position lp::lp_core_solver_base<lp::mpq, lp::mpq>::get_non_basic_column_value_position(unsigned int) const; template lp::non_basic_column_value_position lp::lp_core_solver_base<lp::mpq, lp::mpq>::get_non_basic_column_value_position(unsigned int) const;
template void lp::lp_core_solver_base<double, double>::init_reduced_costs_for_one_iteration(); template void lp::lp_core_solver_base<double, double>::init_reduced_costs_for_one_iteration();
template lp::lp_core_solver_base<double, double>::lp_core_solver_base( template lp::lp_core_solver_base<double, double>::lp_core_solver_base(
lp::static_matrix<double, double>&, vector<double>&, lp::static_matrix<double, double>&, // vector<double>&,
vector<unsigned int >&, vector<unsigned>&,
vector<unsigned> &, vector<int> &, vector<unsigned> &, vector<int> &,
vector<double >&, vector<double >&,
vector<double >&, vector<double >&,
@ -80,7 +80,9 @@ template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::calc
template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::init(); template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::init();
template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::init_basis_heading_and_non_basic_columns_vector(); template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::init_basis_heading_and_non_basic_columns_vector();
template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::init_reduced_costs_for_one_iteration(); template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::init_reduced_costs_for_one_iteration();
template lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::lp_core_solver_base(lp::static_matrix<lp::mpq, lp::numeric_pair<lp::mpq> >&, vector<lp::numeric_pair<lp::mpq> >&, vector<unsigned int >&, vector<unsigned> &, vector<int> &, vector<lp::numeric_pair<lp::mpq> >&, vector<lp::mpq>&, lp::lp_settings&, const column_namer&, const vector<lp::column_type >&, template lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::lp_core_solver_base(lp::static_matrix<lp::mpq, lp::numeric_pair<lp::mpq> >&,
// vector<lp::numeric_pair<lp::mpq> >&,
vector<unsigned int >&, vector<unsigned> &, vector<int> &, vector<lp::numeric_pair<lp::mpq> >&, vector<lp::mpq>&, lp::lp_settings&, const column_namer&, const vector<lp::column_type >&,
const vector<lp::numeric_pair<lp::mpq> >&, const vector<lp::numeric_pair<lp::mpq> >&,
const vector<lp::numeric_pair<lp::mpq> >&); const vector<lp::numeric_pair<lp::mpq> >&);
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::print_statistics_with_cost_and_check_that_the_time_is_over(lp::numeric_pair<lp::mpq>, std::ostream&); template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::print_statistics_with_cost_and_check_that_the_time_is_over(lp::numeric_pair<lp::mpq>, std::ostream&);
@ -91,7 +93,7 @@ template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::upda
template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::add_delta_to_entering(unsigned int, const lp::numeric_pair<lp::mpq>&); template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::add_delta_to_entering(unsigned int, const lp::numeric_pair<lp::mpq>&);
template lp::lp_core_solver_base<lp::mpq, lp::mpq>::lp_core_solver_base( template lp::lp_core_solver_base<lp::mpq, lp::mpq>::lp_core_solver_base(
lp::static_matrix<lp::mpq, lp::mpq>&, lp::static_matrix<lp::mpq, lp::mpq>&,
vector<lp::mpq>&, //vector<lp::mpq>&,
vector<unsigned int >&, vector<unsigned int >&,
vector<unsigned> &, vector<int> &, vector<unsigned> &, vector<int> &,
vector<lp::mpq>&, vector<lp::mpq>&,

View file

@ -67,7 +67,7 @@ public:
indexed_vector<T> m_pivot_row_of_B_1; // the pivot row of the reverse of B indexed_vector<T> m_pivot_row_of_B_1; // the pivot row of the reverse of B
indexed_vector<T> m_pivot_row; // this is the real pivot row of the simplex tableu indexed_vector<T> m_pivot_row; // this is the real pivot row of the simplex tableu
static_matrix<T, X> & m_A; // the matrix A static_matrix<T, X> & m_A; // the matrix A
vector<X> & m_b; // the right side // vector<X> const & m_b; // the right side
vector<unsigned> & m_basis; vector<unsigned> & m_basis;
vector<unsigned>& m_nbasis; vector<unsigned>& m_nbasis;
vector<int>& m_basis_heading; vector<int>& m_basis_heading;
@ -118,7 +118,7 @@ public:
unsigned m_n() const { return m_A.column_count(); } // the number of columns in the matrix m_A unsigned m_n() const { return m_A.column_count(); } // the number of columns in the matrix m_A
lp_core_solver_base(static_matrix<T, X> & A, lp_core_solver_base(static_matrix<T, X> & A,
vector<X> & b, // the right side vector //vector<X> & b, // the right side vector
vector<unsigned> & basis, vector<unsigned> & basis,
vector<unsigned> & nbasis, vector<unsigned> & nbasis,
vector<int> & heading, vector<int> & heading,
@ -213,7 +213,6 @@ public:
return !below_bound(x, bound) && !above_bound(x, bound); return !below_bound(x, bound) && !above_bound(x, bound);
} }
bool need_to_pivot_to_basis_tableau() const { bool need_to_pivot_to_basis_tableau() const {
unsigned m = m_A.row_count(); unsigned m = m_A.row_count();
for (unsigned i = 0; i < m; i++) { for (unsigned i = 0; i < m; i++) {
@ -284,7 +283,6 @@ public:
return below_bound(m_x[p], m_upper_bounds[p]); return below_bound(m_x[p], m_upper_bounds[p]);
} }
bool x_above_upper_bound(unsigned p) const { bool x_above_upper_bound(unsigned p) const {
return above_bound(m_x[p], m_upper_bounds[p]); return above_bound(m_x[p], m_upper_bounds[p]);
} }
@ -310,7 +308,6 @@ public:
bool d_is_not_positive(unsigned j) const; bool d_is_not_positive(unsigned j) const;
bool time_is_over(); bool time_is_over();
void rs_minus_Anx(vector<X> & rs); void rs_minus_Anx(vector<X> & rs);
@ -351,8 +348,6 @@ public:
std::string column_name(unsigned column) const; std::string column_name(unsigned column) const;
void copy_right_side(vector<X> & rs);
void add_delta_to_xB(vector<X> & del); void add_delta_to_xB(vector<X> & del);
void find_error_in_BxB(vector<X>& rs); void find_error_in_BxB(vector<X>& rs);
@ -367,8 +362,6 @@ public:
return ret; return ret;
} }
bool snap_column_to_bound(unsigned j) { bool snap_column_to_bound(unsigned j) {
switch (m_column_types[j]) { switch (m_column_types[j]) {
case column_type::fixed: case column_type::fixed:

View file

@ -28,7 +28,7 @@ namespace lp {
template <typename T, typename X> lp_core_solver_base<T, X>:: template <typename T, typename X> lp_core_solver_base<T, X>::
lp_core_solver_base(static_matrix<T, X> & A, lp_core_solver_base(static_matrix<T, X> & A,
vector<X> & b, // the right side vector // vector<X> & b, // the right side vector
vector<unsigned> & basis, vector<unsigned> & basis,
vector<unsigned> & nbasis, vector<unsigned> & nbasis,
vector<int> & heading, vector<int> & heading,
@ -47,7 +47,7 @@ lp_core_solver_base(static_matrix<T, X> & A,
m_pivot_row_of_B_1(A.row_count()), m_pivot_row_of_B_1(A.row_count()),
m_pivot_row(A.column_count()), m_pivot_row(A.column_count()),
m_A(A), m_A(A),
m_b(b), // m_b(b),
m_basis(basis), m_basis(basis),
m_nbasis(nbasis), m_nbasis(nbasis),
m_basis_heading(heading), m_basis_heading(heading),
@ -220,7 +220,7 @@ A_mult_x_is_off() const {
lp_assert(m_x.size() == m_A.column_count()); lp_assert(m_x.size() == m_A.column_count());
if (numeric_traits<T>::precise()) { if (numeric_traits<T>::precise()) {
for (unsigned i = 0; i < m_m(); i++) { for (unsigned i = 0; i < m_m(); i++) {
X delta = m_b[i] - m_A.dot_product_with_row(i, m_x); X delta = /*m_b[i] */- m_A.dot_product_with_row(i, m_x);
if (delta != numeric_traits<X>::zero()) { if (delta != numeric_traits<X>::zero()) {
return true; return true;
} }
@ -230,8 +230,8 @@ A_mult_x_is_off() const {
T feps = convert_struct<T, double>::convert(m_settings.refactor_tolerance); T feps = convert_struct<T, double>::convert(m_settings.refactor_tolerance);
X one = convert_struct<X, double>::convert(1.0); X one = convert_struct<X, double>::convert(1.0);
for (unsigned i = 0; i < m_m(); i++) { for (unsigned i = 0; i < m_m(); i++) {
X delta = abs(m_b[i] - m_A.dot_product_with_row(i, m_x)); X delta = abs(/*m_b[i] -*/ m_A.dot_product_with_row(i, m_x));
X eps = feps * (one + T(0.1) * abs(m_b[i])); auto eps = feps /* * (one + T(0.1) * abs(m_b[i])) */;
if (delta > eps) { if (delta > eps) {
#if 0 #if 0
@ -263,8 +263,8 @@ A_mult_x_is_off_on_index(const vector<unsigned> & index) const {
T feps = convert_struct<T, double>::convert(m_settings.refactor_tolerance); T feps = convert_struct<T, double>::convert(m_settings.refactor_tolerance);
X one = convert_struct<X, double>::convert(1.0); X one = convert_struct<X, double>::convert(1.0);
for (unsigned i : index) { for (unsigned i : index) {
X delta = abs(m_b[i] - m_A.dot_product_with_row(i, m_x)); X delta = abs(/*m_b[i] -*/ m_A.dot_product_with_row(i, m_x));
X eps = feps * (one + T(0.1) * abs(m_b[i])); auto eps = feps /* *(one + T(0.1) * abs(m_b[i])) */;
if (delta > eps) { if (delta > eps) {
#if 0 #if 0
@ -400,7 +400,8 @@ column_is_dual_feasible(unsigned j) const {
case column_type::lower_bound: case column_type::lower_bound:
return x_is_at_lower_bound(j) && d_is_not_negative(j); return x_is_at_lower_bound(j) && d_is_not_negative(j);
case column_type::upper_bound: case column_type::upper_bound:
lp_assert(false); // impossible case UNREACHABLE();
break;
case column_type::free_column: case column_type::free_column:
return numeric_traits<X>::is_zero(m_d[j]); return numeric_traits<X>::is_zero(m_d[j]);
default: default:
@ -441,7 +442,7 @@ template <typename T, typename X> void lp_core_solver_base<T, X>::
rs_minus_Anx(vector<X> & rs) { rs_minus_Anx(vector<X> & rs) {
unsigned row = m_m(); unsigned row = m_m();
while (row--) { while (row--) {
auto &rsv = rs[row] = m_b[row]; auto& rsv = rs[row] = zero_of_type<X>(); //m_b[row];
for (auto & it : m_A.m_rows[row]) { for (auto & it : m_A.m_rows[row]) {
unsigned j = it.var(); unsigned j = it.var();
if (m_basis_heading[j] < 0) { if (m_basis_heading[j] < 0) {
@ -454,8 +455,7 @@ rs_minus_Anx(vector<X> & rs) {
template <typename T, typename X> bool lp_core_solver_base<T, X>:: template <typename T, typename X> bool lp_core_solver_base<T, X>::
find_x_by_solving() { find_x_by_solving() {
solve_Ax_eq_b(); solve_Ax_eq_b();
bool ret= !A_mult_x_is_off(); return !A_mult_x_is_off();
return ret;
} }
template <typename T, typename X> bool lp_core_solver_base<T, X>::column_is_feasible(unsigned j) const { template <typename T, typename X> bool lp_core_solver_base<T, X>::column_is_feasible(unsigned j) const {
@ -463,28 +463,12 @@ template <typename T, typename X> bool lp_core_solver_base<T, X>::column_is_feas
switch (this->m_column_types[j]) { switch (this->m_column_types[j]) {
case column_type::fixed: case column_type::fixed:
case column_type::boxed: case column_type::boxed:
if (this->above_bound(x, this->m_upper_bounds[j])) { return !this->above_bound(x, this->m_upper_bounds[j]) &&
return false; !this->below_bound(x, this->m_lower_bounds[j]);
} else if (this->below_bound(x, this->m_lower_bounds[j])) {
return false;
} else {
return true;
}
break;
case column_type::lower_bound: case column_type::lower_bound:
if (this->below_bound(x, this->m_lower_bounds[j])) { return !this->below_bound(x, this->m_lower_bounds[j]);
return false;
} else {
return true;
}
break;
case column_type::upper_bound: case column_type::upper_bound:
if (this->above_bound(x, this->m_upper_bounds[j])) { return !this->above_bound(x, this->m_upper_bounds[j]);
return false;
} else {
return true;
}
break;
case column_type::free_column: case column_type::free_column:
return true; return true;
break; break;
@ -598,7 +582,7 @@ divide_row_by_pivot(unsigned pivot_row, unsigned pivot_col) {
if (is_zero(coeff)) if (is_zero(coeff))
return false; return false;
this->m_b[pivot_row] /= coeff; // this->m_b[pivot_row] /= coeff;
for (unsigned j = 0; j < size; j++) { for (unsigned j = 0; j < size; j++) {
auto & c = row[j]; auto & c = row[j];
if (c.var() != pivot_col) { if (c.var() != pivot_col) {
@ -662,58 +646,51 @@ basis_has_no_doubles() const {
template <typename T, typename X> bool lp_core_solver_base<T, X>:: template <typename T, typename X> bool lp_core_solver_base<T, X>::
non_basis_has_no_doubles() const { non_basis_has_no_doubles() const {
std::set<int> bm; std::set<int> bm;
for (auto j : m_nbasis) { for (auto j : m_nbasis)
bm.insert(j); bm.insert(j);
}
return bm.size() == m_nbasis.size(); return bm.size() == m_nbasis.size();
} }
template <typename T, typename X> bool lp_core_solver_base<T, X>:: template <typename T, typename X> bool lp_core_solver_base<T, X>::
basis_is_correctly_represented_in_heading() const { basis_is_correctly_represented_in_heading() const {
for (unsigned i = 0; i < m_m(); i++) { for (unsigned i = 0; i < m_m(); i++)
if (m_basis_heading[m_basis[i]] != static_cast<int>(i)) if (m_basis_heading[m_basis[i]] != static_cast<int>(i))
return false; return false;
}
return true; return true;
} }
template <typename T, typename X> bool lp_core_solver_base<T, X>:: template <typename T, typename X> bool lp_core_solver_base<T, X>::
non_basis_is_correctly_represented_in_heading() const { non_basis_is_correctly_represented_in_heading() const {
for (unsigned i = 0; i < m_nbasis.size(); i++) { for (unsigned i = 0; i < m_nbasis.size(); i++)
if (m_basis_heading[m_nbasis[i]] != - static_cast<int>(i) - 1) if (m_basis_heading[m_nbasis[i]] != - static_cast<int>(i) - 1)
return false; return false;
}
for (unsigned j = 0; j < m_A.column_count(); j++) { for (unsigned j = 0; j < m_A.column_count(); j++)
if (m_basis_heading[j] >= 0) { if (m_basis_heading[j] >= 0)
lp_assert(static_cast<unsigned>(m_basis_heading[j]) < m_A.row_count() && m_basis[m_basis_heading[j]] == j); lp_assert(static_cast<unsigned>(m_basis_heading[j]) < m_A.row_count() && m_basis[m_basis_heading[j]] == j);
}
}
return true; return true;
} }
template <typename T, typename X> bool lp_core_solver_base<T, X>:: template <typename T, typename X> bool lp_core_solver_base<T, X>::
basis_heading_is_correct() const { basis_heading_is_correct() const {
if ( m_A.column_count() > 10 ) { // for the performance reason if ( m_A.column_count() > 10 ) // for the performance reason
return true; return true;
}
lp_assert(m_basis_heading.size() == m_A.column_count()); lp_assert(m_basis_heading.size() == m_A.column_count());
lp_assert(m_basis.size() == m_A.row_count()); lp_assert(m_basis.size() == m_A.row_count());
lp_assert(m_nbasis.size() <= m_A.column_count() - m_A.row_count()); // for the dual the size of non basis can be smaller lp_assert(m_nbasis.size() <= m_A.column_count() - m_A.row_count()); // for the dual the size of non basis can be smaller
if (!basis_has_no_doubles()) {
return false;
}
if (!non_basis_has_no_doubles()) { if (!basis_has_no_doubles())
return false; return false;
}
if (!basis_is_correctly_represented_in_heading()) { if (!non_basis_has_no_doubles())
return false; return false;
}
if (!non_basis_is_correctly_represented_in_heading()) { if (!basis_is_correctly_represented_in_heading())
return false; return false;
}
if (!non_basis_is_correctly_represented_in_heading())
return false;
return true; return true;
} }
@ -781,14 +758,6 @@ column_name(unsigned column) const {
return m_column_names.get_variable_name(column); return m_column_names.get_variable_name(column);
} }
template <typename T, typename X> void lp_core_solver_base<T, X>::
copy_right_side(vector<X> & rs) {
unsigned i = m_m();
while (i --) {
rs[i] = m_b[i];
}
}
template <typename T, typename X> void lp_core_solver_base<T, X>:: template <typename T, typename X> void lp_core_solver_base<T, X>::
add_delta_to_xB(vector<X> & del) { add_delta_to_xB(vector<X> & del) {
unsigned i = m_m(); unsigned i = m_m();
@ -819,7 +788,8 @@ solve_Ax_eq_b() {
rs_minus_Anx(rs); rs_minus_Anx(rs);
m_factorization->solve_By(rs); m_factorization->solve_By(rs);
copy_rs_to_xB(rs); copy_rs_to_xB(rs);
} else { }
else {
vector<X> rs(m_m()); vector<X> rs(m_m());
rs_minus_Anx(rs); rs_minus_Anx(rs);
vector<X> rrs = rs; // another copy of rs vector<X> rrs = rs; // another copy of rs

View file

@ -61,7 +61,7 @@ public:
lp_settings & settings, lp_settings & settings,
const column_namer & column_names): const column_namer & column_names):
lp_core_solver_base<T, X>(A, lp_core_solver_base<T, X>(A,
b, // b,
basis, basis,
nbasis, nbasis,
heading, heading,

View file

@ -948,7 +948,7 @@ public:
const vector<X> & upper_bound_values, const vector<X> & upper_bound_values,
lp_settings & settings, lp_settings & settings,
const column_namer& column_names): const column_namer& column_names):
lp_core_solver_base<T, X>(A, b, lp_core_solver_base<T, X>(A, // b,
basis, basis,
nbasis, nbasis,
heading, heading,
@ -983,7 +983,7 @@ public:
const vector<X> & upper_bound_values, const vector<X> & upper_bound_values,
lp_settings & settings, lp_settings & settings,
const column_namer& column_names): const column_namer& column_names):
lp_core_solver_base<T, X>(A, b, lp_core_solver_base<T, X>(A, // b,
basis, basis,
nbasis, nbasis,
heading, heading,