3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-16 05:48:44 +00:00

fix a bug in the lar_solver::m_status update during push/pop

Signed-off-by: Lev Nachmanson <levnach@microsoft.com>
This commit is contained in:
Lev Nachmanson 2017-07-10 16:34:23 -07:00
parent 581098299b
commit 2fe846d9fc
19 changed files with 212 additions and 190 deletions

View file

@ -84,7 +84,7 @@ void run_solver(lp_params & params, char const * mps_file_name) {
solver->find_maximal_solution(); solver->find_maximal_solution();
*(solver->settings().get_message_ostream()) << "status is " << lp_status_to_string(solver->get_status()) << std::endl; *(solver->settings().get_message_ostream()) << "status is " << lp_status_to_string(solver->get_status()) << std::endl;
if (solver->get_status() == lp::OPTIMAL) { if (solver->get_status() == lp::lp_status::OPTIMAL) {
if (params.min()) { if (params.min()) {
solver->flip_costs(); solver->flip_costs();
} }

View file

@ -1165,6 +1165,7 @@ namespace smt {
} }
final_check_status final_check_eh() { final_check_status final_check_eh() {
TRACE("lar_solver", tout << "ddd=" <<++lp::lp_settings::ddd << std::endl;);
m_use_nra_model = false; m_use_nra_model = false;
lbool is_sat = l_true; lbool is_sat = l_true;
if (m_solver->get_status() != lp::lp_status::OPTIMAL) { if (m_solver->get_status() != lp::lp_status::OPTIMAL) {

View file

@ -1656,7 +1656,7 @@ void solve_some_mps(argument_parser & args_parser) {
} }
if (!solve_for_rational) { if (!solve_for_rational) {
solve_mps(file_names[6], false, 0, time_limit, false, dual, compare_with_primal, args_parser); solve_mps(file_names[6], false, 0, time_limit, false, dual, compare_with_primal, args_parser);
solve_mps_with_known_solution(file_names[3], nullptr, INFEASIBLE, dual); // chvatal: 135(d) solve_mps_with_known_solution(file_names[3], nullptr, lp_status::INFEASIBLE, dual); // chvatal: 135(d)
std::unordered_map<std::string, double> sol; std::unordered_map<std::string, double> sol;
sol["X1"] = 0; sol["X1"] = 0;
sol["X2"] = 6; sol["X2"] = 6;
@ -1666,8 +1666,8 @@ void solve_some_mps(argument_parser & args_parser) {
sol["X6"] = 1; sol["X6"] = 1;
sol["X7"] = 1; sol["X7"] = 1;
sol["X8"] = 0; sol["X8"] = 0;
solve_mps_with_known_solution(file_names[9], &sol, OPTIMAL, dual); solve_mps_with_known_solution(file_names[9], &sol, lp_status::OPTIMAL, dual);
solve_mps_with_known_solution(file_names[0], &sol, OPTIMAL, dual); solve_mps_with_known_solution(file_names[0], &sol, lp_status::OPTIMAL, dual);
sol.clear(); sol.clear();
sol["X1"] = 25.0/14.0; sol["X1"] = 25.0/14.0;
// sol["X2"] = 0; // sol["X2"] = 0;
@ -1676,10 +1676,10 @@ void solve_some_mps(argument_parser & args_parser) {
// sol["X5"] = 0; // sol["X5"] = 0;
// sol["X6"] = 0; // sol["X6"] = 0;
// sol["X7"] = 9.0/14.0; // sol["X7"] = 9.0/14.0;
solve_mps_with_known_solution(file_names[5], &sol, OPTIMAL, dual); // chvatal: 135(e) solve_mps_with_known_solution(file_names[5], &sol, lp_status::OPTIMAL, dual); // chvatal: 135(e)
solve_mps_with_known_solution(file_names[4], &sol, OPTIMAL, dual); // chvatal: 135(e) solve_mps_with_known_solution(file_names[4], &sol, lp_status::OPTIMAL, dual); // chvatal: 135(e)
solve_mps_with_known_solution(file_names[2], nullptr, UNBOUNDED, dual); // chvatal: 135(c) solve_mps_with_known_solution(file_names[2], nullptr, lp_status::UNBOUNDED, dual); // chvatal: 135(c)
solve_mps_with_known_solution(file_names[1], nullptr, UNBOUNDED, dual); // chvatal: 135(b) solve_mps_with_known_solution(file_names[1], nullptr, lp_status::UNBOUNDED, dual); // chvatal: 135(b)
solve_mps(file_names[8], false, 0, time_limit, false, dual, compare_with_primal, args_parser); solve_mps(file_names[8], false, 0, time_limit, false, dual, compare_with_primal, args_parser);
// return; // return;
for (auto& s : file_names) { for (auto& s : file_names) {
@ -1745,7 +1745,7 @@ void solve_rational() {
expected_sol["x7"] = lp::mpq(1); expected_sol["x7"] = lp::mpq(1);
expected_sol["x8"] = lp::mpq(0); expected_sol["x8"] = lp::mpq(0);
solver.find_maximal_solution(); solver.find_maximal_solution();
lp_assert(solver.get_status() == OPTIMAL); lp_assert(solver.get_status() == lp_status::OPTIMAL);
for (auto it : expected_sol) { for (auto it : expected_sol) {
lp_assert(it.second == solver.get_column_value_by_name(it.first)); lp_assert(it.second == solver.get_column_value_by_name(it.first));
} }
@ -2433,12 +2433,12 @@ void run_lar_solver(argument_parser & args_parser, lar_solver * solver, mps_read
sw.start(); sw.start();
lp_status status = solver->solve(); lp_status status = solver->solve();
std::cout << "status is " << lp_status_to_string(status) << ", processed for " << sw.get_current_seconds() <<" seconds, and " << solver->get_total_iterations() << " iterations" << std::endl; std::cout << "status is " << lp_status_to_string(status) << ", processed for " << sw.get_current_seconds() <<" seconds, and " << solver->get_total_iterations() << " iterations" << std::endl;
if (solver->get_status() == INFEASIBLE) { if (solver->get_status() == lp_status::INFEASIBLE) {
vector<std::pair<lp::mpq, constraint_index>> evidence; vector<std::pair<lp::mpq, constraint_index>> evidence;
solver->get_infeasibility_explanation(evidence); solver->get_infeasibility_explanation(evidence);
} }
if (args_parser.option_is_used("--randomize_lar")) { if (args_parser.option_is_used("--randomize_lar")) {
if (solver->get_status() != OPTIMAL) { if (solver->get_status() != lp_status::OPTIMAL) {
std::cout << "cannot check randomize on an infeazible problem" << std::endl; std::cout << "cannot check randomize on an infeazible problem" << std::endl;
return; return;
} }
@ -2717,7 +2717,7 @@ void test_term() {
auto status = solver.solve(); auto status = solver.solve();
std::cout << lp_status_to_string(status) << std::endl; std::cout << lp_status_to_string(status) << std::endl;
std::unordered_map<var_index, mpq> model; std::unordered_map<var_index, mpq> model;
if (status != OPTIMAL) if (status != lp_status::OPTIMAL)
return; return;
solver.get_model(model); solver.get_model(model);
@ -2745,7 +2745,7 @@ void test_evidence_for_total_inf_simple(argument_parser & args_parser) {
auto status = solver.solve(); auto status = solver.solve();
std::cout << lp_status_to_string(status) << std::endl; std::cout << lp_status_to_string(status) << std::endl;
std::unordered_map<var_index, mpq> model; std::unordered_map<var_index, mpq> model;
lp_assert(solver.get_status() == INFEASIBLE); lp_assert(solver.get_status() == lp_status::INFEASIBLE);
} }
void test_bound_propagation_one_small_sample1() { void test_bound_propagation_one_small_sample1() {
/* /*

View file

@ -19,7 +19,7 @@ void int_solver::fix_non_base_columns() {
} }
if (!change) if (!change)
return; return;
if (m_lar_solver->find_feasible_solution() == INFEASIBLE) if (m_lar_solver->find_feasible_solution() == lp_status::INFEASIBLE)
failed(); failed();
init_inf_int_set(); init_inf_int_set();
lp_assert(is_feasible() && inf_int_set_is_correct()); lp_assert(is_feasible() && inf_int_set_is_correct());
@ -109,14 +109,13 @@ int int_solver::find_inf_int_boxed_base_column_with_smallest_range() {
} }
bool int_solver::mk_gomory_cut(unsigned row_index, explanation & ex) { bool int_solver::mk_gomory_cut(unsigned row_index, explanation & ex) {
lp_assert(false);
return true; auto row_it = m_lar_solver->get_iterator_on_row(row_index);
unsigned x_i = m_lar_solver->get_base_column_in_row(row_index);
lp_assert(column_is_int_inf(x_i));
/* /*
const auto & row = m_lar_solver->A_r().m_rows[row_index];
// The following assertion is wrong. It may be violated in mixed-integer problems.
// SASSERT(!all_coeff_int(r));
theory_var x_i = r.get_base_var();
SASSERT(is_int(x_i)); SASSERT(is_int(x_i));
// The following assertion is wrong. It may be violated in mixed-real-interger problems. // The following assertion is wrong. It may be violated in mixed-real-interger problems.
// The check is_gomory_cut_target will discard rows where any variable contains infinitesimals. // The check is_gomory_cut_target will discard rows where any variable contains infinitesimals.
@ -286,6 +285,8 @@ bool int_solver::mk_gomory_cut(unsigned row_index, explanation & ex) {
ante.eqs().size(), ante.eqs().c_ptr(), ante, l))); ante.eqs().size(), ante.eqs().c_ptr(), ante, l)));
return true; return true;
*/ */
delete row_it;
return true;
} }

View file

@ -230,7 +230,7 @@ void lar_core_solver::solve() {
lp_assert(m_r_solver.non_basic_columns_are_set_correctly()); lp_assert(m_r_solver.non_basic_columns_are_set_correctly());
lp_assert(m_r_solver.inf_set_is_correct()); lp_assert(m_r_solver.inf_set_is_correct());
if (m_r_solver.current_x_is_feasible() && m_r_solver.m_look_for_feasible_solution_only) { if (m_r_solver.current_x_is_feasible() && m_r_solver.m_look_for_feasible_solution_only) {
m_r_solver.set_status(OPTIMAL); m_r_solver.set_status(lp_status::OPTIMAL);
return; return;
} }
++settings().st().m_need_to_solve_inf; ++settings().st().m_need_to_solve_inf;
@ -240,8 +240,8 @@ void lar_core_solver::solve() {
prefix_d(); prefix_d();
lar_solution_signature solution_signature; lar_solution_signature solution_signature;
vector<unsigned> changes_of_basis = find_solution_signature_with_doubles(solution_signature); vector<unsigned> changes_of_basis = find_solution_signature_with_doubles(solution_signature);
if (m_d_solver.get_status() == TIME_EXHAUSTED) { if (m_d_solver.get_status() == lp_status::TIME_EXHAUSTED) {
m_r_solver.set_status(TIME_EXHAUSTED); m_r_solver.set_status(lp_status::TIME_EXHAUSTED);
return; return;
} }
if (settings().use_tableau()) if (settings().use_tableau())
@ -262,10 +262,10 @@ void lar_core_solver::solve() {
m_r_solver.solve(); m_r_solver.solve();
lp_assert(!settings().use_tableau() || r_basis_is_OK()); lp_assert(!settings().use_tableau() || r_basis_is_OK());
} }
if (m_r_solver.get_status() == INFEASIBLE) { if (m_r_solver.get_status() == lp_status::INFEASIBLE) {
fill_not_improvable_zero_sum(); fill_not_improvable_zero_sum();
} else if (m_r_solver.get_status() != UNBOUNDED) { } else if (m_r_solver.get_status() != lp_status::UNBOUNDED) {
m_r_solver.set_status(OPTIMAL); m_r_solver.set_status(lp_status::OPTIMAL);
} }
lp_assert(r_basis_is_OK()); lp_assert(r_basis_is_OK());
lp_assert(m_r_solver.non_basic_columns_are_set_correctly()); lp_assert(m_r_solver.non_basic_columns_are_set_correctly());

View file

@ -27,7 +27,7 @@ void clear() {lp_assert(false); // not implemented
} }
lar_solver::lar_solver() : m_status(OPTIMAL), lar_solver::lar_solver() : m_status(lp_status::OPTIMAL),
m_infeasible_column_index(-1), m_infeasible_column_index(-1),
m_terms_start_index(1000000), m_terms_start_index(1000000),
m_mpq_lar_core_solver(m_settings, *this) m_mpq_lar_core_solver(m_settings, *this)
@ -293,11 +293,11 @@ lp_status lar_solver::find_feasible_solution() {
} }
lp_status lar_solver::solve() { lp_status lar_solver::solve() {
if (m_status == INFEASIBLE) { if (m_status == lp_status::INFEASIBLE) {
return m_status; return m_status;
} }
solve_with_core_solver(); solve_with_core_solver();
if (m_status != INFEASIBLE) { if (m_status != lp_status::INFEASIBLE) {
if (m_settings.bound_propagation()) if (m_settings.bound_propagation())
detect_rows_with_changed_bounds(); detect_rows_with_changed_bounds();
} }
@ -325,7 +325,6 @@ vector<unsigned> lar_solver::get_list_of_all_var_indices() const {
void lar_solver::push() { void lar_solver::push() {
m_simplex_strategy = m_settings.simplex_strategy(); m_simplex_strategy = m_settings.simplex_strategy();
m_simplex_strategy.push(); m_simplex_strategy.push();
m_status.push();
m_vars_to_ul_pairs.push(); m_vars_to_ul_pairs.push();
m_infeasible_column_index.push(); m_infeasible_column_index.push();
m_mpq_lar_core_solver.push(); m_mpq_lar_core_solver.push();
@ -335,7 +334,7 @@ void lar_solver::push() {
m_constraint_count.push(); m_constraint_count.push();
} }
void lar_solver::clean_large_elements_after_pop(unsigned n, int_set& set) { void lar_solver::clean_popped_elements(unsigned n, int_set& set) {
vector<int> to_remove; vector<int> to_remove;
for (unsigned j: set.m_index) for (unsigned j: set.m_index)
if (j >= n) if (j >= n)
@ -345,14 +344,15 @@ void lar_solver::clean_large_elements_after_pop(unsigned n, int_set& set) {
} }
void lar_solver::shrink_inf_set_after_pop(unsigned n, int_set & set) { void lar_solver::shrink_inf_set_after_pop(unsigned n, int_set & set) {
clean_large_elements_after_pop(n, set); clean_popped_elements(n, set);
set.resize(n); set.resize(n);
} }
void lar_solver::pop(unsigned k) { void lar_solver::pop(unsigned k) {
TRACE("lar_solver", tout << "k = " << k << std::endl;);
int n_was = static_cast<int>(m_ext_vars_to_columns.size()); int n_was = static_cast<int>(m_ext_vars_to_columns.size());
m_status.pop(k);
m_infeasible_column_index.pop(k); m_infeasible_column_index.pop(k);
unsigned n = m_vars_to_ul_pairs.peek_size(k); unsigned n = m_vars_to_ul_pairs.peek_size(k);
for (unsigned j = n_was; j-- > n;) for (unsigned j = n_was; j-- > n;)
@ -364,10 +364,11 @@ void lar_solver::pop(unsigned k) {
m_vars_to_ul_pairs.pop(k); m_vars_to_ul_pairs.pop(k);
m_mpq_lar_core_solver.pop(k); m_mpq_lar_core_solver.pop(k);
clean_large_elements_after_pop(n, m_columns_with_changed_bound); clean_popped_elements(n, m_columns_with_changed_bound);
unsigned m = A_r().row_count(); unsigned m = A_r().row_count();
clean_large_elements_after_pop(m, m_rows_with_changed_bounds); clean_popped_elements(m, m_rows_with_changed_bounds);
clean_inf_set_of_r_solver_after_pop(); clean_inf_set_of_r_solver_after_pop();
m_status = m_mpq_lar_core_solver.m_r_solver.current_x_is_feasible()? lp_status::OPTIMAL: lp_status::UNKNOWN;
lp_assert(m_settings.simplex_strategy() == simplex_strategy_enum::undecided || lp_assert(m_settings.simplex_strategy() == simplex_strategy_enum::undecided ||
(!use_tableau()) || m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau()); (!use_tableau()) || m_mpq_lar_core_solver.m_r_solver.reduced_costs_are_correct_tableau());
@ -404,7 +405,7 @@ bool lar_solver::maximize_term_on_tableau(const vector<std::pair<mpq, var_index>
decide_on_strategy_and_adjust_initial_state(); decide_on_strategy_and_adjust_initial_state();
m_mpq_lar_core_solver.solve(); m_mpq_lar_core_solver.solve();
if (m_mpq_lar_core_solver.m_r_solver.get_status() == UNBOUNDED) if (m_mpq_lar_core_solver.m_r_solver.get_status() == lp_status::UNBOUNDED)
return false; return false;
term_max = 0; term_max = 0;
@ -482,7 +483,7 @@ bool lar_solver::maximize_term_on_corrected_r_solver(const vector<std::pair<mpq,
bool ret = maximize_term_on_tableau(term, term_max); bool ret = maximize_term_on_tableau(term, term_max);
settings().simplex_strategy() = simplex_strategy_enum::tableau_rows; settings().simplex_strategy() = simplex_strategy_enum::tableau_rows;
set_costs_to_zero(term); set_costs_to_zero(term);
m_mpq_lar_core_solver.m_r_solver.set_status(OPTIMAL); m_mpq_lar_core_solver.m_r_solver.set_status(lp_status::OPTIMAL);
return ret; return ret;
} }
case simplex_strategy_enum::tableau_costs: case simplex_strategy_enum::tableau_costs:
@ -490,7 +491,7 @@ bool lar_solver::maximize_term_on_corrected_r_solver(const vector<std::pair<mpq,
{ {
bool ret = maximize_term_on_tableau(term, term_max); bool ret = maximize_term_on_tableau(term, term_max);
set_costs_to_zero(term); set_costs_to_zero(term);
m_mpq_lar_core_solver.m_r_solver.set_status(OPTIMAL); m_mpq_lar_core_solver.m_r_solver.set_status(lp_status::OPTIMAL);
return ret; return ret;
} }
@ -732,7 +733,7 @@ void lar_solver::solve_with_core_solver() {
update_x_and_inf_costs_for_columns_with_changed_bounds(); update_x_and_inf_costs_for_columns_with_changed_bounds();
m_mpq_lar_core_solver.solve(); m_mpq_lar_core_solver.solve();
set_status(m_mpq_lar_core_solver.m_r_solver.get_status()); set_status(m_mpq_lar_core_solver.m_r_solver.get_status());
lp_assert(m_status != OPTIMAL || all_constraints_hold()); lp_assert(m_status != lp_status::OPTIMAL || all_constraints_hold());
} }
@ -1113,7 +1114,7 @@ void lar_solver::get_infeasibility_explanation_for_inf_sign(
void lar_solver::get_model(std::unordered_map<var_index, mpq> & variable_values) const { void lar_solver::get_model(std::unordered_map<var_index, mpq> & variable_values) const {
mpq delta = mpq(1, 2); // start from 0.5 to have less clashes mpq delta = mpq(1, 2); // start from 0.5 to have less clashes
lp_assert(m_status == OPTIMAL); lp_assert(m_status == lp_status::OPTIMAL);
unsigned i; unsigned i;
do { do {
@ -1353,7 +1354,7 @@ void lar_solver::pop_tableau() {
void lar_solver::clean_inf_set_of_r_solver_after_pop() { void lar_solver::clean_inf_set_of_r_solver_after_pop() {
vector<unsigned> became_feas; vector<unsigned> became_feas;
clean_large_elements_after_pop(A_r().column_count(), m_mpq_lar_core_solver.m_r_solver.m_inf_set); clean_popped_elements(A_r().column_count(), m_mpq_lar_core_solver.m_r_solver.m_inf_set);
std::unordered_set<unsigned> basic_columns_with_changed_cost; std::unordered_set<unsigned> basic_columns_with_changed_cost;
auto inf_index_copy = m_mpq_lar_core_solver.m_r_solver.m_inf_set.m_index; auto inf_index_copy = m_mpq_lar_core_solver.m_r_solver.m_inf_set.m_index;
for (auto j: inf_index_copy) { for (auto j: inf_index_copy) {
@ -1598,6 +1599,7 @@ bool lar_solver::bound_is_integer_if_needed(unsigned j, const mpq & right_side)
} }
constraint_index lar_solver::add_var_bound(var_index j, lconstraint_kind kind, const mpq & right_side) { constraint_index lar_solver::add_var_bound(var_index j, lconstraint_kind kind, const mpq & right_side) {
TRACE("lar_solver", tout << "j = " << j << std::endl;);
constraint_index ci = m_constraints.size(); constraint_index ci = m_constraints.size();
if (!is_term(j)) { // j is a var if (!is_term(j)) { // j is a var
lp_assert(bound_is_integer_if_needed(j, right_side)); lp_assert(bound_is_integer_if_needed(j, right_side));
@ -1816,7 +1818,7 @@ void lar_solver::update_upper_bound_column_type_and_bound(var_index j, lconstrai
set_low_bound_witness(j, ci); set_low_bound_witness(j, ci);
m_columns_with_changed_bound.insert(j); m_columns_with_changed_bound.insert(j);
if (low > m_mpq_lar_core_solver.m_r_upper_bounds[j]) { if (low > m_mpq_lar_core_solver.m_r_upper_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
m_infeasible_column_index = j; m_infeasible_column_index = j;
} }
else { else {
@ -1828,7 +1830,7 @@ void lar_solver::update_upper_bound_column_type_and_bound(var_index j, lconstrai
{ {
auto v = numeric_pair<mpq>(right_side, zero_of_type<mpq>()); auto v = numeric_pair<mpq>(right_side, zero_of_type<mpq>());
if (v > m_mpq_lar_core_solver.m_r_upper_bounds[j]) { if (v > m_mpq_lar_core_solver.m_r_upper_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
set_low_bound_witness(j, ci); set_low_bound_witness(j, ci);
m_infeasible_column_index = j; m_infeasible_column_index = j;
} }
@ -1850,7 +1852,7 @@ void lar_solver::update_upper_bound_column_type_and_bound(var_index j, lconstrai
} }
void lar_solver::update_boxed_column_type_and_bound(var_index j, lconstraint_kind kind, const mpq & right_side, constraint_index ci) { void lar_solver::update_boxed_column_type_and_bound(var_index j, lconstraint_kind kind, const mpq & right_side, constraint_index ci) {
lp_assert(m_status == INFEASIBLE || (m_mpq_lar_core_solver.m_column_types()[j] == column_type::boxed && m_mpq_lar_core_solver.m_r_low_bounds()[j] < m_mpq_lar_core_solver.m_r_upper_bounds()[j])); lp_assert(m_status == lp_status::INFEASIBLE || (m_mpq_lar_core_solver.m_column_types()[j] == column_type::boxed && m_mpq_lar_core_solver.m_r_low_bounds()[j] < m_mpq_lar_core_solver.m_r_upper_bounds()[j]));
mpq y_of_bound(0); mpq y_of_bound(0);
switch (kind) { switch (kind) {
case LT: case LT:
@ -1865,7 +1867,7 @@ void lar_solver::update_boxed_column_type_and_bound(var_index j, lconstraint_kin
} }
if (up < m_mpq_lar_core_solver.m_r_low_bounds[j]) { if (up < m_mpq_lar_core_solver.m_r_low_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
lp_assert(false); lp_assert(false);
m_infeasible_column_index = j; m_infeasible_column_index = j;
} }
@ -1886,7 +1888,7 @@ void lar_solver::update_boxed_column_type_and_bound(var_index j, lconstraint_kin
set_low_bound_witness(j, ci); set_low_bound_witness(j, ci);
} }
if (low > m_mpq_lar_core_solver.m_r_upper_bounds[j]) { if (low > m_mpq_lar_core_solver.m_r_upper_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
m_infeasible_column_index = j; m_infeasible_column_index = j;
} }
else if (low == m_mpq_lar_core_solver.m_r_upper_bounds[j]) { else if (low == m_mpq_lar_core_solver.m_r_upper_bounds[j]) {
@ -1898,12 +1900,12 @@ void lar_solver::update_boxed_column_type_and_bound(var_index j, lconstraint_kin
{ {
auto v = numeric_pair<mpq>(right_side, zero_of_type<mpq>()); auto v = numeric_pair<mpq>(right_side, zero_of_type<mpq>());
if (v < m_mpq_lar_core_solver.m_r_low_bounds[j]) { if (v < m_mpq_lar_core_solver.m_r_low_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
m_infeasible_column_index = j; m_infeasible_column_index = j;
set_upper_bound_witness(j, ci); set_upper_bound_witness(j, ci);
} }
else if (v > m_mpq_lar_core_solver.m_r_upper_bounds[j]) { else if (v > m_mpq_lar_core_solver.m_r_upper_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
m_infeasible_column_index = j; m_infeasible_column_index = j;
set_low_bound_witness(j, ci); set_low_bound_witness(j, ci);
} }
@ -1937,7 +1939,7 @@ void lar_solver::update_low_bound_column_type_and_bound(var_index j, lconstraint
m_columns_with_changed_bound.insert(j); m_columns_with_changed_bound.insert(j);
if (up < m_mpq_lar_core_solver.m_r_low_bounds[j]) { if (up < m_mpq_lar_core_solver.m_r_low_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
m_infeasible_column_index = j; m_infeasible_column_index = j;
} }
else { else {
@ -1961,7 +1963,7 @@ void lar_solver::update_low_bound_column_type_and_bound(var_index j, lconstraint
{ {
auto v = numeric_pair<mpq>(right_side, zero_of_type<mpq>()); auto v = numeric_pair<mpq>(right_side, zero_of_type<mpq>());
if (v < m_mpq_lar_core_solver.m_r_low_bounds[j]) { if (v < m_mpq_lar_core_solver.m_r_low_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
m_infeasible_column_index = j; m_infeasible_column_index = j;
set_upper_bound_witness(j, ci); set_upper_bound_witness(j, ci);
} }
@ -1982,15 +1984,15 @@ void lar_solver::update_low_bound_column_type_and_bound(var_index j, lconstraint
} }
void lar_solver::update_fixed_column_type_and_bound(var_index j, lconstraint_kind kind, const mpq & right_side, constraint_index ci) { void lar_solver::update_fixed_column_type_and_bound(var_index j, lconstraint_kind kind, const mpq & right_side, constraint_index ci) {
lp_assert(m_status == INFEASIBLE || (m_mpq_lar_core_solver.m_column_types()[j] == column_type::fixed && m_mpq_lar_core_solver.m_r_low_bounds()[j] == m_mpq_lar_core_solver.m_r_upper_bounds()[j])); lp_assert(m_status == lp_status::INFEASIBLE || (m_mpq_lar_core_solver.m_column_types()[j] == column_type::fixed && m_mpq_lar_core_solver.m_r_low_bounds()[j] == m_mpq_lar_core_solver.m_r_upper_bounds()[j]));
lp_assert(m_status == INFEASIBLE || (m_mpq_lar_core_solver.m_r_low_bounds()[j].y.is_zero() && m_mpq_lar_core_solver.m_r_upper_bounds()[j].y.is_zero())); lp_assert(m_status == lp_status::INFEASIBLE || (m_mpq_lar_core_solver.m_r_low_bounds()[j].y.is_zero() && m_mpq_lar_core_solver.m_r_upper_bounds()[j].y.is_zero()));
auto v = numeric_pair<mpq>(right_side, mpq(0)); auto v = numeric_pair<mpq>(right_side, mpq(0));
mpq y_of_bound(0); mpq y_of_bound(0);
switch (kind) { switch (kind) {
case LT: case LT:
if (v <= m_mpq_lar_core_solver.m_r_low_bounds[j]) { if (v <= m_mpq_lar_core_solver.m_r_low_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
m_infeasible_column_index = j; m_infeasible_column_index = j;
set_upper_bound_witness(j, ci); set_upper_bound_witness(j, ci);
} }
@ -1998,7 +2000,7 @@ void lar_solver::update_fixed_column_type_and_bound(var_index j, lconstraint_kin
case LE: case LE:
{ {
if (v < m_mpq_lar_core_solver.m_r_low_bounds[j]) { if (v < m_mpq_lar_core_solver.m_r_low_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
m_infeasible_column_index = j; m_infeasible_column_index = j;
set_upper_bound_witness(j, ci); set_upper_bound_witness(j, ci);
} }
@ -2007,7 +2009,7 @@ void lar_solver::update_fixed_column_type_and_bound(var_index j, lconstraint_kin
case GT: case GT:
{ {
if (v >= m_mpq_lar_core_solver.m_r_upper_bounds[j]) { if (v >= m_mpq_lar_core_solver.m_r_upper_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
m_infeasible_column_index = j; m_infeasible_column_index = j;
set_low_bound_witness(j, ci); set_low_bound_witness(j, ci);
} }
@ -2016,7 +2018,7 @@ void lar_solver::update_fixed_column_type_and_bound(var_index j, lconstraint_kin
case GE: case GE:
{ {
if (v > m_mpq_lar_core_solver.m_r_upper_bounds[j]) { if (v > m_mpq_lar_core_solver.m_r_upper_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
m_infeasible_column_index = j; m_infeasible_column_index = j;
set_low_bound_witness(j, ci); set_low_bound_witness(j, ci);
} }
@ -2025,12 +2027,12 @@ void lar_solver::update_fixed_column_type_and_bound(var_index j, lconstraint_kin
case EQ: case EQ:
{ {
if (v < m_mpq_lar_core_solver.m_r_low_bounds[j]) { if (v < m_mpq_lar_core_solver.m_r_low_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
m_infeasible_column_index = j; m_infeasible_column_index = j;
set_upper_bound_witness(j, ci); set_upper_bound_witness(j, ci);
} }
else if (v > m_mpq_lar_core_solver.m_r_upper_bounds[j]) { else if (v > m_mpq_lar_core_solver.m_r_upper_bounds[j]) {
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
m_infeasible_column_index = j; m_infeasible_column_index = j;
set_low_bound_witness(j, ci); set_low_bound_witness(j, ci);
} }

View file

@ -48,7 +48,7 @@ class lar_solver : public column_namer {
}; };
//////////////////// fields ////////////////////////// //////////////////// fields //////////////////////////
lp_settings m_settings; lp_settings m_settings;
stacked_value<lp_status> m_status; lp_status m_status;
stacked_value<simplex_strategy_enum> m_simplex_strategy; stacked_value<simplex_strategy_enum> m_simplex_strategy;
std::unordered_map<unsigned, ext_var_info> m_ext_vars_to_columns; std::unordered_map<unsigned, ext_var_info> m_ext_vars_to_columns;
vector<unsigned> m_columns_to_ext_vars_or_term_indices; vector<unsigned> m_columns_to_ext_vars_or_term_indices;
@ -222,7 +222,7 @@ public:
vector<unsigned> get_list_of_all_var_indices() const; vector<unsigned> get_list_of_all_var_indices() const;
void push(); void push();
static void clean_large_elements_after_pop(unsigned n, int_set& set); static void clean_popped_elements(unsigned n, int_set& set);
static void shrink_inf_set_after_pop(unsigned n, int_set & set); static void shrink_inf_set_after_pop(unsigned n, int_set & set);
@ -447,5 +447,14 @@ public:
} }
bool bound_is_integer_if_needed(unsigned j, const mpq & right_side) const; bool bound_is_integer_if_needed(unsigned j, const mpq & right_side) const;
linear_combination_iterator<mpq> * get_iterator_on_row(unsigned i) {
return m_mpq_lar_core_solver.m_r_solver.get_iterator_on_row(i);
}
unsigned get_base_column_in_row(unsigned row_index) const {
return m_mpq_lar_core_solver.m_r_solver.get_base_column_in_row(row_index);
}
}; };
} }

View file

@ -26,7 +26,14 @@ class lp_core_solver_base {
private: private:
lp_status m_status; lp_status m_status;
public: public:
bool current_x_is_feasible() const { return m_inf_set.size() == 0; } bool current_x_is_feasible() const {
TRACE("feas",
if (m_inf_set.size()) {
tout << "column " << m_inf_set.m_index[0] << " is infeasible" << std::endl;
}
);
return m_inf_set.size() == 0;
}
bool current_x_is_infeasible() const { return m_inf_set.size() != 0; } bool current_x_is_infeasible() const { return m_inf_set.size() != 0; }
int_set m_inf_set; int_set m_inf_set;
bool m_using_infeas_costs; bool m_using_infeas_costs;
@ -700,5 +707,8 @@ public:
} }
void calculate_pivot_row(unsigned i); void calculate_pivot_row(unsigned i);
unsigned get_base_column_in_row(unsigned row_index) const {
return m_basis[row_index];
}
}; };
} }

View file

@ -24,7 +24,7 @@ lp_core_solver_base(static_matrix<T, X> & A,
const vector<X> & upper_bound_values): const vector<X> & upper_bound_values):
m_total_iterations(0), m_total_iterations(0),
m_iters_with_no_cost_growing(0), m_iters_with_no_cost_growing(0),
m_status(FEASIBLE), m_status(lp_status::FEASIBLE),
m_inf_set(A.column_count()), m_inf_set(A.column_count()),
m_using_infeas_costs(false), m_using_infeas_costs(false),
m_pivot_row_of_B_1(A.row_count()), m_pivot_row_of_B_1(A.row_count()),
@ -534,7 +534,7 @@ update_basis_and_x(int entering, int leaving, X const & tt) {
if (!find_x_by_solving()) { if (!find_x_by_solving()) {
restore_x(entering, tt); restore_x(entering, tt);
if(A_mult_x_is_off()) { if(A_mult_x_is_off()) {
m_status = FLOATING_POINT_ERROR; m_status = lp_status::FLOATING_POINT_ERROR;
m_iters_with_no_cost_growing++; m_iters_with_no_cost_growing++;
return false; return false;
} }
@ -544,7 +544,7 @@ update_basis_and_x(int entering, int leaving, X const & tt) {
if (m_factorization->get_status() != LU_status::OK) { if (m_factorization->get_status() != LU_status::OK) {
std::stringstream s; std::stringstream s;
// s << "failing refactor on off_result for entering = " << entering << ", leaving = " << leaving << " total_iterations = " << total_iterations(); // s << "failing refactor on off_result for entering = " << entering << ", leaving = " << leaving << " total_iterations = " << total_iterations();
m_status = FLOATING_POINT_ERROR; m_status = lp_status::FLOATING_POINT_ERROR;
return false; return false;
} }
return false; return false;
@ -566,19 +566,19 @@ update_basis_and_x(int entering, int leaving, X const & tt) {
init_lu(); init_lu();
if (m_factorization->get_status() != LU_status::OK) { if (m_factorization->get_status() != LU_status::OK) {
if (m_look_for_feasible_solution_only && !precise()) { if (m_look_for_feasible_solution_only && !precise()) {
m_status = UNSTABLE; m_status = lp_status::UNSTABLE;
delete m_factorization; delete m_factorization;
m_factorization = nullptr; m_factorization = nullptr;
return false; return false;
} }
// LP_OUT(m_settings, "failing refactor for entering = " << entering << ", leaving = " << leaving << " total_iterations = " << total_iterations() << std::endl); // LP_OUT(m_settings, "failing refactor for entering = " << entering << ", leaving = " << leaving << " total_iterations = " << total_iterations() << std::endl);
restore_x_and_refactor(entering, leaving, tt); restore_x_and_refactor(entering, leaving, tt);
if (m_status == FLOATING_POINT_ERROR) if (m_status == lp_status::FLOATING_POINT_ERROR)
return false; return false;
lp_assert(!A_mult_x_is_off()); lp_assert(!A_mult_x_is_off());
m_iters_with_no_cost_growing++; m_iters_with_no_cost_growing++;
// LP_OUT(m_settings, "rolled back after failing of init_factorization()" << std::endl); // LP_OUT(m_settings, "rolled back after failing of init_factorization()" << std::endl);
m_status = UNSTABLE; m_status = lp_status::UNSTABLE;
return false; return false;
} }
return true; return true;
@ -960,7 +960,6 @@ template <typename T, typename X> void lp_core_solver_base<T, X>::pivot_fixed_v
unsigned basic_j = m_basis[i]; unsigned basic_j = m_basis[i];
if (get_column_type(basic_j) != column_type::fixed) continue; if (get_column_type(basic_j) != column_type::fixed) continue;
//todo run over the row here!!!!! call get_iterator_on_row();
T a; T a;
unsigned j; unsigned j;
auto * it = get_iterator_on_row(i); auto * it = get_iterator_on_row(i);

View file

@ -82,11 +82,11 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::start_with_ini
} }
template <typename T, typename X> bool lp_dual_core_solver<T, X>::done() { template <typename T, typename X> bool lp_dual_core_solver<T, X>::done() {
if (this->get_status() == OPTIMAL) { if (this->get_status() == lp_status::OPTIMAL) {
return true; return true;
} }
if (this->total_iterations() > this->m_settings.max_total_number_of_iterations) { // debug !!!! if (this->total_iterations() > this->m_settings.max_total_number_of_iterations) { // debug !!!!
this->set_status(ITERATIONS_EXHAUSTED); this->set_status(lp_status::ITERATIONS_EXHAUSTED);
return true; return true;
} }
return false; // todo, need to be more cases return false; // todo, need to be more cases
@ -170,8 +170,8 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::pricing_loop(u
} }
} while (i != initial_offset_in_rows && rows_left); } while (i != initial_offset_in_rows && rows_left);
if (m_r == -1) { if (m_r == -1) {
if (this->get_status() != UNSTABLE) { if (this->get_status() != lp_status::UNSTABLE) {
this->set_status(OPTIMAL); this->set_status(lp_status::OPTIMAL);
} }
} else { } else {
m_p = this->m_basis[m_r]; m_p = this->m_basis[m_r];
@ -181,10 +181,10 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::pricing_loop(u
return; return;
} }
// failure in advance_on_known_p // failure in advance_on_known_p
if (this->get_status() == FLOATING_POINT_ERROR) { if (this->get_status() == lp_status::FLOATING_POINT_ERROR) {
return; return;
} }
this->set_status(UNSTABLE); this->set_status(lp_status::UNSTABLE);
m_forbidden_rows.insert(m_r); m_forbidden_rows.insert(m_r);
} }
} }
@ -466,12 +466,12 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::revert_to_prev
this->change_basis_unconditionally(m_p, m_q); this->change_basis_unconditionally(m_p, m_q);
init_factorization(this->m_factorization, this->m_A, this->m_basis, this->m_settings); init_factorization(this->m_factorization, this->m_A, this->m_basis, this->m_settings);
if (this->m_factorization->get_status() != LU_status::OK) { if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status(FLOATING_POINT_ERROR); // complete failure this->set_status(lp_status::FLOATING_POINT_ERROR); // complete failure
return; return;
} }
recover_leaving(); recover_leaving();
if (!this->find_x_by_solving()) { if (!this->find_x_by_solving()) {
this->set_status(FLOATING_POINT_ERROR); this->set_status(lp_status::FLOATING_POINT_ERROR);
return; return;
} }
recalculate_xB_and_d(); recalculate_xB_and_d();
@ -551,10 +551,10 @@ template <typename T, typename X> bool lp_dual_core_solver<T, X>::delta_keeps_th
} }
template <typename T, typename X> void lp_dual_core_solver<T, X>::set_status_to_tentative_dual_unbounded_or_dual_unbounded() { template <typename T, typename X> void lp_dual_core_solver<T, X>::set_status_to_tentative_dual_unbounded_or_dual_unbounded() {
if (this->get_status() == TENTATIVE_DUAL_UNBOUNDED) { if (this->get_status() == lp_status::TENTATIVE_DUAL_UNBOUNDED) {
this->set_status(DUAL_UNBOUNDED); this->set_status(lp_status::DUAL_UNBOUNDED);
} else { } else {
this->set_status(TENTATIVE_DUAL_UNBOUNDED); this->set_status(lp_status::TENTATIVE_DUAL_UNBOUNDED);
} }
} }
@ -660,7 +660,7 @@ template <typename T, typename X> bool lp_dual_core_solver<T, X>::ratio_test() {
set_status_to_tentative_dual_unbounded_or_dual_unbounded(); set_status_to_tentative_dual_unbounded_or_dual_unbounded();
return false; return false;
} }
this->set_status(FEASIBLE); this->set_status(lp_status::FEASIBLE);
find_q_and_tight_set(); find_q_and_tight_set();
if (!tight_breakpoinst_are_all_boxed()) break; if (!tight_breakpoinst_are_all_boxed()) break;
T del = m_delta - delta_lost_on_flips_of_tight_breakpoints() * initial_delta_sign; T del = m_delta - delta_lost_on_flips_of_tight_breakpoints() * initial_delta_sign;
@ -716,10 +716,10 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::update_xb_afte
template <typename T, typename X> void lp_dual_core_solver<T, X>::one_iteration() { template <typename T, typename X> void lp_dual_core_solver<T, X>::one_iteration() {
unsigned number_of_rows_to_try = get_number_of_rows_to_try_for_leaving(); unsigned number_of_rows_to_try = get_number_of_rows_to_try_for_leaving();
unsigned offset_in_rows = this->m_settings.random_next() % this->m_m(); unsigned offset_in_rows = this->m_settings.random_next() % this->m_m();
if (this->get_status() == TENTATIVE_DUAL_UNBOUNDED) { if (this->get_status() == lp_status::TENTATIVE_DUAL_UNBOUNDED) {
number_of_rows_to_try = this->m_m(); number_of_rows_to_try = this->m_m();
} else { } else {
this->set_status(FEASIBLE); this->set_status(lp_status::FEASIBLE);
} }
pricing_loop(number_of_rows_to_try, offset_in_rows); pricing_loop(number_of_rows_to_try, offset_in_rows);
lp_assert(problem_is_dual_feasible()); lp_assert(problem_is_dual_feasible());
@ -736,7 +736,7 @@ template <typename T, typename X> void lp_dual_core_solver<T, X>::solve() { // s
return; return;
} }
one_iteration(); one_iteration();
} while (this->get_status() != FLOATING_POINT_ERROR && this->get_status() != DUAL_UNBOUNDED && this->get_status() != OPTIMAL && } while (this->get_status() != lp_status::FLOATING_POINT_ERROR && this->get_status() != lp_status::DUAL_UNBOUNDED && this->get_status() != lp_status::OPTIMAL &&
this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements
&& this->total_iterations() <= this->m_settings.max_total_number_of_iterations); && this->total_iterations() <= this->m_settings.max_total_number_of_iterations);
} }

View file

@ -7,23 +7,23 @@ namespace lp{
template <typename T, typename X> void lp_dual_simplex<T, X>::decide_on_status_after_stage1() { template <typename T, typename X> void lp_dual_simplex<T, X>::decide_on_status_after_stage1() {
switch (m_core_solver->get_status()) { switch (m_core_solver->get_status()) {
case OPTIMAL: case lp_status::OPTIMAL:
if (this->m_settings.abs_val_is_smaller_than_artificial_tolerance(m_core_solver->get_cost())) { if (this->m_settings.abs_val_is_smaller_than_artificial_tolerance(m_core_solver->get_cost())) {
this->m_status = FEASIBLE; this->m_status = lp_status::FEASIBLE;
} else { } else {
this->m_status = UNBOUNDED; this->m_status = lp_status::UNBOUNDED;
} }
break; break;
case DUAL_UNBOUNDED: case lp_status::DUAL_UNBOUNDED:
lp_unreachable(); lp_unreachable();
case ITERATIONS_EXHAUSTED: case lp_status::ITERATIONS_EXHAUSTED:
this->m_status = ITERATIONS_EXHAUSTED; this->m_status = lp_status::ITERATIONS_EXHAUSTED;
break; break;
case TIME_EXHAUSTED: case lp_status::TIME_EXHAUSTED:
this->m_status = TIME_EXHAUSTED; this->m_status = lp_status::TIME_EXHAUSTED;
break; break;
case FLOATING_POINT_ERROR: case lp_status::FLOATING_POINT_ERROR:
this->m_status = FLOATING_POINT_ERROR; this->m_status = lp_status::FLOATING_POINT_ERROR;
break; break;
default: default:
lp_unreachable(); lp_unreachable();
@ -99,20 +99,20 @@ template <typename T, typename X> void lp_dual_simplex<T, X>::solve_for_stage2()
m_core_solver->solve_yB(m_core_solver->m_y); m_core_solver->solve_yB(m_core_solver->m_y);
m_core_solver->fill_reduced_costs_from_m_y_by_rows(); m_core_solver->fill_reduced_costs_from_m_y_by_rows();
m_core_solver->start_with_initial_basis_and_make_it_dual_feasible(); m_core_solver->start_with_initial_basis_and_make_it_dual_feasible();
m_core_solver->set_status(FEASIBLE); m_core_solver->set_status(lp_status::FEASIBLE);
m_core_solver->solve(); m_core_solver->solve();
switch (m_core_solver->get_status()) { switch (m_core_solver->get_status()) {
case OPTIMAL: case lp_status::OPTIMAL:
this->m_status = OPTIMAL; this->m_status = lp_status::OPTIMAL;
break; break;
case DUAL_UNBOUNDED: case lp_status::DUAL_UNBOUNDED:
this->m_status = INFEASIBLE; this->m_status = lp_status::INFEASIBLE;
break; break;
case TIME_EXHAUSTED: case lp_status::TIME_EXHAUSTED:
this->m_status = TIME_EXHAUSTED; this->m_status = lp_status::TIME_EXHAUSTED;
break; break;
case FLOATING_POINT_ERROR: case lp_status::FLOATING_POINT_ERROR:
this->m_status = FLOATING_POINT_ERROR; this->m_status = lp_status::FLOATING_POINT_ERROR;
break; break;
default: default:
lp_unreachable(); lp_unreachable();
@ -151,7 +151,7 @@ template <typename T, typename X> void lp_dual_simplex<T, X>::stage1() {
m_core_solver->start_with_initial_basis_and_make_it_dual_feasible(); m_core_solver->start_with_initial_basis_and_make_it_dual_feasible();
if (this->m_settings.abs_val_is_smaller_than_artificial_tolerance(m_core_solver->get_cost())) { if (this->m_settings.abs_val_is_smaller_than_artificial_tolerance(m_core_solver->get_cost())) {
// skipping stage 1 // skipping stage 1
m_core_solver->set_status(OPTIMAL); m_core_solver->set_status(lp_status::OPTIMAL);
m_core_solver->set_total_iterations(0); m_core_solver->set_total_iterations(0);
} else { } else {
m_core_solver->solve(); m_core_solver->solve();
@ -336,7 +336,7 @@ template <typename T, typename X> void lp_dual_simplex<T, X>::find_maximal_solut
this->flip_costs(); // do it for now, todo ( remove the flipping) this->flip_costs(); // do it for now, todo ( remove the flipping)
this->cleanup(); this->cleanup();
if (this->m_status == INFEASIBLE) { if (this->m_status == lp_status::INFEASIBLE) {
return; return;
} }
this->fill_matrix_A_and_init_right_side(); this->fill_matrix_A_and_init_right_side();
@ -346,7 +346,7 @@ template <typename T, typename X> void lp_dual_simplex<T, X>::find_maximal_solut
fill_first_stage_solver_fields(); fill_first_stage_solver_fields();
copy_m_b_aside_and_set_it_to_zeros(); copy_m_b_aside_and_set_it_to_zeros();
stage1(); stage1();
if (this->m_status == FEASIBLE) { if (this->m_status == lp_status::FEASIBLE) {
stage2(); stage2();
} }
} }

View file

@ -469,7 +469,7 @@ public:
X new_val_for_leaving; X new_val_for_leaving;
int leaving = find_leaving_tableau_rows(new_val_for_leaving); int leaving = find_leaving_tableau_rows(new_val_for_leaving);
if (leaving == -1) { if (leaving == -1) {
this->set_status(OPTIMAL); this->set_status(lp_status::OPTIMAL);
return; return;
} }
@ -485,14 +485,14 @@ public:
T a_ent; T a_ent;
int entering = find_beneficial_column_in_row_tableau_rows(this->m_basis_heading[leaving], a_ent); int entering = find_beneficial_column_in_row_tableau_rows(this->m_basis_heading[leaving], a_ent);
if (entering == -1) { if (entering == -1) {
this->set_status(INFEASIBLE); this->set_status(lp_status::INFEASIBLE);
return; return;
} }
X theta = (this->m_x[leaving] - new_val_for_leaving) / a_ent; X theta = (this->m_x[leaving] - new_val_for_leaving) / a_ent;
advance_on_entering_and_leaving_tableau_rows(entering, leaving, theta ); advance_on_entering_and_leaving_tableau_rows(entering, leaving, theta );
lp_assert(this->m_x[leaving] == new_val_for_leaving); lp_assert(this->m_x[leaving] == new_val_for_leaving);
if (this->current_x_is_feasible()) if (this->current_x_is_feasible())
this->set_status(OPTIMAL); this->set_status(lp_status::OPTIMAL);
} }
void fill_breakpoints_array(unsigned entering); void fill_breakpoints_array(unsigned entering);
@ -508,7 +508,7 @@ public:
void decide_on_status_when_cannot_find_entering() { void decide_on_status_when_cannot_find_entering() {
lp_assert(!need_to_switch_costs()); lp_assert(!need_to_switch_costs());
this->set_status(this->current_x_is_feasible()? OPTIMAL: INFEASIBLE); this->set_status(this->current_x_is_feasible()? lp_status::OPTIMAL: lp_status::INFEASIBLE);
} }
// void limit_theta_on_basis_column_for_feas_case_m_neg(unsigned j, const T & m, X & theta) { // void limit_theta_on_basis_column_for_feas_case_m_neg(unsigned j, const T & m, X & theta) {
@ -915,7 +915,7 @@ public:
} else { } else {
m_converted_harris_eps = zero_of_type<T>(); m_converted_harris_eps = zero_of_type<T>();
} }
this->set_status(UNKNOWN); this->set_status(lp_status::UNKNOWN);
} }
// constructor // constructor

View file

@ -698,14 +698,14 @@ template <typename T, typename X>void lp_primal_core_solver<T, X>::advance_on_en
int pivot_compare_result = this->pivots_in_column_and_row_are_different(entering, leaving); int pivot_compare_result = this->pivots_in_column_and_row_are_different(entering, leaving);
if (!pivot_compare_result){;} if (!pivot_compare_result){;}
else if (pivot_compare_result == 2) { // the sign is changed, cannot continue else if (pivot_compare_result == 2) { // the sign is changed, cannot continue
this->set_status(UNSTABLE); this->set_status(lp_status::UNSTABLE);
this->iters_with_no_cost_growing()++; this->iters_with_no_cost_growing()++;
return; return;
} else { } else {
lp_assert(pivot_compare_result == 1); lp_assert(pivot_compare_result == 1);
this->init_lu(); this->init_lu();
if (this->m_factorization == nullptr || this->m_factorization->get_status() != LU_status::OK) { if (this->m_factorization == nullptr || this->m_factorization->get_status() != LU_status::OK) {
this->set_status(UNSTABLE); this->set_status(lp_status::UNSTABLE);
this->iters_with_no_cost_growing()++; this->iters_with_no_cost_growing()++;
return; return;
} }
@ -717,10 +717,10 @@ template <typename T, typename X>void lp_primal_core_solver<T, X>::advance_on_en
t = -t; t = -t;
} }
if (!this->update_basis_and_x(entering, leaving, t)) { if (!this->update_basis_and_x(entering, leaving, t)) {
if (this->get_status() == FLOATING_POINT_ERROR) if (this->get_status() == lp_status::FLOATING_POINT_ERROR)
return; return;
if (this->m_look_for_feasible_solution_only) { if (this->m_look_for_feasible_solution_only) {
this->set_status(FLOATING_POINT_ERROR); this->set_status(lp_status::FLOATING_POINT_ERROR);
return; return;
} }
init_reduced_costs(); init_reduced_costs();
@ -733,7 +733,7 @@ template <typename T, typename X>void lp_primal_core_solver<T, X>::advance_on_en
} }
if (this->current_x_is_feasible()) { if (this->current_x_is_feasible()) {
this->set_status(FEASIBLE); this->set_status(lp_status::FEASIBLE);
if (this->m_look_for_feasible_solution_only) if (this->m_look_for_feasible_solution_only)
return; return;
} }
@ -760,7 +760,7 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::advance_on_e
X t; X t;
int leaving = find_leaving_and_t_precise(entering, t); int leaving = find_leaving_and_t_precise(entering, t);
if (leaving == -1) { if (leaving == -1) {
this->set_status(UNBOUNDED); this->set_status(lp_status::UNBOUNDED);
return; return;
} }
advance_on_entering_and_leaving(entering, leaving, t); advance_on_entering_and_leaving(entering, leaving, t);
@ -776,7 +776,7 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::advance_on_e
int refresh_result = refresh_reduced_cost_at_entering_and_check_that_it_is_off(entering); int refresh_result = refresh_reduced_cost_at_entering_and_check_that_it_is_off(entering);
if (refresh_result) { if (refresh_result) {
if (this->m_look_for_feasible_solution_only) { if (this->m_look_for_feasible_solution_only) {
this->set_status(FLOATING_POINT_ERROR); this->set_status(lp_status::FLOATING_POINT_ERROR);
return; return;
} }
@ -799,19 +799,19 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::advance_on_e
// } // }
if (this->get_status() == UNSTABLE) { if (this->get_status() == lp_status::UNSTABLE) {
this->set_status(FLOATING_POINT_ERROR); this->set_status(lp_status::FLOATING_POINT_ERROR);
return; return;
} }
init_infeasibility_costs(); init_infeasibility_costs();
this->set_status(UNSTABLE); this->set_status(lp_status::UNSTABLE);
return; return;
} }
if (this->get_status() == TENTATIVE_UNBOUNDED) { if (this->get_status() == lp_status::TENTATIVE_UNBOUNDED) {
this->set_status(UNBOUNDED); this->set_status(lp_status::UNBOUNDED);
} else { } else {
this->set_status(TENTATIVE_UNBOUNDED); this->set_status(lp_status::TENTATIVE_UNBOUNDED);
} }
return; return;
} }
@ -825,7 +825,7 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::push_forw
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 = static_cast<unsigned>(this->m_nbasis.size()); unsigned ret = static_cast<unsigned>(this->m_nbasis.size());
if (this->get_status() == TENTATIVE_UNBOUNDED) if (this->get_status() == lp_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) {
ret = (unsigned)(ret * this->m_settings.percent_of_entering_to_check / 100); ret = (unsigned)(ret * this->m_settings.percent_of_entering_to_check / 100);
@ -852,12 +852,12 @@ template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::solve()
init_run(); init_run();
if (this->current_x_is_feasible() && this->m_look_for_feasible_solution_only) { if (this->current_x_is_feasible() && this->m_look_for_feasible_solution_only) {
this->set_status(FEASIBLE); this->set_status(lp_status::FEASIBLE);
return 0; return 0;
} }
if ((!numeric_traits<T>::precise()) && this->A_mult_x_is_off()) { if ((!numeric_traits<T>::precise()) && this->A_mult_x_is_off()) {
this->set_status(FLOATING_POINT_ERROR); this->set_status(lp_status::FLOATING_POINT_ERROR);
return 0; return 0;
} }
do { do {
@ -867,8 +867,8 @@ template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::solve()
one_iteration(); one_iteration();
lp_assert(!this->m_using_infeas_costs || this->costs_on_nbasis_are_zeros()); lp_assert(!this->m_using_infeas_costs || this->costs_on_nbasis_are_zeros());
switch (this->get_status()) { switch (this->get_status()) {
case OPTIMAL: // double check that we are at optimum case lp_status::OPTIMAL: // double check that we are at optimum
case INFEASIBLE: case lp_status::INFEASIBLE:
if (this->m_look_for_feasible_solution_only && this->current_x_is_feasible()) if (this->m_look_for_feasible_solution_only && this->current_x_is_feasible())
break; break;
if (!numeric_traits<T>::precise()) { if (!numeric_traits<T>::precise()) {
@ -877,7 +877,7 @@ template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::solve()
this->init_lu(); this->init_lu();
if (this->m_factorization->get_status() != LU_status::OK) { if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status (FLOATING_POINT_ERROR); this->set_status (lp_status::FLOATING_POINT_ERROR);
break; break;
} }
init_reduced_costs(); init_reduced_costs();
@ -885,7 +885,7 @@ template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::solve()
decide_on_status_when_cannot_find_entering(); decide_on_status_when_cannot_find_entering();
break; break;
} }
this->set_status(UNKNOWN); this->set_status(lp_status::UNKNOWN);
} else { // precise case } else { // precise case
if (this->m_look_for_feasible_solution_only) { // todo: keep the reduced costs correct all the time! if (this->m_look_for_feasible_solution_only) { // todo: keep the reduced costs correct all the time!
init_reduced_costs(); init_reduced_costs();
@ -893,31 +893,31 @@ template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::solve()
decide_on_status_when_cannot_find_entering(); decide_on_status_when_cannot_find_entering();
break; break;
} }
this->set_status(UNKNOWN); this->set_status(lp_status::UNKNOWN);
} }
} }
break; break;
case TENTATIVE_UNBOUNDED: case lp_status::TENTATIVE_UNBOUNDED:
this->init_lu(); this->init_lu();
if (this->m_factorization->get_status() != LU_status::OK) { if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status(FLOATING_POINT_ERROR); this->set_status(lp_status::FLOATING_POINT_ERROR);
break; break;
} }
init_reduced_costs(); init_reduced_costs();
break; break;
case UNBOUNDED: case lp_status::UNBOUNDED:
if (this->current_x_is_infeasible()) { if (this->current_x_is_infeasible()) {
init_reduced_costs(); init_reduced_costs();
this->set_status(UNKNOWN); this->set_status(lp_status::UNKNOWN);
} }
break; break;
case UNSTABLE: case lp_status::UNSTABLE:
lp_assert(! (numeric_traits<T>::precise())); lp_assert(! (numeric_traits<T>::precise()));
this->init_lu(); this->init_lu();
if (this->m_factorization->get_status() != LU_status::OK) { if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status(FLOATING_POINT_ERROR); this->set_status(lp_status::FLOATING_POINT_ERROR);
break; break;
} }
init_reduced_costs(); init_reduced_costs();
@ -926,13 +926,13 @@ template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::solve()
default: default:
break; // do nothing break; // do nothing
} }
} while (this->get_status() != FLOATING_POINT_ERROR } while (this->get_status() != lp_status::FLOATING_POINT_ERROR
&& &&
this->get_status() != UNBOUNDED this->get_status() != lp_status::UNBOUNDED
&& &&
this->get_status() != OPTIMAL this->get_status() != lp_status::OPTIMAL
&& &&
this->get_status() != INFEASIBLE this->get_status() != lp_status::INFEASIBLE
&& &&
this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements
&& &&
@ -940,7 +940,7 @@ template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::solve()
&& &&
!(this->current_x_is_feasible() && this->m_look_for_feasible_solution_only)); !(this->current_x_is_feasible() && this->m_look_for_feasible_solution_only));
lp_assert(this->get_status() == FLOATING_POINT_ERROR lp_assert(this->get_status() == lp_status::FLOATING_POINT_ERROR
|| ||
this->current_x_is_feasible() == false this->current_x_is_feasible() == false
|| ||
@ -1028,7 +1028,7 @@ template <typename T, typename X> T lp_primal_core_solver<T, X>::calculate_no
template <typename T, typename X> void lp_primal_core_solver<T, X>::find_feasible_solution() { template <typename T, typename X> void lp_primal_core_solver<T, X>::find_feasible_solution() {
this->m_look_for_feasible_solution_only = true; this->m_look_for_feasible_solution_only = true;
lp_assert(this->non_basic_columns_are_set_correctly()); lp_assert(this->non_basic_columns_are_set_correctly());
this->set_status(UNKNOWN); this->set_status(lp_status::UNKNOWN);
solve(); solve();
} }
@ -1072,15 +1072,15 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::fill_breakpo
template <typename T, typename X> bool lp_primal_core_solver<T, X>::done() { template <typename T, typename X> bool lp_primal_core_solver<T, X>::done() {
if (this->get_status() == OPTIMAL || this->get_status() == FLOATING_POINT_ERROR) return true; if (this->get_status() == lp_status::OPTIMAL || this->get_status() == lp_status::FLOATING_POINT_ERROR) return true;
if (this->get_status() == INFEASIBLE) { if (this->get_status() == lp_status::INFEASIBLE) {
return true; return true;
} }
if (this->m_iters_with_no_cost_growing >= this->m_settings.max_number_of_iterations_with_no_improvements) { if (this->m_iters_with_no_cost_growing >= this->m_settings.max_number_of_iterations_with_no_improvements) {
this->get_status() = ITERATIONS_EXHAUSTED; return true; this->get_status() = lp_status::ITERATIONS_EXHAUSTED; return true;
} }
if (this->total_iterations() >= this->m_settings.max_total_number_of_iterations) { if (this->total_iterations() >= this->m_settings.max_total_number_of_iterations) {
this->get_status() = ITERATIONS_EXHAUSTED; return true; this->get_status() = lp_status::ITERATIONS_EXHAUSTED; return true;
} }
return false; return false;
} }

View file

@ -20,7 +20,7 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::advance_on_e
X t; X t;
int leaving = find_leaving_and_t_tableau(entering, t); int leaving = find_leaving_and_t_tableau(entering, t);
if (leaving == -1) { if (leaving == -1) {
this->set_status(UNBOUNDED); this->set_status(lp_status::UNBOUNDED);
return; return;
} }
advance_on_entering_and_leaving_tableau(entering, leaving, t); advance_on_entering_and_leaving_tableau(entering, leaving, t);
@ -85,12 +85,12 @@ template <typename T, typename X>
unsigned lp_primal_core_solver<T, X>::solve_with_tableau() { unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
init_run_tableau(); init_run_tableau();
if (this->current_x_is_feasible() && this->m_look_for_feasible_solution_only) { if (this->current_x_is_feasible() && this->m_look_for_feasible_solution_only) {
this->set_status(FEASIBLE); this->set_status(lp_status::FEASIBLE);
return 0; return 0;
} }
if ((!numeric_traits<T>::precise()) && this->A_mult_x_is_off()) { if ((!numeric_traits<T>::precise()) && this->A_mult_x_is_off()) {
this->set_status(FLOATING_POINT_ERROR); this->set_status(lp_status::FLOATING_POINT_ERROR);
return 0; return 0;
} }
do { do {
@ -102,8 +102,8 @@ unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
else else
one_iteration_tableau(); one_iteration_tableau();
switch (this->get_status()) { switch (this->get_status()) {
case OPTIMAL: // double check that we are at optimum case lp_status::OPTIMAL: // double check that we are at optimum
case INFEASIBLE: case lp_status::INFEASIBLE:
if (this->m_look_for_feasible_solution_only && this->current_x_is_feasible()) if (this->m_look_for_feasible_solution_only && this->current_x_is_feasible())
break; break;
if (!numeric_traits<T>::precise()) { if (!numeric_traits<T>::precise()) {
@ -112,7 +112,7 @@ unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
this->init_lu(); this->init_lu();
if (this->m_factorization->get_status() != LU_status::OK) { if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status(FLOATING_POINT_ERROR); this->set_status(lp_status::FLOATING_POINT_ERROR);
break; break;
} }
init_reduced_costs(); init_reduced_costs();
@ -120,7 +120,7 @@ unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
decide_on_status_when_cannot_find_entering(); decide_on_status_when_cannot_find_entering();
break; break;
} }
this->set_status(UNKNOWN); this->set_status(lp_status::UNKNOWN);
} else { // precise case } else { // precise case
if ((!this->infeasibility_costs_are_correct())) { if ((!this->infeasibility_costs_are_correct())) {
init_reduced_costs_tableau(); // forcing recalc init_reduced_costs_tableau(); // forcing recalc
@ -128,31 +128,31 @@ unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
decide_on_status_when_cannot_find_entering(); decide_on_status_when_cannot_find_entering();
break; break;
} }
this->set_status(UNKNOWN); this->set_status(lp_status::UNKNOWN);
} }
} }
break; break;
case TENTATIVE_UNBOUNDED: case lp_status::TENTATIVE_UNBOUNDED:
this->init_lu(); this->init_lu();
if (this->m_factorization->get_status() != LU_status::OK) { if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status(FLOATING_POINT_ERROR); this->set_status(lp_status::FLOATING_POINT_ERROR);
break; break;
} }
init_reduced_costs(); init_reduced_costs();
break; break;
case UNBOUNDED: case lp_status::UNBOUNDED:
if (this->current_x_is_infeasible()) { if (this->current_x_is_infeasible()) {
init_reduced_costs(); init_reduced_costs();
this->set_status(UNKNOWN); this->set_status(lp_status::UNKNOWN);
} }
break; break;
case UNSTABLE: case lp_status::UNSTABLE:
lp_assert(! (numeric_traits<T>::precise())); lp_assert(! (numeric_traits<T>::precise()));
this->init_lu(); this->init_lu();
if (this->m_factorization->get_status() != LU_status::OK) { if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status(FLOATING_POINT_ERROR); this->set_status(lp_status::FLOATING_POINT_ERROR);
break; break;
} }
init_reduced_costs(); init_reduced_costs();
@ -161,13 +161,13 @@ unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
default: default:
break; // do nothing break; // do nothing
} }
} while (this->get_status() != FLOATING_POINT_ERROR } while (this->get_status() != lp_status::FLOATING_POINT_ERROR
&& &&
this->get_status() != UNBOUNDED this->get_status() != lp_status::UNBOUNDED
&& &&
this->get_status() != OPTIMAL this->get_status() != lp_status::OPTIMAL
&& &&
this->get_status() != INFEASIBLE this->get_status() != lp_status::INFEASIBLE
&& &&
this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements this->iters_with_no_cost_growing() <= this->m_settings.max_number_of_iterations_with_no_improvements
&& &&
@ -175,7 +175,7 @@ unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
&& &&
!(this->current_x_is_feasible() && this->m_look_for_feasible_solution_only)); !(this->current_x_is_feasible() && this->m_look_for_feasible_solution_only));
lp_assert(this->get_status() == FLOATING_POINT_ERROR lp_assert(this->get_status() == lp_status::FLOATING_POINT_ERROR
|| ||
this->current_x_is_feasible() == false this->current_x_is_feasible() == false
|| ||

View file

@ -216,7 +216,7 @@ template <typename T, typename X> void lp_primal_simplex<T, X>::fill_A_x_and_bas
template <typename T, typename X> void lp_primal_simplex<T, X>::solve_with_total_inf() { template <typename T, typename X> void lp_primal_simplex<T, X>::solve_with_total_inf() {
int total_vars = this->m_A->column_count() + this->row_count(); int total_vars = this->m_A->column_count() + this->row_count();
if (total_vars == 0) { if (total_vars == 0) {
this->m_status = OPTIMAL; this->m_status = lp_status::OPTIMAL;
return; return;
} }
m_low_bounds.clear(); m_low_bounds.clear();

View file

@ -36,7 +36,7 @@ enum class simplex_strategy_enum {
std::string column_type_to_string(column_type t); std::string column_type_to_string(column_type t);
enum lp_status { enum class lp_status {
UNKNOWN, UNKNOWN,
INFEASIBLE, INFEASIBLE,
TENTATIVE_UNBOUNDED, TENTATIVE_UNBOUNDED,

View file

@ -21,18 +21,18 @@ std::string column_type_to_string(column_type t) {
const char* lp_status_to_string(lp_status status) { const char* lp_status_to_string(lp_status status) {
switch (status) { switch (status) {
case UNKNOWN: return "UNKNOWN"; case lp_status::UNKNOWN: return "UNKNOWN";
case INFEASIBLE: return "INFEASIBLE"; case lp_status::INFEASIBLE: return "INFEASIBLE";
case UNBOUNDED: return "UNBOUNDED"; case lp_status::UNBOUNDED: return "UNBOUNDED";
case TENTATIVE_DUAL_UNBOUNDED: return "TENTATIVE_DUAL_UNBOUNDED"; case lp_status::TENTATIVE_DUAL_UNBOUNDED: return "TENTATIVE_DUAL_UNBOUNDED";
case DUAL_UNBOUNDED: return "DUAL_UNBOUNDED"; case lp_status::DUAL_UNBOUNDED: return "DUAL_UNBOUNDED";
case OPTIMAL: return "OPTIMAL"; case lp_status::OPTIMAL: return "OPTIMAL";
case FEASIBLE: return "FEASIBLE"; case lp_status::FEASIBLE: return "FEASIBLE";
case FLOATING_POINT_ERROR: return "FLOATING_POINT_ERROR"; case lp_status::FLOATING_POINT_ERROR: return "FLOATING_POINT_ERROR";
case TIME_EXHAUSTED: return "TIME_EXHAUSTED"; case lp_status::TIME_EXHAUSTED: return "TIME_EXHAUSTED";
case ITERATIONS_EXHAUSTED: return "ITERATIONS_EXHAUSTED"; case lp_status::ITERATIONS_EXHAUSTED: return "ITERATIONS_EXHAUSTED";
case EMPTY: return "EMPTY"; case lp_status::EMPTY: return "EMPTY";
case UNSTABLE: return "UNSTABLE"; case lp_status::UNSTABLE: return "UNSTABLE";
default: default:
lp_unreachable(); lp_unreachable();
} }

View file

@ -223,7 +223,7 @@ template <typename T, typename X> bool lp_solver<T, X>::row_e_is_obsolete(std
T rs = m_constraints[row_index].m_rs; T rs = m_constraints[row_index].m_rs;
if (row_is_zero(row)) { if (row_is_zero(row)) {
if (!is_zero(rs)) if (!is_zero(rs))
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
return true; return true;
} }
@ -233,7 +233,7 @@ template <typename T, typename X> bool lp_solver<T, X>::row_e_is_obsolete(std
T diff = low_bound - rs; T diff = low_bound - rs;
if (!val_is_smaller_than_eps(diff, m_settings.refactor_tolerance)){ if (!val_is_smaller_than_eps(diff, m_settings.refactor_tolerance)){
// low_bound > rs + m_settings.refactor_epsilon // low_bound > rs + m_settings.refactor_epsilon
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
return true; return true;
} }
if (val_is_smaller_than_eps(-diff, m_settings.refactor_tolerance)){ if (val_is_smaller_than_eps(-diff, m_settings.refactor_tolerance)){
@ -248,7 +248,7 @@ template <typename T, typename X> bool lp_solver<T, X>::row_e_is_obsolete(std
T diff = rs - upper_bound; T diff = rs - upper_bound;
if (!val_is_smaller_than_eps(diff, m_settings.refactor_tolerance)) { if (!val_is_smaller_than_eps(diff, m_settings.refactor_tolerance)) {
// upper_bound < rs - m_settings.refactor_tolerance // upper_bound < rs - m_settings.refactor_tolerance
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
return true; return true;
} }
if (val_is_smaller_than_eps(-diff, m_settings.refactor_tolerance)){ if (val_is_smaller_than_eps(-diff, m_settings.refactor_tolerance)){
@ -264,7 +264,7 @@ template <typename T, typename X> bool lp_solver<T, X>::row_ge_is_obsolete(std:
T rs = m_constraints[row_index].m_rs; T rs = m_constraints[row_index].m_rs;
if (row_is_zero(row)) { if (row_is_zero(row)) {
if (rs > zero_of_type<X>()) if (rs > zero_of_type<X>())
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
return true; return true;
} }
@ -273,7 +273,7 @@ template <typename T, typename X> bool lp_solver<T, X>::row_ge_is_obsolete(std:
T diff = rs - upper_bound; T diff = rs - upper_bound;
if (!val_is_smaller_than_eps(diff, m_settings.refactor_tolerance)) { if (!val_is_smaller_than_eps(diff, m_settings.refactor_tolerance)) {
// upper_bound < rs - m_settings.refactor_tolerance // upper_bound < rs - m_settings.refactor_tolerance
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
return true; return true;
} }
if (val_is_smaller_than_eps(-diff, m_settings.refactor_tolerance)){ if (val_is_smaller_than_eps(-diff, m_settings.refactor_tolerance)){
@ -290,7 +290,7 @@ template <typename T, typename X> bool lp_solver<T, X>::row_le_is_obsolete(std::
T rs = m_constraints[row_index].m_rs; T rs = m_constraints[row_index].m_rs;
if (row_is_zero(row)) { if (row_is_zero(row)) {
if (rs < zero_of_type<X>()) if (rs < zero_of_type<X>())
m_status = INFEASIBLE; m_status = lp_status::INFEASIBLE;
return true; return true;
} }

View file

@ -29,7 +29,7 @@ void quick_xplain::copy_constraint_and_add_constraint_vars(const lar_constraint&
bool quick_xplain::infeasible() { bool quick_xplain::infeasible() {
m_qsol.solve(); m_qsol.solve();
return m_qsol.get_status() == INFEASIBLE; return m_qsol.get_status() == lp_status::INFEASIBLE;
} }
// u - unexplored constraints // u - unexplored constraints
@ -100,7 +100,7 @@ bool quick_xplain::is_feasible(const vector<unsigned> & x, unsigned k) const {
l.add_constraint(ls, c.m_kind, c.m_right_side); l.add_constraint(ls, c.m_kind, c.m_right_side);
} }
l.solve(); l.solve();
return l.get_status() != INFEASIBLE; return l.get_status() != lp_status::INFEASIBLE;
} }
bool quick_xplain::x_is_minimal() const { bool quick_xplain::x_is_minimal() const {
@ -127,7 +127,7 @@ void quick_xplain::solve() {
for (unsigned i : m_x) for (unsigned i : m_x)
add_constraint_to_qsol(i); add_constraint_to_qsol(i);
m_qsol.solve(); m_qsol.solve();
lp_assert(m_qsol.get_status() == INFEASIBLE); lp_assert(m_qsol.get_status() == lp_status::INFEASIBLE);
m_qsol.get_infeasibility_explanation(m_explanation); m_qsol.get_infeasibility_explanation(m_explanation);
lp_assert(m_qsol.explanation_is_correct(m_explanation)); lp_assert(m_qsol.explanation_is_correct(m_explanation));
lp_assert(x_is_minimal()); lp_assert(x_is_minimal());