3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-14 21:08:46 +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->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()) {
solver->flip_costs();
}

View file

@ -1165,6 +1165,7 @@ namespace smt {
}
final_check_status final_check_eh() {
TRACE("lar_solver", tout << "ddd=" <<++lp::lp_settings::ddd << std::endl;);
m_use_nra_model = false;
lbool is_sat = l_true;
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) {
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;
sol["X1"] = 0;
sol["X2"] = 6;
@ -1666,8 +1666,8 @@ void solve_some_mps(argument_parser & args_parser) {
sol["X6"] = 1;
sol["X7"] = 1;
sol["X8"] = 0;
solve_mps_with_known_solution(file_names[9], &sol, OPTIMAL, dual);
solve_mps_with_known_solution(file_names[0], &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, lp_status::OPTIMAL, dual);
sol.clear();
sol["X1"] = 25.0/14.0;
// sol["X2"] = 0;
@ -1676,10 +1676,10 @@ void solve_some_mps(argument_parser & args_parser) {
// sol["X5"] = 0;
// sol["X6"] = 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[4], &sol, 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[1], nullptr, UNBOUNDED, dual); // chvatal: 135(b)
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, lp_status::OPTIMAL, dual); // chvatal: 135(e)
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, lp_status::UNBOUNDED, dual); // chvatal: 135(b)
solve_mps(file_names[8], false, 0, time_limit, false, dual, compare_with_primal, args_parser);
// return;
for (auto& s : file_names) {
@ -1745,7 +1745,7 @@ void solve_rational() {
expected_sol["x7"] = lp::mpq(1);
expected_sol["x8"] = lp::mpq(0);
solver.find_maximal_solution();
lp_assert(solver.get_status() == OPTIMAL);
lp_assert(solver.get_status() == lp_status::OPTIMAL);
for (auto it : expected_sol) {
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();
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;
if (solver->get_status() == INFEASIBLE) {
if (solver->get_status() == lp_status::INFEASIBLE) {
vector<std::pair<lp::mpq, constraint_index>> evidence;
solver->get_infeasibility_explanation(evidence);
}
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;
return;
}
@ -2717,7 +2717,7 @@ void test_term() {
auto status = solver.solve();
std::cout << lp_status_to_string(status) << std::endl;
std::unordered_map<var_index, mpq> model;
if (status != OPTIMAL)
if (status != lp_status::OPTIMAL)
return;
solver.get_model(model);
@ -2745,7 +2745,7 @@ void test_evidence_for_total_inf_simple(argument_parser & args_parser) {
auto status = solver.solve();
std::cout << lp_status_to_string(status) << std::endl;
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() {
/*

View file

@ -19,7 +19,7 @@ void int_solver::fix_non_base_columns() {
}
if (!change)
return;
if (m_lar_solver->find_feasible_solution() == INFEASIBLE)
if (m_lar_solver->find_feasible_solution() == lp_status::INFEASIBLE)
failed();
init_inf_int_set();
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) {
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));
// 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.
@ -286,6 +285,8 @@ bool int_solver::mk_gomory_cut(unsigned row_index, explanation & ex) {
ante.eqs().size(), ante.eqs().c_ptr(), ante, l)));
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.inf_set_is_correct());
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;
}
++settings().st().m_need_to_solve_inf;
@ -240,8 +240,8 @@ void lar_core_solver::solve() {
prefix_d();
lar_solution_signature solution_signature;
vector<unsigned> changes_of_basis = find_solution_signature_with_doubles(solution_signature);
if (m_d_solver.get_status() == TIME_EXHAUSTED) {
m_r_solver.set_status(TIME_EXHAUSTED);
if (m_d_solver.get_status() == lp_status::TIME_EXHAUSTED) {
m_r_solver.set_status(lp_status::TIME_EXHAUSTED);
return;
}
if (settings().use_tableau())
@ -262,10 +262,10 @@ void lar_core_solver::solve() {
m_r_solver.solve();
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();
} else if (m_r_solver.get_status() != UNBOUNDED) {
m_r_solver.set_status(OPTIMAL);
} else if (m_r_solver.get_status() != lp_status::UNBOUNDED) {
m_r_solver.set_status(lp_status::OPTIMAL);
}
lp_assert(r_basis_is_OK());
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_terms_start_index(1000000),
m_mpq_lar_core_solver(m_settings, *this)
@ -293,11 +293,11 @@ lp_status lar_solver::find_feasible_solution() {
}
lp_status lar_solver::solve() {
if (m_status == INFEASIBLE) {
if (m_status == lp_status::INFEASIBLE) {
return m_status;
}
solve_with_core_solver();
if (m_status != INFEASIBLE) {
if (m_status != lp_status::INFEASIBLE) {
if (m_settings.bound_propagation())
detect_rows_with_changed_bounds();
}
@ -325,7 +325,6 @@ vector<unsigned> lar_solver::get_list_of_all_var_indices() const {
void lar_solver::push() {
m_simplex_strategy = m_settings.simplex_strategy();
m_simplex_strategy.push();
m_status.push();
m_vars_to_ul_pairs.push();
m_infeasible_column_index.push();
m_mpq_lar_core_solver.push();
@ -335,7 +334,7 @@ void lar_solver::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;
for (unsigned j: set.m_index)
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) {
clean_large_elements_after_pop(n, set);
clean_popped_elements(n, set);
set.resize(n);
}
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());
m_status.pop(k);
m_infeasible_column_index.pop(k);
unsigned n = m_vars_to_ul_pairs.peek_size(k);
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_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();
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();
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 ||
(!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();
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;
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);
settings().simplex_strategy() = simplex_strategy_enum::tableau_rows;
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;
}
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);
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;
}
@ -732,7 +733,7 @@ void lar_solver::solve_with_core_solver() {
update_x_and_inf_costs_for_columns_with_changed_bounds();
m_mpq_lar_core_solver.solve();
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 {
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;
do {
@ -1353,7 +1354,7 @@ void lar_solver::pop_tableau() {
void lar_solver::clean_inf_set_of_r_solver_after_pop() {
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;
auto inf_index_copy = m_mpq_lar_core_solver.m_r_solver.m_inf_set.m_index;
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) {
TRACE("lar_solver", tout << "j = " << j << std::endl;);
constraint_index ci = m_constraints.size();
if (!is_term(j)) { // j is a var
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);
m_columns_with_changed_bound.insert(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;
}
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>());
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);
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) {
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);
switch (kind) {
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]) {
m_status = INFEASIBLE;
m_status = lp_status::INFEASIBLE;
lp_assert(false);
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);
}
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;
}
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>());
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;
set_upper_bound_witness(j, ci);
}
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;
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);
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;
}
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>());
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;
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) {
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 == 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_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_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));
mpq y_of_bound(0);
switch (kind) {
case LT:
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;
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:
{
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;
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:
{
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;
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:
{
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;
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:
{
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;
set_upper_bound_witness(j, ci);
}
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;
set_low_bound_witness(j, ci);
}

View file

@ -48,7 +48,7 @@ class lar_solver : public column_namer {
};
//////////////////// fields //////////////////////////
lp_settings m_settings;
stacked_value<lp_status> m_status;
lp_status m_status;
stacked_value<simplex_strategy_enum> m_simplex_strategy;
std::unordered_map<unsigned, ext_var_info> m_ext_vars_to_columns;
vector<unsigned> m_columns_to_ext_vars_or_term_indices;
@ -222,7 +222,7 @@ public:
vector<unsigned> get_list_of_all_var_indices() const;
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);
@ -447,5 +447,14 @@ public:
}
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:
lp_status m_status;
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; }
int_set m_inf_set;
bool m_using_infeas_costs;
@ -700,5 +707,8 @@ public:
}
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):
m_total_iterations(0),
m_iters_with_no_cost_growing(0),
m_status(FEASIBLE),
m_status(lp_status::FEASIBLE),
m_inf_set(A.column_count()),
m_using_infeas_costs(false),
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()) {
restore_x(entering, tt);
if(A_mult_x_is_off()) {
m_status = FLOATING_POINT_ERROR;
m_status = lp_status::FLOATING_POINT_ERROR;
m_iters_with_no_cost_growing++;
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) {
std::stringstream s;
// 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;
@ -566,19 +566,19 @@ update_basis_and_x(int entering, int leaving, X const & tt) {
init_lu();
if (m_factorization->get_status() != LU_status::OK) {
if (m_look_for_feasible_solution_only && !precise()) {
m_status = UNSTABLE;
m_status = lp_status::UNSTABLE;
delete m_factorization;
m_factorization = nullptr;
return false;
}
// LP_OUT(m_settings, "failing refactor for entering = " << entering << ", leaving = " << leaving << " total_iterations = " << total_iterations() << std::endl);
restore_x_and_refactor(entering, leaving, tt);
if (m_status == FLOATING_POINT_ERROR)
if (m_status == lp_status::FLOATING_POINT_ERROR)
return false;
lp_assert(!A_mult_x_is_off());
m_iters_with_no_cost_growing++;
// LP_OUT(m_settings, "rolled back after failing of init_factorization()" << std::endl);
m_status = UNSTABLE;
m_status = lp_status::UNSTABLE;
return false;
}
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];
if (get_column_type(basic_j) != column_type::fixed) continue;
//todo run over the row here!!!!! call get_iterator_on_row();
T a;
unsigned j;
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() {
if (this->get_status() == OPTIMAL) {
if (this->get_status() == lp_status::OPTIMAL) {
return true;
}
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 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);
if (m_r == -1) {
if (this->get_status() != UNSTABLE) {
this->set_status(OPTIMAL);
if (this->get_status() != lp_status::UNSTABLE) {
this->set_status(lp_status::OPTIMAL);
}
} else {
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;
}
// failure in advance_on_known_p
if (this->get_status() == FLOATING_POINT_ERROR) {
if (this->get_status() == lp_status::FLOATING_POINT_ERROR) {
return;
}
this->set_status(UNSTABLE);
this->set_status(lp_status::UNSTABLE);
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);
init_factorization(this->m_factorization, this->m_A, this->m_basis, this->m_settings);
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;
}
recover_leaving();
if (!this->find_x_by_solving()) {
this->set_status(FLOATING_POINT_ERROR);
this->set_status(lp_status::FLOATING_POINT_ERROR);
return;
}
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() {
if (this->get_status() == TENTATIVE_DUAL_UNBOUNDED) {
this->set_status(DUAL_UNBOUNDED);
if (this->get_status() == lp_status::TENTATIVE_DUAL_UNBOUNDED) {
this->set_status(lp_status::DUAL_UNBOUNDED);
} 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();
return false;
}
this->set_status(FEASIBLE);
this->set_status(lp_status::FEASIBLE);
find_q_and_tight_set();
if (!tight_breakpoinst_are_all_boxed()) break;
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() {
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();
if (this->get_status() == TENTATIVE_DUAL_UNBOUNDED) {
if (this->get_status() == lp_status::TENTATIVE_DUAL_UNBOUNDED) {
number_of_rows_to_try = this->m_m();
} else {
this->set_status(FEASIBLE);
this->set_status(lp_status::FEASIBLE);
}
pricing_loop(number_of_rows_to_try, offset_in_rows);
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;
}
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->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() {
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())) {
this->m_status = FEASIBLE;
this->m_status = lp_status::FEASIBLE;
} else {
this->m_status = UNBOUNDED;
this->m_status = lp_status::UNBOUNDED;
}
break;
case DUAL_UNBOUNDED:
case lp_status::DUAL_UNBOUNDED:
lp_unreachable();
case ITERATIONS_EXHAUSTED:
this->m_status = ITERATIONS_EXHAUSTED;
case lp_status::ITERATIONS_EXHAUSTED:
this->m_status = lp_status::ITERATIONS_EXHAUSTED;
break;
case TIME_EXHAUSTED:
this->m_status = TIME_EXHAUSTED;
case lp_status::TIME_EXHAUSTED:
this->m_status = lp_status::TIME_EXHAUSTED;
break;
case FLOATING_POINT_ERROR:
this->m_status = FLOATING_POINT_ERROR;
case lp_status::FLOATING_POINT_ERROR:
this->m_status = lp_status::FLOATING_POINT_ERROR;
break;
default:
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->fill_reduced_costs_from_m_y_by_rows();
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();
switch (m_core_solver->get_status()) {
case OPTIMAL:
this->m_status = OPTIMAL;
case lp_status::OPTIMAL:
this->m_status = lp_status::OPTIMAL;
break;
case DUAL_UNBOUNDED:
this->m_status = INFEASIBLE;
case lp_status::DUAL_UNBOUNDED:
this->m_status = lp_status::INFEASIBLE;
break;
case TIME_EXHAUSTED:
this->m_status = TIME_EXHAUSTED;
case lp_status::TIME_EXHAUSTED:
this->m_status = lp_status::TIME_EXHAUSTED;
break;
case FLOATING_POINT_ERROR:
this->m_status = FLOATING_POINT_ERROR;
case lp_status::FLOATING_POINT_ERROR:
this->m_status = lp_status::FLOATING_POINT_ERROR;
break;
default:
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();
if (this->m_settings.abs_val_is_smaller_than_artificial_tolerance(m_core_solver->get_cost())) {
// skipping stage 1
m_core_solver->set_status(OPTIMAL);
m_core_solver->set_status(lp_status::OPTIMAL);
m_core_solver->set_total_iterations(0);
} else {
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->cleanup();
if (this->m_status == INFEASIBLE) {
if (this->m_status == lp_status::INFEASIBLE) {
return;
}
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();
copy_m_b_aside_and_set_it_to_zeros();
stage1();
if (this->m_status == FEASIBLE) {
if (this->m_status == lp_status::FEASIBLE) {
stage2();
}
}

View file

@ -469,7 +469,7 @@ public:
X new_val_for_leaving;
int leaving = find_leaving_tableau_rows(new_val_for_leaving);
if (leaving == -1) {
this->set_status(OPTIMAL);
this->set_status(lp_status::OPTIMAL);
return;
}
@ -485,14 +485,14 @@ public:
T a_ent;
int entering = find_beneficial_column_in_row_tableau_rows(this->m_basis_heading[leaving], a_ent);
if (entering == -1) {
this->set_status(INFEASIBLE);
this->set_status(lp_status::INFEASIBLE);
return;
}
X theta = (this->m_x[leaving] - new_val_for_leaving) / a_ent;
advance_on_entering_and_leaving_tableau_rows(entering, leaving, theta );
lp_assert(this->m_x[leaving] == new_val_for_leaving);
if (this->current_x_is_feasible())
this->set_status(OPTIMAL);
this->set_status(lp_status::OPTIMAL);
}
void fill_breakpoints_array(unsigned entering);
@ -508,7 +508,7 @@ public:
void decide_on_status_when_cannot_find_entering() {
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) {
@ -915,7 +915,7 @@ public:
} else {
m_converted_harris_eps = zero_of_type<T>();
}
this->set_status(UNKNOWN);
this->set_status(lp_status::UNKNOWN);
}
// 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);
if (!pivot_compare_result){;}
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()++;
return;
} else {
lp_assert(pivot_compare_result == 1);
this->init_lu();
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()++;
return;
}
@ -717,10 +717,10 @@ template <typename T, typename X>void lp_primal_core_solver<T, X>::advance_on_en
t = -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;
if (this->m_look_for_feasible_solution_only) {
this->set_status(FLOATING_POINT_ERROR);
this->set_status(lp_status::FLOATING_POINT_ERROR);
return;
}
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()) {
this->set_status(FEASIBLE);
this->set_status(lp_status::FEASIBLE);
if (this->m_look_for_feasible_solution_only)
return;
}
@ -760,7 +760,7 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::advance_on_e
X t;
int leaving = find_leaving_and_t_precise(entering, t);
if (leaving == -1) {
this->set_status(UNBOUNDED);
this->set_status(lp_status::UNBOUNDED);
return;
}
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);
if (refresh_result) {
if (this->m_look_for_feasible_solution_only) {
this->set_status(FLOATING_POINT_ERROR);
this->set_status(lp_status::FLOATING_POINT_ERROR);
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) {
this->set_status(FLOATING_POINT_ERROR);
if (this->get_status() == lp_status::UNSTABLE) {
this->set_status(lp_status::FLOATING_POINT_ERROR);
return;
}
init_infeasibility_costs();
this->set_status(UNSTABLE);
this->set_status(lp_status::UNSTABLE);
return;
}
if (this->get_status() == TENTATIVE_UNBOUNDED) {
this->set_status(UNBOUNDED);
if (this->get_status() == lp_status::TENTATIVE_UNBOUNDED) {
this->set_status(lp_status::UNBOUNDED);
} else {
this->set_status(TENTATIVE_UNBOUNDED);
this->set_status(lp_status::TENTATIVE_UNBOUNDED);
}
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() {
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
if (ret > 300) {
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();
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;
}
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;
}
do {
@ -867,8 +867,8 @@ template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::solve()
one_iteration();
lp_assert(!this->m_using_infeas_costs || this->costs_on_nbasis_are_zeros());
switch (this->get_status()) {
case OPTIMAL: // double check that we are at optimum
case INFEASIBLE:
case lp_status::OPTIMAL: // double check that we are at optimum
case lp_status::INFEASIBLE:
if (this->m_look_for_feasible_solution_only && this->current_x_is_feasible())
break;
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();
if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status (FLOATING_POINT_ERROR);
this->set_status (lp_status::FLOATING_POINT_ERROR);
break;
}
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();
break;
}
this->set_status(UNKNOWN);
this->set_status(lp_status::UNKNOWN);
} else { // precise case
if (this->m_look_for_feasible_solution_only) { // todo: keep the reduced costs correct all the time!
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();
break;
}
this->set_status(UNKNOWN);
this->set_status(lp_status::UNKNOWN);
}
}
break;
case TENTATIVE_UNBOUNDED:
case lp_status::TENTATIVE_UNBOUNDED:
this->init_lu();
if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status(FLOATING_POINT_ERROR);
this->set_status(lp_status::FLOATING_POINT_ERROR);
break;
}
init_reduced_costs();
break;
case UNBOUNDED:
case lp_status::UNBOUNDED:
if (this->current_x_is_infeasible()) {
init_reduced_costs();
this->set_status(UNKNOWN);
this->set_status(lp_status::UNKNOWN);
}
break;
case UNSTABLE:
case lp_status::UNSTABLE:
lp_assert(! (numeric_traits<T>::precise()));
this->init_lu();
if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status(FLOATING_POINT_ERROR);
this->set_status(lp_status::FLOATING_POINT_ERROR);
break;
}
init_reduced_costs();
@ -926,13 +926,13 @@ template <typename T, typename X> unsigned lp_primal_core_solver<T, X>::solve()
default:
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
&&
@ -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));
lp_assert(this->get_status() == FLOATING_POINT_ERROR
lp_assert(this->get_status() == lp_status::FLOATING_POINT_ERROR
||
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() {
this->m_look_for_feasible_solution_only = true;
lp_assert(this->non_basic_columns_are_set_correctly());
this->set_status(UNKNOWN);
this->set_status(lp_status::UNKNOWN);
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() {
if (this->get_status() == OPTIMAL || this->get_status() == FLOATING_POINT_ERROR) return true;
if (this->get_status() == INFEASIBLE) {
if (this->get_status() == lp_status::OPTIMAL || this->get_status() == lp_status::FLOATING_POINT_ERROR) return true;
if (this->get_status() == lp_status::INFEASIBLE) {
return true;
}
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) {
this->get_status() = ITERATIONS_EXHAUSTED; return true;
this->get_status() = lp_status::ITERATIONS_EXHAUSTED; return true;
}
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;
int leaving = find_leaving_and_t_tableau(entering, t);
if (leaving == -1) {
this->set_status(UNBOUNDED);
this->set_status(lp_status::UNBOUNDED);
return;
}
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() {
init_run_tableau();
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;
}
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;
}
do {
@ -102,8 +102,8 @@ unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
else
one_iteration_tableau();
switch (this->get_status()) {
case OPTIMAL: // double check that we are at optimum
case INFEASIBLE:
case lp_status::OPTIMAL: // double check that we are at optimum
case lp_status::INFEASIBLE:
if (this->m_look_for_feasible_solution_only && this->current_x_is_feasible())
break;
if (!numeric_traits<T>::precise()) {
@ -112,7 +112,7 @@ unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
this->init_lu();
if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status(FLOATING_POINT_ERROR);
this->set_status(lp_status::FLOATING_POINT_ERROR);
break;
}
init_reduced_costs();
@ -120,7 +120,7 @@ unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
decide_on_status_when_cannot_find_entering();
break;
}
this->set_status(UNKNOWN);
this->set_status(lp_status::UNKNOWN);
} else { // precise case
if ((!this->infeasibility_costs_are_correct())) {
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();
break;
}
this->set_status(UNKNOWN);
this->set_status(lp_status::UNKNOWN);
}
}
break;
case TENTATIVE_UNBOUNDED:
case lp_status::TENTATIVE_UNBOUNDED:
this->init_lu();
if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status(FLOATING_POINT_ERROR);
this->set_status(lp_status::FLOATING_POINT_ERROR);
break;
}
init_reduced_costs();
break;
case UNBOUNDED:
case lp_status::UNBOUNDED:
if (this->current_x_is_infeasible()) {
init_reduced_costs();
this->set_status(UNKNOWN);
this->set_status(lp_status::UNKNOWN);
}
break;
case UNSTABLE:
case lp_status::UNSTABLE:
lp_assert(! (numeric_traits<T>::precise()));
this->init_lu();
if (this->m_factorization->get_status() != LU_status::OK) {
this->set_status(FLOATING_POINT_ERROR);
this->set_status(lp_status::FLOATING_POINT_ERROR);
break;
}
init_reduced_costs();
@ -161,13 +161,13 @@ unsigned lp_primal_core_solver<T, X>::solve_with_tableau() {
default:
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
&&
@ -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));
lp_assert(this->get_status() == FLOATING_POINT_ERROR
lp_assert(this->get_status() == lp_status::FLOATING_POINT_ERROR
||
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() {
int total_vars = this->m_A->column_count() + this->row_count();
if (total_vars == 0) {
this->m_status = OPTIMAL;
this->m_status = lp_status::OPTIMAL;
return;
}
m_low_bounds.clear();

View file

@ -36,7 +36,7 @@ enum class simplex_strategy_enum {
std::string column_type_to_string(column_type t);
enum lp_status {
enum class lp_status {
UNKNOWN,
INFEASIBLE,
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) {
switch (status) {
case UNKNOWN: return "UNKNOWN";
case INFEASIBLE: return "INFEASIBLE";
case UNBOUNDED: return "UNBOUNDED";
case TENTATIVE_DUAL_UNBOUNDED: return "TENTATIVE_DUAL_UNBOUNDED";
case DUAL_UNBOUNDED: return "DUAL_UNBOUNDED";
case OPTIMAL: return "OPTIMAL";
case FEASIBLE: return "FEASIBLE";
case FLOATING_POINT_ERROR: return "FLOATING_POINT_ERROR";
case TIME_EXHAUSTED: return "TIME_EXHAUSTED";
case ITERATIONS_EXHAUSTED: return "ITERATIONS_EXHAUSTED";
case EMPTY: return "EMPTY";
case UNSTABLE: return "UNSTABLE";
case lp_status::UNKNOWN: return "UNKNOWN";
case lp_status::INFEASIBLE: return "INFEASIBLE";
case lp_status::UNBOUNDED: return "UNBOUNDED";
case lp_status::TENTATIVE_DUAL_UNBOUNDED: return "TENTATIVE_DUAL_UNBOUNDED";
case lp_status::DUAL_UNBOUNDED: return "DUAL_UNBOUNDED";
case lp_status::OPTIMAL: return "OPTIMAL";
case lp_status::FEASIBLE: return "FEASIBLE";
case lp_status::FLOATING_POINT_ERROR: return "FLOATING_POINT_ERROR";
case lp_status::TIME_EXHAUSTED: return "TIME_EXHAUSTED";
case lp_status::ITERATIONS_EXHAUSTED: return "ITERATIONS_EXHAUSTED";
case lp_status::EMPTY: return "EMPTY";
case lp_status::UNSTABLE: return "UNSTABLE";
default:
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;
if (row_is_zero(row)) {
if (!is_zero(rs))
m_status = INFEASIBLE;
m_status = lp_status::INFEASIBLE;
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;
if (!val_is_smaller_than_eps(diff, m_settings.refactor_tolerance)){
// low_bound > rs + m_settings.refactor_epsilon
m_status = INFEASIBLE;
m_status = lp_status::INFEASIBLE;
return true;
}
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;
if (!val_is_smaller_than_eps(diff, m_settings.refactor_tolerance)) {
// upper_bound < rs - m_settings.refactor_tolerance
m_status = INFEASIBLE;
m_status = lp_status::INFEASIBLE;
return true;
}
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;
if (row_is_zero(row)) {
if (rs > zero_of_type<X>())
m_status = INFEASIBLE;
m_status = lp_status::INFEASIBLE;
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;
if (!val_is_smaller_than_eps(diff, m_settings.refactor_tolerance)) {
// upper_bound < rs - m_settings.refactor_tolerance
m_status = INFEASIBLE;
m_status = lp_status::INFEASIBLE;
return true;
}
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;
if (row_is_zero(row)) {
if (rs < zero_of_type<X>())
m_status = INFEASIBLE;
m_status = lp_status::INFEASIBLE;
return true;
}

View file

@ -29,7 +29,7 @@ void quick_xplain::copy_constraint_and_add_constraint_vars(const lar_constraint&
bool quick_xplain::infeasible() {
m_qsol.solve();
return m_qsol.get_status() == INFEASIBLE;
return m_qsol.get_status() == lp_status::INFEASIBLE;
}
// 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.solve();
return l.get_status() != INFEASIBLE;
return l.get_status() != lp_status::INFEASIBLE;
}
bool quick_xplain::x_is_minimal() const {
@ -127,7 +127,7 @@ void quick_xplain::solve() {
for (unsigned i : m_x)
add_constraint_to_qsol(i);
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);
lp_assert(m_qsol.explanation_is_correct(m_explanation));
lp_assert(x_is_minimal());