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:
parent
581098299b
commit
2fe846d9fc
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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() {
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in a new issue