mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 13:28:47 +00:00
replace lp_assert(false) with UNREACHABLE
This commit is contained in:
parent
3efe91c3e3
commit
8b0aa22631
|
@ -139,7 +139,7 @@ template <typename T, typename X> void core_solver_pretty_printer<T, X>::adjust_
|
|||
case column_type::free_column:
|
||||
break;
|
||||
default:
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,9 +114,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void copy_column_to_indexed_vector(unsigned entering, indexed_vector<mpq> &w ) const {
|
||||
lp_assert(false); // not implemented
|
||||
}
|
||||
general_matrix operator*(const general_matrix & m) const {
|
||||
lp_assert(m.row_count() == column_count());
|
||||
general_matrix ret(row_count(), m.column_count());
|
||||
|
@ -172,23 +169,6 @@ public:
|
|||
return r;
|
||||
}
|
||||
|
||||
// bool create_upper_triangle(general_matrix& m, vector<mpq>& x) {
|
||||
// for (unsigned i = 1; i < m.row_count(); i++) {
|
||||
// lp_assert(false); // to be continued
|
||||
// }
|
||||
// }
|
||||
|
||||
// bool solve_A_x_equal_b(const general_matrix& m, vector<mpq>& x, const vector<mpq>& b) const {
|
||||
// auto m_copy = m;
|
||||
// // for square matrices
|
||||
// lp_assert(row_count() == b.size());
|
||||
// lp_assert(x.size() == column_count());
|
||||
// lp_assert(row_count() == column_count());
|
||||
// x = b;
|
||||
// create_upper_triangle(copy_of_m, x);
|
||||
// solve_on_triangle(copy_of_m, x);
|
||||
// }
|
||||
//
|
||||
|
||||
void transpose_rows(unsigned i, unsigned l) {
|
||||
lp_assert(i != l);
|
||||
|
|
|
@ -44,7 +44,7 @@ inline std::string lconstraint_kind_string(lconstraint_kind t) {
|
|||
case EQ: return std::string("=");
|
||||
case NE: return std::string("!=");
|
||||
}
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
return std::string(); // it is unreachable
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ public:
|
|||
case column_type::fixed:
|
||||
return true;
|
||||
default:
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ public:
|
|||
case column_type::fixed:
|
||||
return true;
|
||||
default:
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -466,7 +466,7 @@ namespace lp {
|
|||
|
||||
|
||||
default:
|
||||
lp_unreachable(); // wrong mode
|
||||
UNREACHABLE(); // wrong mode
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -802,7 +802,7 @@ namespace lp {
|
|||
case GT: return left_side_val > constr.rhs();
|
||||
case EQ: return left_side_val == constr.rhs();
|
||||
default:
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
}
|
||||
return false; // it is unreachable
|
||||
}
|
||||
|
@ -857,7 +857,7 @@ namespace lp {
|
|||
case EQ: lp_assert(rs != zero_of_type<mpq>());
|
||||
break;
|
||||
default:
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
@ -1816,7 +1816,7 @@ namespace lp {
|
|||
adjust_initial_state_for_tableau_rows();
|
||||
break;
|
||||
case simplex_strategy_enum::tableau_costs:
|
||||
lp_assert(false); // not implemented
|
||||
UNREACHABLE(); // not implemented
|
||||
case simplex_strategy_enum::undecided:
|
||||
adjust_initial_state_for_tableau_rows();
|
||||
break;
|
||||
|
@ -1905,7 +1905,7 @@ namespace lp {
|
|||
}
|
||||
|
||||
default:
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (m_mpq_lar_core_solver.m_r_upper_bounds[j] == m_mpq_lar_core_solver.m_r_lower_bounds[j]) {
|
||||
m_mpq_lar_core_solver.m_column_types[j] = column_type::fixed;
|
||||
|
@ -1959,7 +1959,7 @@ namespace lp {
|
|||
}
|
||||
|
||||
default:
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2009,7 +2009,7 @@ namespace lp {
|
|||
}
|
||||
|
||||
default:
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
void lar_solver::update_bound_with_no_ub_no_lb(var_index j, lconstraint_kind kind, const mpq& right_side, constraint_index ci) {
|
||||
|
@ -2050,7 +2050,7 @@ namespace lp {
|
|||
}
|
||||
|
||||
default:
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ public:
|
|||
return p.coeff().is_one();
|
||||
}
|
||||
}
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ inline std::string lia_move_to_string(lia_move m) {
|
|||
case lia_move::unsat:
|
||||
return "unsat";
|
||||
default:
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
};
|
||||
return "strange";
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::prin
|
|||
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::basis_heading_is_correct() const ;
|
||||
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::column_is_dual_feasible(unsigned int) const;
|
||||
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::print_statistics_with_iterations_and_nonzeroes_and_cost_and_check_that_the_time_is_over(char const*, std::ostream &);
|
||||
template void lp::lp_core_solver_base<lp::mpq, lp::mpq>::set_non_basic_x_to_correct_bounds();
|
||||
template void lp::lp_core_solver_base<lp::mpq, lp::mpq>::add_delta_to_entering(unsigned int, const lp::mpq&);
|
||||
template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::init();
|
||||
template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::init_basis_heading_and_non_basic_columns_vector();
|
||||
|
@ -61,7 +60,6 @@ template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::calc
|
|||
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::column_is_feasible(unsigned int) const;
|
||||
// template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::print_linear_combination_of_column_indices(vector<std::pair<lp::mpq, unsigned int>, std::allocator<std::pair<lp::mpq, unsigned int> > > const&, std::ostream&) const;
|
||||
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::column_is_feasible(unsigned int) const;
|
||||
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::snap_non_basic_x_to_bound();
|
||||
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq>>::pivot_column_tableau(unsigned int, unsigned int);
|
||||
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::pivot_column_tableau(unsigned int, unsigned int);
|
||||
template void lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::transpose_rows_tableau(unsigned int, unsigned int);
|
||||
|
@ -70,6 +68,5 @@ template bool lp::lp_core_solver_base<lp::mpq, lp::mpq>::inf_set_is_correct() co
|
|||
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::infeasibility_costs_are_correct() const;
|
||||
template bool lp::lp_core_solver_base<lp::mpq, lp::mpq >::infeasibility_costs_are_correct() const;
|
||||
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::remove_from_basis(unsigned int);
|
||||
template bool lp::lp_core_solver_base<lp::mpq, lp::numeric_pair<lp::mpq> >::remove_from_basis(unsigned int, lp::numeric_pair<lp::mpq> const&);
|
||||
|
||||
|
||||
|
|
|
@ -173,8 +173,6 @@ public:
|
|||
|
||||
void set_total_iterations(unsigned s) { m_total_iterations = s; }
|
||||
|
||||
void set_non_basic_x_to_correct_bounds();
|
||||
|
||||
bool at_bound(const X &x, const X & bound) const {
|
||||
return !below_bound(x, bound) && !above_bound(x, bound);
|
||||
}
|
||||
|
@ -300,45 +298,6 @@ public:
|
|||
|
||||
std::string column_name(unsigned column) const;
|
||||
|
||||
bool snap_non_basic_x_to_bound() {
|
||||
bool ret = false;
|
||||
for (unsigned j : non_basis())
|
||||
ret = snap_column_to_bound(j) || ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool snap_column_to_bound(unsigned j) {
|
||||
switch (m_column_types[j]) {
|
||||
case column_type::fixed:
|
||||
if (x_is_at_bound(j))
|
||||
break;
|
||||
m_x[j] = m_lower_bounds[j];
|
||||
return true;
|
||||
case column_type::boxed:
|
||||
if (x_is_at_bound(j))
|
||||
break; // we should preserve x if possible
|
||||
// snap randomly
|
||||
if (m_settings.random_next() % 2 == 1)
|
||||
m_x[j] = m_lower_bounds[j];
|
||||
else
|
||||
m_x[j] = m_upper_bounds[j];
|
||||
return true;
|
||||
case column_type::lower_bound:
|
||||
if (x_is_at_lower_bound(j))
|
||||
break;
|
||||
m_x[j] = m_lower_bounds[j];
|
||||
return true;
|
||||
case column_type::upper_bound:
|
||||
if (x_is_at_upper_bound(j))
|
||||
break;
|
||||
m_x[j] = m_upper_bounds[j];
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool make_column_feasible(unsigned j, numeric_pair<mpq> & delta) {
|
||||
bool ret = false;
|
||||
lp_assert(m_basis_heading[j] < 0);
|
||||
|
@ -384,7 +343,6 @@ public:
|
|||
}
|
||||
|
||||
bool remove_from_basis(unsigned j);
|
||||
bool remove_from_basis(unsigned j, const impq&);
|
||||
bool pivot_column_general(unsigned j, unsigned j_basic, indexed_vector<T> & w);
|
||||
void init_basic_part_of_basis_heading() {
|
||||
unsigned m = m_basis.size();
|
||||
|
@ -456,31 +414,6 @@ public:
|
|||
change_basis_unconditionally(leaving, entering);
|
||||
}
|
||||
|
||||
bool non_basic_column_is_set_correctly(unsigned j) const {
|
||||
if (j >= this->m_n())
|
||||
return false;
|
||||
switch (this->m_column_types[j]) {
|
||||
case column_type::fixed:
|
||||
case column_type::boxed:
|
||||
if (!this->x_is_at_bound(j))
|
||||
return false;
|
||||
break;
|
||||
case column_type::lower_bound:
|
||||
if (!this->x_is_at_lower_bound(j))
|
||||
return false;
|
||||
break;
|
||||
case column_type::upper_bound:
|
||||
if (!this->x_is_at_upper_bound(j))
|
||||
return false;
|
||||
break;
|
||||
case column_type::free_column:
|
||||
break;
|
||||
default:
|
||||
lp_assert(false);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool non_basic_columns_are_set_correctly() const {
|
||||
for (unsigned j : this->m_nbasis)
|
||||
if (!column_is_feasible(j)) {
|
||||
|
@ -540,13 +473,11 @@ public:
|
|||
out << "[-oo, oo]";
|
||||
break;
|
||||
default:
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
}
|
||||
return out << "\n";
|
||||
}
|
||||
|
||||
bool column_is_free(unsigned j) const { return this->m_column_types[j] == column_type::free_column; }
|
||||
|
||||
bool column_is_fixed(unsigned j) const { return this->m_column_types[j] == column_type::fixed; }
|
||||
|
||||
|
||||
|
@ -579,16 +510,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// only check for basic columns
|
||||
bool calc_current_x_is_feasible() const {
|
||||
unsigned i = this->m_m();
|
||||
while (i--) {
|
||||
if (!column_is_feasible(m_basis[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void transpose_rows_tableau(unsigned i, unsigned ii);
|
||||
|
||||
void pivot_to_reduced_costs_tableau(unsigned i, unsigned j);
|
||||
|
|
|
@ -166,26 +166,6 @@ print_statistics_with_cost_and_check_that_the_time_is_over(X cost, std::ostream
|
|||
return time_is_over();
|
||||
}
|
||||
|
||||
template <typename T, typename X> void lp_core_solver_base<T, X>::
|
||||
set_non_basic_x_to_correct_bounds() {
|
||||
for (unsigned j : non_basis()) {
|
||||
switch (m_column_types[j]) {
|
||||
case column_type::boxed:
|
||||
m_x[j] = m_d[j] < 0? m_upper_bounds[j]: m_lower_bounds[j];
|
||||
break;
|
||||
case column_type::lower_bound:
|
||||
m_x[j] = m_lower_bounds[j];
|
||||
lp_assert(column_is_dual_feasible(j));
|
||||
break;
|
||||
case column_type::upper_bound:
|
||||
m_x[j] = m_upper_bounds[j];
|
||||
lp_assert(column_is_dual_feasible(j));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename T, typename X> bool lp_core_solver_base<T, X>::
|
||||
column_is_dual_feasible(unsigned j) const {
|
||||
switch (m_column_types[j]) {
|
||||
|
@ -201,9 +181,9 @@ column_is_dual_feasible(unsigned j) const {
|
|||
case column_type::free_column:
|
||||
return numeric_traits<X>::is_zero(m_d[j]);
|
||||
default:
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
}
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
template <typename T, typename X> bool lp_core_solver_base<T, X>::
|
||||
|
@ -257,7 +237,7 @@ template <typename T, typename X> bool lp_core_solver_base<T, X>::column_is_feas
|
|||
return true;
|
||||
break;
|
||||
default:
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
}
|
||||
return false; // it is unreachable
|
||||
}
|
||||
|
@ -453,18 +433,6 @@ template <typename T, typename X> bool lp_core_solver_base<T, X>::remove_from_ba
|
|||
return false;
|
||||
}
|
||||
|
||||
template <typename T, typename X> bool lp_core_solver_base<T, X>::remove_from_basis(unsigned basic_j, const impq& val) {
|
||||
indexed_vector<T> w(m_basis.size()); // the buffer
|
||||
unsigned i = m_basis_heading[basic_j];
|
||||
for (auto &c : m_A.m_rows[i]) {
|
||||
if (c.var() == basic_j)
|
||||
continue;
|
||||
if (pivot_column_general(c.var(), basic_j, w))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename X> bool
|
||||
lp_core_solver_base<T, X>::infeasibility_costs_are_correct() const {
|
||||
|
@ -513,7 +481,7 @@ lp_core_solver_base<T, X>::infeasibility_cost_is_correct_for_column(unsigned j)
|
|||
case column_type::free_column:
|
||||
return is_zero(this->m_costs[j]);
|
||||
default:
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,26 +19,27 @@ Revision History:
|
|||
--*/
|
||||
|
||||
#pragma once
|
||||
#include <list>
|
||||
#include <limits>
|
||||
#include <unordered_map>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "util/vector.h"
|
||||
#include <set>
|
||||
#include <math.h>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
#include "math/lp/static_matrix.h"
|
||||
#include "math/lp/core_solver_pretty_printer.h"
|
||||
#include "math/lp/lp_core_solver_base.h"
|
||||
#include "math/lp/static_matrix.h"
|
||||
#include "math/lp/u_set.h"
|
||||
#include "util/vector.h"
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <limits>
|
||||
#include <list>
|
||||
#include <math.h>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
namespace lp {
|
||||
|
||||
// This core solver solves (Ax=b, lower_bound_values \leq x \leq upper_bound_values, maximize costs*x )
|
||||
// The right side b is given implicitly by x and the basis
|
||||
// This core solver solves (Ax=b, lower_bound_values \leq x \leq
|
||||
// upper_bound_values, maximize costs*x ) The right side b is given implicitly
|
||||
// by x and the basis
|
||||
template <typename T, typename X>
|
||||
class lp_primal_core_solver:public lp_core_solver_base<T, X> {
|
||||
class lp_primal_core_solver : public lp_core_solver_base<T, X> {
|
||||
public:
|
||||
int m_sign_of_entering_delta;
|
||||
vector<T> m_costs_backup;
|
||||
|
@ -51,47 +52,42 @@ public:
|
|||
|
||||
std::list<unsigned> m_non_basis_list;
|
||||
void sort_non_basis();
|
||||
int choose_entering_column(unsigned number_of_benefitial_columns_to_go_over);
|
||||
int choose_entering_column_tableau();
|
||||
int choose_entering_column_presize(unsigned number_of_benefitial_columns_to_go_over);
|
||||
|
||||
|
||||
bool needs_to_grow(unsigned bj) const {
|
||||
lp_assert(!this->column_is_feasible(bj));
|
||||
switch(this->m_column_types[bj]) {
|
||||
switch (this->m_column_types[bj]) {
|
||||
case column_type::free_column:
|
||||
return false;
|
||||
case column_type::fixed:
|
||||
case column_type::lower_bound:
|
||||
case column_type::boxed:
|
||||
return this-> x_below_low_bound(bj);
|
||||
return this->x_below_low_bound(bj);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
lp_assert(false); // unreachable
|
||||
UNREACHABLE(); // unreachable
|
||||
return false;
|
||||
}
|
||||
|
||||
int inf_sign_of_column(unsigned bj) const {
|
||||
lp_assert(!this->column_is_feasible(bj));
|
||||
switch(this->m_column_types[bj]) {
|
||||
switch (this->m_column_types[bj]) {
|
||||
case column_type::free_column:
|
||||
return 0;
|
||||
case column_type::lower_bound:
|
||||
return 1;
|
||||
case column_type::fixed:
|
||||
case column_type::boxed:
|
||||
return this->x_above_upper_bound(bj)? -1: 1;
|
||||
return this->x_above_upper_bound(bj) ? -1 : 1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
lp_assert(false); // unreachable
|
||||
UNREACHABLE(); // unreachable
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool monoid_can_decrease(const row_cell<T> & rc) const {
|
||||
bool monoid_can_decrease(const row_cell<T> &rc) const {
|
||||
unsigned j = rc.var();
|
||||
lp_assert(this->column_is_feasible(j));
|
||||
switch (this->m_column_types[j]) {
|
||||
|
@ -120,11 +116,11 @@ public:
|
|||
default:
|
||||
return false;
|
||||
}
|
||||
lp_assert(false); // unreachable
|
||||
UNREACHABLE(); // unreachable
|
||||
return false;
|
||||
}
|
||||
|
||||
bool monoid_can_increase(const row_cell<T> & rc) const {
|
||||
bool monoid_can_increase(const row_cell<T> &rc) const {
|
||||
unsigned j = rc.var();
|
||||
lp_assert(this->column_is_feasible(j));
|
||||
switch (this->m_column_types[j]) {
|
||||
|
@ -153,13 +149,14 @@ public:
|
|||
default:
|
||||
return false;
|
||||
}
|
||||
lp_assert(false); // unreachable
|
||||
UNREACHABLE(); // unreachable
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned get_number_of_basic_vars_that_might_become_inf(unsigned j) const { // consider looking at the signs here: todo
|
||||
unsigned get_number_of_basic_vars_that_might_become_inf(
|
||||
unsigned j) const { // consider looking at the signs here: todo
|
||||
unsigned r = 0;
|
||||
for (const auto & cc : this->m_A.m_columns[j]) {
|
||||
for (const auto &cc : this->m_A.m_columns[j]) {
|
||||
unsigned k = this->m_basis[cc.var()];
|
||||
if (this->m_column_types[k] != column_type::free_column)
|
||||
r++;
|
||||
|
@ -167,12 +164,11 @@ public:
|
|||
return r;
|
||||
}
|
||||
|
||||
|
||||
int find_beneficial_column_in_row_tableau_rows_bland_mode(int i, T & a_ent) {
|
||||
int find_beneficial_column_in_row_tableau_rows_bland_mode(int i, T &a_ent) {
|
||||
int j = -1;
|
||||
unsigned bj = this->m_basis[i];
|
||||
bool bj_needs_to_grow = needs_to_grow(bj);
|
||||
for (const row_cell<T>& rc : this->m_A.m_rows[i]) {
|
||||
for (const row_cell<T> &rc : this->m_A.m_rows[i]) {
|
||||
if (rc.var() == bj)
|
||||
continue;
|
||||
if (bj_needs_to_grow) {
|
||||
|
@ -182,7 +178,7 @@ public:
|
|||
if (!monoid_can_increase(rc))
|
||||
continue;
|
||||
}
|
||||
if (rc.var() < static_cast<unsigned>(j) ) {
|
||||
if (rc.var() < static_cast<unsigned>(j)) {
|
||||
j = rc.var();
|
||||
a_ent = rc.coeff();
|
||||
}
|
||||
|
@ -194,10 +190,11 @@ public:
|
|||
return j;
|
||||
}
|
||||
|
||||
int find_beneficial_column_in_row_tableau_rows(int i, T & a_ent) {
|
||||
int find_beneficial_column_in_row_tableau_rows(int i, T &a_ent) {
|
||||
if (m_bland_mode_tableau)
|
||||
return find_beneficial_column_in_row_tableau_rows_bland_mode(i, a_ent);
|
||||
// a short row produces short infeasibility explanation and benefits at least one pivot operation
|
||||
// a short row produces short infeasibility explanation and benefits at
|
||||
// least one pivot operation
|
||||
int choice = -1;
|
||||
int nchoices = 0;
|
||||
unsigned num_of_non_free_basics = 1000000;
|
||||
|
@ -205,7 +202,7 @@ public:
|
|||
unsigned bj = this->m_basis[i];
|
||||
bool bj_needs_to_grow = needs_to_grow(bj);
|
||||
for (unsigned k = 0; k < this->m_A.m_rows[i].size(); k++) {
|
||||
const row_cell<T>& rc = this->m_A.m_rows[i][k];
|
||||
const row_cell<T> &rc = this->m_A.m_rows[i][k];
|
||||
unsigned j = rc.var();
|
||||
if (j == bj)
|
||||
continue;
|
||||
|
@ -223,27 +220,28 @@ public:
|
|||
choice = k;
|
||||
nchoices = 1;
|
||||
} else if (damage == num_of_non_free_basics &&
|
||||
this->m_A.m_columns[j].size() <= len && (this->m_settings.random_next() % (++nchoices))) {
|
||||
this->m_A.m_columns[j].size() <= len &&
|
||||
(this->m_settings.random_next() % (++nchoices))) {
|
||||
choice = k;
|
||||
len = this->m_A.m_columns[j].size();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (choice == -1) {
|
||||
m_inf_row_index_for_tableau = i;
|
||||
return -1;
|
||||
}
|
||||
const row_cell<T>& rc = this->m_A.m_rows[i][choice];
|
||||
const row_cell<T> &rc = this->m_A.m_rows[i][choice];
|
||||
a_ent = rc.coeff();
|
||||
return rc.var();
|
||||
}
|
||||
|
||||
bool try_jump_to_another_bound_on_entering(unsigned entering, const X & theta, X & t, bool & unlimited);
|
||||
bool try_jump_to_another_bound_on_entering_unlimited(unsigned entering, X & t);
|
||||
int find_leaving_and_t_tableau(unsigned entering, X & t);
|
||||
bool try_jump_to_another_bound_on_entering(unsigned entering, const X &theta,
|
||||
X &t, bool &unlimited);
|
||||
bool try_jump_to_another_bound_on_entering_unlimited(unsigned entering, X &t);
|
||||
int find_leaving_and_t_tableau(unsigned entering, X &t);
|
||||
|
||||
void limit_theta(const X & lim, X & theta, bool & unlimited) {
|
||||
void limit_theta(const X &lim, X &theta, bool &unlimited) {
|
||||
if (unlimited) {
|
||||
theta = lim;
|
||||
unlimited = false;
|
||||
|
@ -252,31 +250,39 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void limit_theta_on_basis_column_for_inf_case_m_neg_upper_bound(unsigned j, const T & m, X & theta, bool & unlimited) {
|
||||
void limit_theta_on_basis_column_for_inf_case_m_neg_upper_bound(
|
||||
unsigned j, const T &m, X &theta, bool &unlimited) {
|
||||
lp_assert(m < 0 && this->m_column_types[j] == column_type::upper_bound);
|
||||
limit_inf_on_upper_bound_m_neg(m, this->m_x[j], this->m_upper_bounds[j], theta, unlimited);
|
||||
limit_inf_on_upper_bound_m_neg(m, this->m_x[j], this->m_upper_bounds[j],
|
||||
theta, unlimited);
|
||||
}
|
||||
|
||||
|
||||
void limit_theta_on_basis_column_for_inf_case_m_neg_lower_bound(unsigned j, const T & m, X & theta, bool & unlimited) {
|
||||
void limit_theta_on_basis_column_for_inf_case_m_neg_lower_bound(
|
||||
unsigned j, const T &m, X &theta, bool &unlimited) {
|
||||
lp_assert(m < 0 && this->m_column_types[j] == column_type::lower_bound);
|
||||
limit_inf_on_bound_m_neg(m, this->m_x[j], this->m_lower_bounds[j], theta, unlimited);
|
||||
limit_inf_on_bound_m_neg(m, this->m_x[j], this->m_lower_bounds[j], theta,
|
||||
unlimited);
|
||||
}
|
||||
|
||||
|
||||
void limit_theta_on_basis_column_for_inf_case_m_pos_lower_bound(unsigned j, const T & m, X & theta, bool & unlimited) {
|
||||
void limit_theta_on_basis_column_for_inf_case_m_pos_lower_bound(
|
||||
unsigned j, const T &m, X &theta, bool &unlimited) {
|
||||
lp_assert(m > 0 && this->m_column_types[j] == column_type::lower_bound);
|
||||
limit_inf_on_lower_bound_m_pos(m, this->m_x[j], this->m_lower_bounds[j], theta, unlimited);
|
||||
limit_inf_on_lower_bound_m_pos(m, this->m_x[j], this->m_lower_bounds[j],
|
||||
theta, unlimited);
|
||||
}
|
||||
|
||||
void limit_theta_on_basis_column_for_inf_case_m_pos_upper_bound(unsigned j, const T & m, X & theta, bool & unlimited) {
|
||||
void limit_theta_on_basis_column_for_inf_case_m_pos_upper_bound(
|
||||
unsigned j, const T &m, X &theta, bool &unlimited) {
|
||||
lp_assert(m > 0 && this->m_column_types[j] == column_type::upper_bound);
|
||||
limit_inf_on_bound_m_pos(m, this->m_x[j], this->m_upper_bounds[j], theta, unlimited);
|
||||
limit_inf_on_bound_m_pos(m, this->m_x[j], this->m_upper_bounds[j], theta,
|
||||
unlimited);
|
||||
};
|
||||
|
||||
void get_bound_on_variable_and_update_leaving_precisely(unsigned j, vector<unsigned> & leavings, T m, X & t, T & abs_of_d_of_leaving);
|
||||
void get_bound_on_variable_and_update_leaving_precisely(
|
||||
unsigned j, vector<unsigned> &leavings, T m, X &t,
|
||||
T &abs_of_d_of_leaving);
|
||||
|
||||
X get_max_bound(vector<X> & b);
|
||||
X get_max_bound(vector<X> &b);
|
||||
|
||||
#ifdef Z3DEBUG
|
||||
void check_Ax_equal_b();
|
||||
|
@ -291,56 +297,55 @@ public:
|
|||
|
||||
// return 0 if the reduced cost at entering is close enough to the refreshed
|
||||
// 1 if it is way off, and 2 if it is unprofitable
|
||||
int refresh_reduced_cost_at_entering_and_check_that_it_is_off(unsigned entering);
|
||||
int refresh_reduced_cost_at_entering_and_check_that_it_is_off(
|
||||
unsigned entering);
|
||||
|
||||
void backup_and_normalize_costs();
|
||||
|
||||
void advance_on_entering_and_leaving(int entering, int leaving, X & t);
|
||||
void advance_on_entering_and_leaving_tableau(int entering, int leaving, X & t);
|
||||
void advance_on_entering_equal_leaving(int entering, X & t);
|
||||
void advance_on_entering_equal_leaving_tableau(int entering, X & t);
|
||||
void advance_on_entering_and_leaving_tableau(int entering, int leaving, X &t);
|
||||
void advance_on_entering_equal_leaving_tableau(int entering, X &t);
|
||||
|
||||
bool need_to_switch_costs() const {
|
||||
if (this->m_settings.simplex_strategy() == simplex_strategy_enum::tableau_rows)
|
||||
if (this->m_settings.simplex_strategy() ==
|
||||
simplex_strategy_enum::tableau_rows)
|
||||
return false;
|
||||
// lp_assert(calc_current_x_is_feasible() == current_x_is_feasible());
|
||||
// lp_assert(calc_current_x_is_feasible() ==
|
||||
// current_x_is_feasible());
|
||||
return this->current_x_is_feasible() == this->using_infeas_costs();
|
||||
}
|
||||
|
||||
|
||||
void advance_on_entering(int entering);
|
||||
void advance_on_entering_tableau(int entering);
|
||||
void advance_on_entering_precise(int entering);
|
||||
void push_forward_offset_in_non_basis(unsigned & offset_in_nb);
|
||||
|
||||
void push_forward_offset_in_non_basis(unsigned &offset_in_nb);
|
||||
|
||||
unsigned get_number_of_non_basic_column_to_try_for_enter();
|
||||
|
||||
|
||||
// returns the number of iterations
|
||||
unsigned solve();
|
||||
|
||||
|
||||
|
||||
void find_feasible_solution();
|
||||
|
||||
// bool is_tiny() const {return this->m_m < 10 && this->m_n < 20;}
|
||||
|
||||
void one_iteration_tableau();
|
||||
|
||||
// this version assumes that the leaving already has the right value, and does not update it
|
||||
void update_x_tableau_rows(unsigned entering, unsigned leaving, const X& delta) {
|
||||
// this version assumes that the leaving already has the right value, and does
|
||||
// not update it
|
||||
void update_x_tableau_rows(unsigned entering, unsigned leaving,
|
||||
const X &delta) {
|
||||
this->add_delta_to_x(entering, delta);
|
||||
if (!this->using_infeas_costs()) {
|
||||
for (const auto & c : this->m_A.m_columns[entering]) {
|
||||
for (const auto &c : this->m_A.m_columns[entering]) {
|
||||
if (leaving != this->m_basis[c.var()]) {
|
||||
this->add_delta_to_x_and_track_feasibility(this->m_basis[c.var()], - delta * this->m_A.get_val(c));
|
||||
this->add_delta_to_x_and_track_feasibility(
|
||||
this->m_basis[c.var()], -delta * this->m_A.get_val(c));
|
||||
}
|
||||
}
|
||||
} else { // using_infeas_costs() == true
|
||||
lp_assert(this->column_is_feasible(entering));
|
||||
lp_assert(this->m_costs[entering] == zero_of_type<T>());
|
||||
// m_d[entering] can change because of the cost change for basic columns.
|
||||
for (const auto & c : this->m_A.m_columns[entering]) {
|
||||
for (const auto &c : this->m_A.m_columns[entering]) {
|
||||
unsigned j = this->m_basis[c.var()];
|
||||
if (j != leaving)
|
||||
this->add_delta_to_x(j, -delta * this->m_A.get_val(c));
|
||||
|
@ -353,15 +358,15 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void update_basis_and_x_tableau_rows(int entering, int leaving, X const & tt) {
|
||||
void update_basis_and_x_tableau_rows(int entering, int leaving, X const &tt) {
|
||||
lp_assert(entering != leaving);
|
||||
update_x_tableau_rows(entering, leaving, tt);
|
||||
this->pivot_column_tableau(entering, this->m_basis_heading[leaving]);
|
||||
this->change_basis(entering, leaving);
|
||||
}
|
||||
|
||||
|
||||
void advance_on_entering_and_leaving_tableau_rows(int entering, int leaving, const X &theta ) {
|
||||
void advance_on_entering_and_leaving_tableau_rows(int entering, int leaving,
|
||||
const X &theta) {
|
||||
update_basis_and_x_tableau_rows(entering, leaving, theta);
|
||||
this->track_column_feasibility(entering);
|
||||
}
|
||||
|
@ -376,7 +381,7 @@ public:
|
|||
return j;
|
||||
}
|
||||
|
||||
const X& get_val_for_leaving(unsigned j) const {
|
||||
const X &get_val_for_leaving(unsigned j) const {
|
||||
lp_assert(!this->column_is_feasible(j));
|
||||
switch (this->m_column_types[j]) {
|
||||
case column_type::fixed:
|
||||
|
@ -397,7 +402,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void one_iteration_tableau_rows() {
|
||||
int leaving = find_smallest_inf_column();
|
||||
if (leaving == -1) {
|
||||
|
@ -417,35 +421,41 @@ public:
|
|||
}
|
||||
}
|
||||
T a_ent;
|
||||
int entering = find_beneficial_column_in_row_tableau_rows(this->m_basis_heading[leaving], a_ent);
|
||||
int entering = find_beneficial_column_in_row_tableau_rows(
|
||||
this->m_basis_heading[leaving], a_ent);
|
||||
if (entering == -1) {
|
||||
this->set_status(lp_status::INFEASIBLE);
|
||||
return;
|
||||
}
|
||||
const X& new_val_for_leaving = get_val_for_leaving(leaving);
|
||||
const X &new_val_for_leaving = get_val_for_leaving(leaving);
|
||||
X theta = (this->m_x[leaving] - new_val_for_leaving) / a_ent;
|
||||
this->m_x[leaving] = new_val_for_leaving;
|
||||
this->remove_column_from_inf_set(leaving);
|
||||
advance_on_entering_and_leaving_tableau_rows(entering, leaving, theta );
|
||||
advance_on_entering_and_leaving_tableau_rows(entering, leaving, theta);
|
||||
if (this->current_x_is_feasible())
|
||||
this->set_status(lp_status::OPTIMAL);
|
||||
}
|
||||
|
||||
void decide_on_status_when_cannot_find_entering() {
|
||||
lp_assert(!need_to_switch_costs());
|
||||
this->set_status(this->current_x_is_feasible()? lp_status::OPTIMAL: lp_status::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_no_check(unsigned j, const T & m, X & theta, bool & unlimited) {
|
||||
void limit_theta_on_basis_column_for_feas_case_m_neg_no_check(
|
||||
unsigned j, const T &m, X &theta, bool &unlimited) {
|
||||
lp_assert(m < 0);
|
||||
limit_theta((this->m_lower_bounds[j] - this->m_x[j]) / m, theta, unlimited);
|
||||
if (theta < zero_of_type<X>()) theta = zero_of_type<X>();
|
||||
if (theta < zero_of_type<X>())
|
||||
theta = zero_of_type<X>();
|
||||
}
|
||||
|
||||
bool limit_inf_on_bound_m_neg(const T & m, const X & x, const X & bound, X & theta, bool & unlimited) {
|
||||
bool limit_inf_on_bound_m_neg(const T &m, const X &x, const X &bound,
|
||||
X &theta, bool &unlimited) {
|
||||
// x gets smaller
|
||||
lp_assert(m < 0);
|
||||
if (this->below_bound(x, bound)) return false;
|
||||
if (this->below_bound(x, bound))
|
||||
return false;
|
||||
if (this->above_bound(x, bound)) {
|
||||
limit_theta((bound - x) / m, theta, unlimited);
|
||||
} else {
|
||||
|
@ -455,10 +465,12 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool limit_inf_on_bound_m_pos(const T & m, const X & x, const X & bound, X & theta, bool & unlimited) {
|
||||
bool limit_inf_on_bound_m_pos(const T &m, const X &x, const X &bound,
|
||||
X &theta, bool &unlimited) {
|
||||
// x gets larger
|
||||
lp_assert(m > 0);
|
||||
if (this->above_bound(x, bound)) return false;
|
||||
if (this->above_bound(x, bound))
|
||||
return false;
|
||||
if (this->below_bound(x, bound)) {
|
||||
limit_theta((bound - x) / m, theta, unlimited);
|
||||
} else {
|
||||
|
@ -469,16 +481,17 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
void limit_inf_on_lower_bound_m_pos(const T & m, const X & x, const X & bound, X & theta, bool & unlimited) {
|
||||
void limit_inf_on_lower_bound_m_pos(const T &m, const X &x, const X &bound,
|
||||
X &theta, bool &unlimited) {
|
||||
// x gets larger
|
||||
lp_assert(m > 0);
|
||||
if (this->below_bound(x, bound)) {
|
||||
limit_theta((bound - x) / m, theta, unlimited);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void limit_inf_on_upper_bound_m_neg(const T & m, const X & x, const X & bound, X & theta, bool & unlimited) {
|
||||
void limit_inf_on_upper_bound_m_neg(const T &m, const X &x, const X &bound,
|
||||
X &theta, bool &unlimited) {
|
||||
// x gets smaller
|
||||
lp_assert(m < 0);
|
||||
if (this->above_bound(x, bound)) {
|
||||
|
@ -486,15 +499,18 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void limit_theta_on_basis_column_for_inf_case_m_pos_boxed(unsigned j, const T & m, X & theta, bool & unlimited) {
|
||||
const X & x = this->m_x[j];
|
||||
const X & lbound = this->m_lower_bounds[j];
|
||||
void limit_theta_on_basis_column_for_inf_case_m_pos_boxed(unsigned j,
|
||||
const T &m,
|
||||
X &theta,
|
||||
bool &unlimited) {
|
||||
const X &x = this->m_x[j];
|
||||
const X &lbound = this->m_lower_bounds[j];
|
||||
|
||||
if (this->below_bound(x, lbound)) {
|
||||
limit_theta((lbound - x) / m, theta, unlimited);
|
||||
} else {
|
||||
const X & ubound = this->m_upper_bounds[j];
|
||||
if (this->below_bound(x, ubound)){
|
||||
const X &ubound = this->m_upper_bounds[j];
|
||||
if (this->below_bound(x, ubound)) {
|
||||
limit_theta((ubound - x) / m, theta, unlimited);
|
||||
} else if (!this->above_bound(x, ubound)) {
|
||||
theta = zero_of_type<X>();
|
||||
|
@ -503,15 +519,18 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void limit_theta_on_basis_column_for_inf_case_m_neg_boxed(unsigned j, const T & m, X & theta, bool & unlimited) {
|
||||
void limit_theta_on_basis_column_for_inf_case_m_neg_boxed(unsigned j,
|
||||
const T &m,
|
||||
X &theta,
|
||||
bool &unlimited) {
|
||||
// lp_assert(m < 0 && this->m_column_type[j] == column_type::boxed);
|
||||
const X & x = this->m_x[j];
|
||||
const X & ubound = this->m_upper_bounds[j];
|
||||
const X &x = this->m_x[j];
|
||||
const X &ubound = this->m_upper_bounds[j];
|
||||
if (this->above_bound(x, ubound)) {
|
||||
limit_theta((ubound - x) / m, theta, unlimited);
|
||||
} else {
|
||||
const X & lbound = this->m_lower_bounds[j];
|
||||
if (this->above_bound(x, lbound)){
|
||||
const X &lbound = this->m_lower_bounds[j];
|
||||
if (this->above_bound(x, lbound)) {
|
||||
limit_theta((lbound - x) / m, theta, unlimited);
|
||||
} else if (!this->below_bound(x, lbound)) {
|
||||
theta = zero_of_type<X>();
|
||||
|
@ -519,20 +538,11 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
void limit_theta_on_basis_column_for_feas_case_m_pos(unsigned j, const T & m, X & theta, bool & unlimited) {
|
||||
lp_assert(m > 0);
|
||||
if (this->below_bound(this->m_x[j], this->m_upper_bounds[j])) {
|
||||
limit_theta((this->m_upper_bounds[j] - this->m_x[j]) / m, theta, unlimited);
|
||||
if (theta < zero_of_type<X>()) {
|
||||
theta = zero_of_type<X>();
|
||||
unlimited = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void limit_theta_on_basis_column_for_feas_case_m_pos_no_check(unsigned j, const T & m, X & theta, bool & unlimited ) {
|
||||
void limit_theta_on_basis_column_for_feas_case_m_pos_no_check(
|
||||
unsigned j, const T &m, X &theta, bool &unlimited) {
|
||||
lp_assert(m > 0);
|
||||
limit_theta( (this->m_upper_bounds[j] - this->m_x[j]) / m, theta, unlimited);
|
||||
limit_theta((this->m_upper_bounds[j] - this->m_x[j]) / m, theta, unlimited);
|
||||
if (theta < zero_of_type<X>()) {
|
||||
theta = zero_of_type<X>();
|
||||
}
|
||||
|
@ -543,29 +553,36 @@ public:
|
|||
// x[j] + t * m >= this->m_lower_bounds[j]( if m < 0 )
|
||||
// or
|
||||
// x[j] + t * m <= this->m_upper_bounds[j] ( if m > 0)
|
||||
void limit_theta_on_basis_column(unsigned j, T m, X & theta, bool & unlimited) {
|
||||
void limit_theta_on_basis_column(unsigned j, T m, X &theta, bool &unlimited) {
|
||||
switch (this->m_column_types[j]) {
|
||||
case column_type::free_column: break;
|
||||
case column_type::free_column:
|
||||
break;
|
||||
case column_type::upper_bound:
|
||||
if (this->current_x_is_feasible()) {
|
||||
if (m > 0)
|
||||
limit_theta_on_basis_column_for_feas_case_m_pos_no_check(j, m, theta, unlimited);
|
||||
limit_theta_on_basis_column_for_feas_case_m_pos_no_check(j, m, theta,
|
||||
unlimited);
|
||||
} else { // inside of feasibility_loop
|
||||
if (m > 0)
|
||||
limit_theta_on_basis_column_for_inf_case_m_pos_upper_bound(j, m, theta, unlimited);
|
||||
limit_theta_on_basis_column_for_inf_case_m_pos_upper_bound(
|
||||
j, m, theta, unlimited);
|
||||
else
|
||||
limit_theta_on_basis_column_for_inf_case_m_neg_upper_bound(j, m, theta, unlimited);
|
||||
limit_theta_on_basis_column_for_inf_case_m_neg_upper_bound(
|
||||
j, m, theta, unlimited);
|
||||
}
|
||||
break;
|
||||
case column_type::lower_bound:
|
||||
if (this->current_x_is_feasible()) {
|
||||
if (m < 0)
|
||||
limit_theta_on_basis_column_for_feas_case_m_neg_no_check(j, m, theta, unlimited);
|
||||
limit_theta_on_basis_column_for_feas_case_m_neg_no_check(j, m, theta,
|
||||
unlimited);
|
||||
} else {
|
||||
if (m < 0)
|
||||
limit_theta_on_basis_column_for_inf_case_m_neg_lower_bound(j, m, theta, unlimited);
|
||||
limit_theta_on_basis_column_for_inf_case_m_neg_lower_bound(
|
||||
j, m, theta, unlimited);
|
||||
else
|
||||
limit_theta_on_basis_column_for_inf_case_m_pos_lower_bound(j, m, theta, unlimited);
|
||||
limit_theta_on_basis_column_for_inf_case_m_pos_lower_bound(
|
||||
j, m, theta, unlimited);
|
||||
}
|
||||
break;
|
||||
// case fixed:
|
||||
|
@ -574,71 +591,75 @@ public:
|
|||
// break;
|
||||
// }
|
||||
// if (m < 0)
|
||||
// limit_theta_on_basis_column_for_inf_case_m_neg_fixed(j, m, theta);
|
||||
// limit_theta_on_basis_column_for_inf_case_m_neg_fixed(j, m,
|
||||
// theta);
|
||||
// else
|
||||
// limit_theta_on_basis_column_for_inf_case_m_pos_fixed(j, m, theta);
|
||||
// limit_theta_on_basis_column_for_inf_case_m_pos_fixed(j, m,
|
||||
// theta);
|
||||
// break;
|
||||
case column_type::fixed:
|
||||
case column_type::boxed:
|
||||
if (this->current_x_is_feasible()) {
|
||||
if (m > 0) {
|
||||
limit_theta_on_basis_column_for_feas_case_m_pos_no_check(j, m, theta, unlimited);
|
||||
limit_theta_on_basis_column_for_feas_case_m_pos_no_check(j, m, theta,
|
||||
unlimited);
|
||||
} else {
|
||||
limit_theta_on_basis_column_for_feas_case_m_neg_no_check(j, m, theta, unlimited);
|
||||
limit_theta_on_basis_column_for_feas_case_m_neg_no_check(j, m, theta,
|
||||
unlimited);
|
||||
}
|
||||
} else {
|
||||
if (m > 0) {
|
||||
limit_theta_on_basis_column_for_inf_case_m_pos_boxed(j, m, theta, unlimited);
|
||||
limit_theta_on_basis_column_for_inf_case_m_pos_boxed(j, m, theta,
|
||||
unlimited);
|
||||
} else {
|
||||
limit_theta_on_basis_column_for_inf_case_m_neg_boxed(j, m, theta, unlimited);
|
||||
limit_theta_on_basis_column_for_inf_case_m_neg_boxed(j, m, theta,
|
||||
unlimited);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
}
|
||||
if (!unlimited && theta < zero_of_type<X>()) {
|
||||
theta = zero_of_type<X>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool column_is_benefitial_for_entering_basis(unsigned j) const;
|
||||
bool column_is_benefitial_for_entering_basis_precise(unsigned j) const;
|
||||
bool can_enter_basis(unsigned j);
|
||||
void init_infeasibility_costs();
|
||||
|
||||
void init_infeasibility_cost_for_column(unsigned j);
|
||||
T get_infeasibility_cost_for_column(unsigned j) const;
|
||||
void init_infeasibility_costs_for_changed_basis_only();
|
||||
|
||||
void print_column(unsigned j, std::ostream & out);
|
||||
void print_column(unsigned j, std::ostream &out);
|
||||
|
||||
void print_bound_info_and_x(unsigned j, std::ostream & out);
|
||||
void print_bound_info_and_x(unsigned j, std::ostream &out);
|
||||
|
||||
bool basis_column_is_set_correctly(unsigned j) const {
|
||||
return this->m_A.m_columns[j].size() == 1;
|
||||
|
||||
}
|
||||
|
||||
bool basis_columns_are_set_correctly() const {
|
||||
for (unsigned j : this->m_basis)
|
||||
if(!basis_column_is_set_correctly(j))
|
||||
if (!basis_column_is_set_correctly(j))
|
||||
return false;
|
||||
|
||||
return this->m_basis_heading.size() == this->m_A.column_count() && this->m_basis.size() == this->m_A.row_count();
|
||||
return this->m_basis_heading.size() == this->m_A.column_count() &&
|
||||
this->m_basis.size() == this->m_A.row_count();
|
||||
}
|
||||
|
||||
void init_run_tableau();
|
||||
void update_x_tableau(unsigned entering, const X & delta);
|
||||
void update_x_tableau(unsigned entering, const X &delta);
|
||||
void update_inf_cost_for_column_tableau(unsigned j);
|
||||
|
||||
// the delta is between the old and the new cost (old - new)
|
||||
void update_reduced_cost_for_basic_column_cost_change(const T & delta, unsigned j) {
|
||||
// the delta is between the old and the new cost (old - new)
|
||||
void update_reduced_cost_for_basic_column_cost_change(const T &delta,
|
||||
unsigned j) {
|
||||
lp_assert(this->m_basis_heading[j] >= 0);
|
||||
unsigned i = static_cast<unsigned>(this->m_basis_heading[j]);
|
||||
for (const row_cell<T> & rc : this->m_A.m_rows[i]) {
|
||||
for (const row_cell<T> &rc : this->m_A.m_rows[i]) {
|
||||
unsigned k = rc.var();
|
||||
if (k == j)
|
||||
continue;
|
||||
|
@ -646,7 +667,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
bool update_basis_and_x_tableau(int entering, int leaving, X const & tt);
|
||||
bool update_basis_and_x_tableau(int entering, int leaving, X const &tt);
|
||||
void init_reduced_costs_tableau();
|
||||
void init_tableau_rows() {
|
||||
m_bland_mode_tableau = false;
|
||||
|
@ -654,69 +675,24 @@ public:
|
|||
m_left_basis_tableau.resize(this->m_A.column_count());
|
||||
m_left_basis_repeated = 0;
|
||||
}
|
||||
// stage1 constructor
|
||||
lp_primal_core_solver(static_matrix<T, X> & A,
|
||||
vector<X> & b, // the right side vector
|
||||
vector<X> & x, // the number of elements in x needs to be at least as large as the number of columns in A
|
||||
vector<unsigned> & basis,
|
||||
vector<unsigned> & nbasis,
|
||||
vector<int> & heading,
|
||||
vector<T> & costs,
|
||||
const vector<column_type> & column_type_array,
|
||||
const vector<X> & lower_bound_values,
|
||||
const vector<X> & upper_bound_values,
|
||||
lp_settings & settings,
|
||||
const column_namer& column_names):
|
||||
lp_core_solver_base<T, X>(A, // b,
|
||||
basis,
|
||||
nbasis,
|
||||
heading,
|
||||
x,
|
||||
costs,
|
||||
settings,
|
||||
column_names,
|
||||
column_type_array,
|
||||
lower_bound_values,
|
||||
upper_bound_values),
|
||||
// stage1 constructor
|
||||
lp_primal_core_solver(
|
||||
static_matrix<T, X> &A,
|
||||
vector<X> &b, // the right side vector
|
||||
vector<X> &x, // the number of elements in x needs to be at least as large
|
||||
// as the number of columns in A
|
||||
vector<unsigned> &basis, vector<unsigned> &nbasis, vector<int> &heading,
|
||||
vector<T> &costs, const vector<column_type> &column_type_array,
|
||||
const vector<X> &lower_bound_values, const vector<X> &upper_bound_values,
|
||||
lp_settings &settings, const column_namer &column_names)
|
||||
: lp_core_solver_base<T, X>(A, // b,
|
||||
basis, nbasis, heading, x, costs, settings,
|
||||
column_names, column_type_array,
|
||||
lower_bound_values, upper_bound_values),
|
||||
m_bland_mode_threshold(1000) {
|
||||
this->set_status(lp_status::UNKNOWN);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool initial_x_is_correct() {
|
||||
std::set<unsigned> basis_set;
|
||||
for (unsigned i = 0; i < this->m_A.row_count(); i++) {
|
||||
basis_set.insert(this->m_basis[i]);
|
||||
}
|
||||
for (unsigned j = 0; j < this->m_n(); j++) {
|
||||
if (this->column_has_lower_bound(j) && this->m_x[j] < numeric_traits<T>::zero()) {
|
||||
LP_OUT(this->m_settings, "low bound for variable " << j << " does not hold: this->m_x[" << j << "] = " << this->m_x[j] << " is negative " << std::endl);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->column_has_upper_bound(j) && this->m_x[j] > this->m_upper_bounds[j]) {
|
||||
LP_OUT(this->m_settings, "upper bound for " << j << " does not hold: " << this->m_upper_bounds[j] << ">" << this->m_x[j] << std::endl);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (basis_set.find(j) != basis_set.end()) continue;
|
||||
if (this->m_column_types[j] == column_type::lower_bound) {
|
||||
if (numeric_traits<T>::zero() != this->m_x[j]) {
|
||||
LP_OUT(this->m_settings, "only low bound is set for " << j << " but low bound value " << numeric_traits<T>::zero() << " is not equal to " << this->m_x[j] << std::endl);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (this->m_column_types[j] == column_type::boxed) {
|
||||
if (this->m_upper_bounds[j] != this->m_x[j] && !numeric_traits<T>::is_zero(this->m_x[j])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
friend core_solver_pretty_printer<T, X>;
|
||||
};
|
||||
}
|
||||
} // namespace lp
|
||||
|
|
|
@ -53,10 +53,6 @@ void lp_primal_core_solver<T, X>::sort_non_basis() {
|
|||
|
||||
template <typename T, typename X>
|
||||
bool lp_primal_core_solver<T, X>::column_is_benefitial_for_entering_basis(unsigned j) const {
|
||||
return column_is_benefitial_for_entering_basis_precise(j);
|
||||
}
|
||||
template <typename T, typename X>
|
||||
bool lp_primal_core_solver<T, X>::column_is_benefitial_for_entering_basis_precise(unsigned j) const {
|
||||
const T& dj = this->m_d[j];
|
||||
TRACE("lar_solver", tout << "dj=" << dj << "\n";);
|
||||
switch (this->m_column_types[j]) {
|
||||
|
@ -88,56 +84,12 @@ bool lp_primal_core_solver<T, X>::column_is_benefitial_for_entering_basis_precis
|
|||
}
|
||||
break;
|
||||
default:
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T, typename X>
|
||||
int lp_primal_core_solver<T, X>::choose_entering_column_presize(unsigned number_of_benefitial_columns_to_go_over) { // at this moment m_y = cB * B(-1)
|
||||
if (number_of_benefitial_columns_to_go_over == 0)
|
||||
return -1;
|
||||
if (this->m_basis_sort_counter == 0) {
|
||||
sort_non_basis();
|
||||
this->m_basis_sort_counter = 20;
|
||||
}
|
||||
else {
|
||||
this->m_basis_sort_counter--;
|
||||
}
|
||||
unsigned j_nz = this->m_m() + 1; // this number is greater than the max column size
|
||||
std::list<unsigned>::iterator entering_iter = m_non_basis_list.end();
|
||||
for (auto non_basis_iter = m_non_basis_list.begin(); number_of_benefitial_columns_to_go_over && non_basis_iter != m_non_basis_list.end(); ++non_basis_iter) {
|
||||
unsigned j = *non_basis_iter;
|
||||
if (!column_is_benefitial_for_entering_basis(j))
|
||||
continue;
|
||||
|
||||
// if we are here then j is a candidate to enter the basis
|
||||
unsigned t = this->m_columns_nz[j];
|
||||
if (t < j_nz) {
|
||||
j_nz = t;
|
||||
entering_iter = non_basis_iter;
|
||||
if (number_of_benefitial_columns_to_go_over)
|
||||
number_of_benefitial_columns_to_go_over--;
|
||||
} else if (t == j_nz && this->m_settings.random_next() % 2 == 0) {
|
||||
entering_iter = non_basis_iter;
|
||||
}
|
||||
}// while (number_of_benefitial_columns_to_go_over && initial_offset_in_non_basis != offset_in_nb);
|
||||
if (entering_iter == m_non_basis_list.end())
|
||||
return -1;
|
||||
unsigned entering = *entering_iter;
|
||||
m_sign_of_entering_delta = this->m_d[entering] > 0 ? 1 : -1;
|
||||
m_non_basis_list.erase(entering_iter);
|
||||
m_non_basis_list.push_back(entering);
|
||||
return entering;
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename X>
|
||||
int lp_primal_core_solver<T, X>::choose_entering_column(unsigned number_of_benefitial_columns_to_go_over) { // at this moment m_y = cB * B(-1)
|
||||
return choose_entering_column_presize(number_of_benefitial_columns_to_go_over);
|
||||
}
|
||||
|
||||
template <typename T, typename X> bool lp_primal_core_solver<T, X>::try_jump_to_another_bound_on_entering(unsigned entering,
|
||||
const X & theta,
|
||||
X & t,
|
||||
|
@ -278,24 +230,6 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::backup_an
|
|||
|
||||
|
||||
|
||||
template <typename T, typename X>
|
||||
void lp_primal_core_solver<T, X>::advance_on_entering_equal_leaving(int entering, X & t) {
|
||||
|
||||
}
|
||||
|
||||
template <typename T, typename X>void lp_primal_core_solver<T, X>::advance_on_entering_and_leaving(int entering, int leaving, X & t) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
template <typename T, typename X> void lp_primal_core_solver<T, X>::advance_on_entering_precise(int entering) {
|
||||
lp_assert(false);
|
||||
}
|
||||
|
||||
template <typename T, typename X> void lp_primal_core_solver<T, X>::advance_on_entering(int entering) {
|
||||
lp_assert(false);
|
||||
}
|
||||
|
||||
template <typename T, typename X> void lp_primal_core_solver<T, X>::push_forward_offset_in_non_basis(unsigned & offset_in_nb) {
|
||||
if (++offset_in_nb == this->m_nbasis.size())
|
||||
offset_in_nb = 0;
|
||||
|
@ -377,7 +311,7 @@ lp_primal_core_solver<T, X>::get_infeasibility_cost_for_column(unsigned j) const
|
|||
ret = numeric_traits<T>::zero();
|
||||
break;
|
||||
default:
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
ret = numeric_traits<T>::zero(); // does not matter
|
||||
break;
|
||||
}
|
||||
|
@ -427,7 +361,7 @@ lp_primal_core_solver<T, X>::init_infeasibility_cost_for_column(unsigned j) {
|
|||
this->m_costs[j] = numeric_traits<T>::zero();
|
||||
break;
|
||||
default:
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -458,7 +392,7 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::print_column
|
|||
out << "( _" << this->m_x[j] << "_)" << std::endl;
|
||||
break;
|
||||
default:
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -480,7 +414,7 @@ template <typename T, typename X> void lp_primal_core_solver<T, X>::print_bound_
|
|||
out << "inf, inf" << std::endl;
|
||||
break;
|
||||
default:
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ unsigned lp_primal_core_solver<T, X>::solve() {
|
|||
}
|
||||
break;
|
||||
case lp_status::TENTATIVE_UNBOUNDED:
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
break;
|
||||
case lp_status::UNBOUNDED:
|
||||
if (this->current_x_is_infeasible()) {
|
||||
|
@ -132,7 +132,7 @@ unsigned lp_primal_core_solver<T, X>::solve() {
|
|||
break;
|
||||
|
||||
case lp_status::UNSTABLE:
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -31,7 +31,7 @@ std::string column_type_to_string(column_type t) {
|
|||
case column_type::lower_bound: return "lower_bound";
|
||||
case column_type::upper_bound: return "upper_bound";
|
||||
case column_type::free_column: return "free_column";
|
||||
default: lp_unreachable();
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
return "unknown"; // it is unreachable
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ const char* lp_status_to_string(lp_status status) {
|
|||
case lp_status::UNSTABLE: return "UNSTABLE";
|
||||
case lp_status::CANCELLED: return "CANCELLED";
|
||||
default:
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
}
|
||||
return "UNKNOWN"; // it is unreachable
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ lp_status lp_status_from_string(std::string status) {
|
|||
if (status == "FEASIBLE") return lp_status::FEASIBLE;
|
||||
if (status == "TIME_EXHAUSTED") return lp_status::TIME_EXHAUSTED;
|
||||
if (status == "EMPTY") return lp_status::EMPTY;
|
||||
lp_unreachable();
|
||||
UNREACHABLE();
|
||||
return lp_status::UNKNOWN; // it is unreachable
|
||||
}
|
||||
|
||||
|
|
|
@ -141,7 +141,6 @@ inline void throw_exception(std::string && str) {
|
|||
typedef z3_exception exception;
|
||||
|
||||
#define lp_assert(_x_) { SASSERT(_x_); }
|
||||
inline void lp_unreachable() { lp_assert(false); }
|
||||
template <typename X> inline X zero_of_type() { return numeric_traits<X>::zero(); }
|
||||
template <typename X> inline X one_of_type() { return numeric_traits<X>::one(); }
|
||||
template <typename X> inline bool is_zero(const X & v) { return numeric_traits<X>::is_zero(v); }
|
||||
|
|
|
@ -171,7 +171,7 @@ struct solver::imp {
|
|||
lit = m_nlsat->mk_ineq_literal(nlsat::atom::kind::EQ, 1, ps, is_even);
|
||||
break;
|
||||
default:
|
||||
lp_assert(false); // unreachable
|
||||
UNREACHABLE(); // unreachable
|
||||
}
|
||||
m_nlsat->mk_clause(1, &lit, a);
|
||||
}
|
||||
|
|
|
@ -107,8 +107,8 @@ public:
|
|||
template <typename X, typename Y>
|
||||
struct convert_struct {
|
||||
static X convert(const Y & y){ return X(y);}
|
||||
static bool below_bound_numeric(const X &, const X &, const Y &) { /*lp_unreachable();*/ return false;}
|
||||
static bool above_bound_numeric(const X &, const X &, const Y &) { /*lp_unreachable();*/ return false; }
|
||||
static bool below_bound_numeric(const X &, const X &, const Y &) { /*UNREACHABLE();*/ return false;}
|
||||
static bool above_bound_numeric(const X &, const X &, const Y &) { /*UNREACHABLE();*/ return false; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -190,7 +190,7 @@ struct numeric_pair {
|
|||
}
|
||||
|
||||
numeric_pair operator/(const numeric_pair &) const {
|
||||
// lp_unreachable();
|
||||
// UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
|
@ -199,7 +199,7 @@ struct numeric_pair {
|
|||
}
|
||||
|
||||
numeric_pair operator*(const numeric_pair & /*a*/) const {
|
||||
// lp_unreachable();
|
||||
// UNREACHABLE();
|
||||
}
|
||||
|
||||
numeric_pair& operator+=(const numeric_pair & a) {
|
||||
|
@ -275,14 +275,14 @@ numeric_pair<T> operator/(const numeric_pair<T> & r, const X & a) {
|
|||
return numeric_pair<T>(r.x / a, r.y / a);
|
||||
}
|
||||
|
||||
template <typename T> double get_double(const lp::numeric_pair<T> & ) { /* lp_unreachable(); */ return 0;}
|
||||
template <typename T> double get_double(const lp::numeric_pair<T> & ) { /* UNREACHABLE(); */ return 0;}
|
||||
template <typename T>
|
||||
class numeric_traits<lp::numeric_pair<T>> {
|
||||
public:
|
||||
static lp::numeric_pair<T> zero() { return lp::numeric_pair<T>(numeric_traits<T>::zero(), numeric_traits<T>::zero()); }
|
||||
static bool is_zero(const lp::numeric_pair<T> & v) { return numeric_traits<T>::is_zero(v.x) && numeric_traits<T>::is_zero(v.y); }
|
||||
static double get_double(const lp::numeric_pair<T> & v){ return numeric_traits<T>::get_double(v.x); } // just return the double of the first coordinate
|
||||
static double one() { /*lp_unreachable();*/ return 0;}
|
||||
static double one() { /*UNREACHABLE();*/ return 0;}
|
||||
static bool is_pos(const numeric_pair<T> &p) {
|
||||
return numeric_traits<T>::is_pos(p.x) ||
|
||||
(numeric_traits<T>::is_zero(p.x) && numeric_traits<T>::is_pos(p.y));
|
||||
|
|
|
@ -31,7 +31,6 @@ template std::set<std::pair<unsigned, unsigned>> lp::static_matrix<lp::mpq, lp::
|
|||
template void static_matrix<mpq, mpq>::add_column_to_vector(mpq const&, unsigned int, mpq*) const;
|
||||
template void static_matrix<mpq, mpq>::add_columns_at_the_end(unsigned int);
|
||||
template bool static_matrix<mpq, mpq>::is_correct() const;
|
||||
template void static_matrix<mpq, mpq>::copy_column_to_indexed_vector(unsigned int, indexed_vector<mpq>&) const;
|
||||
|
||||
template mpq static_matrix<mpq, mpq>::get_balance() const;
|
||||
template mpq static_matrix<mpq, mpq>::get_elem(unsigned int, unsigned int) const;
|
||||
|
@ -47,7 +46,6 @@ template static_matrix<mpq, mpq>::static_matrix(unsigned int, unsigned int);
|
|||
#ifdef Z3DEBUG
|
||||
template bool static_matrix<mpq, numeric_pair<mpq> >::is_correct() const;
|
||||
#endif
|
||||
template void static_matrix<mpq, numeric_pair<mpq> >::copy_column_to_indexed_vector(unsigned int, indexed_vector<mpq>&) const;
|
||||
template mpq static_matrix<mpq, numeric_pair<mpq> >::get_elem(unsigned int, unsigned int) const;
|
||||
template void static_matrix<mpq, numeric_pair<mpq> >::init_empty_matrix(unsigned int, unsigned int);
|
||||
template void static_matrix<mpq, numeric_pair<mpq> >::set(unsigned int, unsigned int, mpq const&);
|
||||
|
|
|
@ -168,8 +168,6 @@ public:
|
|||
|
||||
std::set<std::pair<unsigned, unsigned>> get_domain();
|
||||
|
||||
void copy_column_to_indexed_vector(unsigned j, indexed_vector<T> & v) const;
|
||||
|
||||
T get_max_abs_in_row(unsigned row) const;
|
||||
void add_column_to_vector (const T & a, unsigned j, T * v) const {
|
||||
for (const auto & it : m_columns[j]) {
|
||||
|
@ -222,7 +220,7 @@ public:
|
|||
virtual void set_number_of_columns(unsigned /*n*/) { }
|
||||
#endif
|
||||
|
||||
T get_max_val_in_row(unsigned /* i */) const { lp_unreachable(); }
|
||||
T get_max_val_in_row(unsigned /* i */) const { UNREACHABLE(); }
|
||||
|
||||
T get_balance() const;
|
||||
|
||||
|
|
|
@ -174,14 +174,6 @@ std::set<std::pair<unsigned, unsigned>> static_matrix<T, X>::get_domain() {
|
|||
return ret;
|
||||
}
|
||||
|
||||
template <typename T, typename X> void static_matrix<T, X>::copy_column_to_indexed_vector (unsigned j, indexed_vector<T> & v) const {
|
||||
lp_assert(j < m_columns.size());
|
||||
for (auto & it : m_columns[j]) {
|
||||
const T& val = get_val(it);
|
||||
if (!is_zero(val))
|
||||
v.set_value(val, it.var());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename X> T static_matrix<T, X>::get_max_abs_in_row(unsigned row) const {
|
||||
T ret = numeric_traits<T>::zero();
|
||||
|
|
|
@ -130,7 +130,7 @@ struct gomory_test {
|
|||
|
||||
|
||||
void report_conflict_from_gomory_cut(mpq &k) {
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void adjust_term_and_k_for_some_ints_case_gomory(lar_term& t, mpq& k, mpq &lcm_den) {
|
||||
|
|
|
@ -1365,7 +1365,7 @@ void test_gomory_cut_0() {
|
|||
if (j == 2)
|
||||
return zero_of_type<mpq>();
|
||||
if (j == 3) return mpq(3);
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
return zero_of_type<mpq>();
|
||||
},
|
||||
[](unsigned j) { // at_low_p
|
||||
|
@ -1375,7 +1375,7 @@ void test_gomory_cut_0() {
|
|||
return true;
|
||||
if (j == 3)
|
||||
return true;
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
},
|
||||
[](unsigned j) { // at_upper
|
||||
|
@ -1385,31 +1385,31 @@ void test_gomory_cut_0() {
|
|||
return true;
|
||||
if (j == 3)
|
||||
return false;
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
},
|
||||
[](unsigned j) { // lower_bound
|
||||
if (j == 1) {
|
||||
lp_assert(false); //unlimited from below
|
||||
UNREACHABLE(); //unlimited from below
|
||||
return impq(0);
|
||||
}
|
||||
if (j == 2)
|
||||
return impq(0);
|
||||
if (j == 3)
|
||||
return impq(3);
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
return impq(0);
|
||||
},
|
||||
[](unsigned j) { // upper
|
||||
if (j == 1) {
|
||||
lp_assert(false); //unlimited from above
|
||||
UNREACHABLE(); //unlimited from above
|
||||
return impq(0);
|
||||
}
|
||||
if (j == 2)
|
||||
return impq(0);
|
||||
if (j == 3)
|
||||
return impq(10);
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
return impq(0);
|
||||
},
|
||||
[] (unsigned) { return 0; },
|
||||
|
@ -1437,7 +1437,7 @@ void test_gomory_cut_1() {
|
|||
return mpq(4363334, 2730001);
|
||||
if (j == 3)
|
||||
return mpq(1);
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
return zero_of_type<mpq>();
|
||||
},
|
||||
[](unsigned j) { // at_low_p
|
||||
|
@ -1447,7 +1447,7 @@ void test_gomory_cut_1() {
|
|||
return false;
|
||||
if (j == 3)
|
||||
return true;
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
},
|
||||
[](unsigned j) { // at_upper
|
||||
|
@ -1457,19 +1457,19 @@ void test_gomory_cut_1() {
|
|||
return false;
|
||||
if (j == 3)
|
||||
return true;
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
},
|
||||
[](unsigned j) { // lower_bound
|
||||
if (j == 1) {
|
||||
lp_assert(false); //unlimited from below
|
||||
UNREACHABLE(); //unlimited from below
|
||||
return impq(0);
|
||||
}
|
||||
if (j == 2)
|
||||
return impq(1);
|
||||
if (j == 3)
|
||||
return impq(1);
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
return impq(0);
|
||||
},
|
||||
[](unsigned j) { // upper
|
||||
|
@ -1480,7 +1480,7 @@ void test_gomory_cut_1() {
|
|||
return impq(3333);
|
||||
if (j == 3)
|
||||
return impq(10000);
|
||||
lp_assert(false);
|
||||
UNREACHABLE();
|
||||
return impq(0);
|
||||
},
|
||||
[] (unsigned) { return 0; },
|
||||
|
|
|
@ -272,7 +272,7 @@ namespace lp {
|
|||
} else if (el.m_head == "+") {
|
||||
add_sum(c, el.m_elems);
|
||||
} else {
|
||||
lp_assert(false); // unexpected input
|
||||
UNREACHABLE(); // unexpected input
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue