rearchitecture glop/lp_data

This commit is contained in:
Laurent Perron
2019-07-24 13:49:08 -07:00
parent 0805c35356
commit 758667daf9
17 changed files with 442 additions and 519 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -20,6 +20,8 @@
#include "ortools/glop/rank_one_update.h"
#include "ortools/glop/status.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/lp_data/permutation.h"
#include "ortools/lp_data/scattered_vector.h"
#include "ortools/lp_data/sparse.h"
#include "ortools/util/stats.h"

View File

@@ -18,6 +18,8 @@
#include "ortools/glop/parameters.pb.h"
#include "ortools/lp_data/lp_data.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/lp_data/permutation.h"
#include "ortools/lp_data/scattered_vector.h"
#include "ortools/util/stats.h"
namespace operations_research {

View File

@@ -18,7 +18,10 @@
#include "ortools/glop/parameters.pb.h"
#include "ortools/glop/status.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/lp_data/permutation.h"
#include "ortools/lp_data/scattered_vector.h"
#include "ortools/lp_data/sparse.h"
#include "ortools/lp_data/sparse_column.h"
#include "ortools/util/stats.h"
namespace operations_research {

View File

@@ -80,7 +80,9 @@
#include "ortools/glop/parameters.pb.h"
#include "ortools/glop/status.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/lp_data/permutation.h"
#include "ortools/lp_data/sparse.h"
#include "ortools/lp_data/sparse_column.h"
#include "ortools/util/stats.h"
namespace operations_research {

View File

@@ -20,6 +20,7 @@
#include "ortools/glop/variables_info.h"
#include "ortools/lp_data/lp_data.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/lp_data/scattered_vector.h"
#include "ortools/util/stats.h"
namespace operations_research {

View File

@@ -17,6 +17,7 @@
#include "ortools/base/logging.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/lp_data/lp_utils.h"
#include "ortools/lp_data/scattered_vector.h"
#include "ortools/lp_data/sparse.h"
namespace operations_research {

View File

@@ -22,6 +22,7 @@
#include "ortools/glop/variables_info.h"
#include "ortools/lp_data/lp_data.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/lp_data/scattered_vector.h"
#include "ortools/util/random_engine.h"
#include "ortools/util/stats.h"

View File

@@ -32,6 +32,7 @@
#include "ortools/lp_data/lp_print_utils.h"
#include "ortools/lp_data/lp_utils.h"
#include "ortools/lp_data/matrix_utils.h"
#include "ortools/lp_data/permutation.h"
#include "ortools/util/fp_utils.h"
DEFINE_bool(simplex_display_numbers_as_fractions, false,
@@ -2006,7 +2007,7 @@ void RevisedSimplex::DualPhaseIUpdatePriceOnReducedCostChange(
if (something_to_do) {
// TODO(user): This code is duplicated with UpdateGivenNonBasicVariables()
// and more generally with the one in RankOneUpdateFactorization. Fix.
if (ShouldUseDenseIteration(initially_all_zero_scratchpad_)) {
if (initially_all_zero_scratchpad_.ShouldUseDenseIteration()) {
initially_all_zero_scratchpad_.non_zeros.clear();
initially_all_zero_scratchpad_.is_non_zero.assign(num_rows_, false);
} else {

View File

@@ -109,6 +109,7 @@
#include "ortools/lp_data/lp_data.h"
#include "ortools/lp_data/lp_print_utils.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/lp_data/scattered_vector.h"
#include "ortools/lp_data/sparse_row.h"
#include "ortools/util/random_engine.h"
#include "ortools/util/time_limit.h"

View File

@@ -18,6 +18,7 @@
#include "ortools/glop/parameters.pb.h"
#include "ortools/glop/variables_info.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/lp_data/scattered_vector.h"
#include "ortools/util/stats.h"
namespace operations_research {

View File

@@ -182,7 +182,7 @@ void VariableValues::UpdateGivenNonBasicVariables(
col, variable_values_[col] - old_value,
&initially_all_zero_scratchpad_);
}
if (ShouldUseDenseIteration(initially_all_zero_scratchpad_)) {
if (initially_all_zero_scratchpad_.ShouldUseDenseIteration()) {
initially_all_zero_scratchpad_.non_zeros.clear();
initially_all_zero_scratchpad_.is_non_zero.assign(num_rows, false);
} else {

View File

@@ -17,6 +17,7 @@
#include "ortools/glop/basis_representation.h"
#include "ortools/glop/variables_info.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/lp_data/scattered_vector.h"
#include "ortools/util/stats.h"
namespace operations_research {

View File

@@ -344,42 +344,6 @@ typedef StrictITIVector<RowIndex, ColIndex> RowToColMapping;
// Column of constraints (slack variables) statuses.
typedef StrictITIVector<RowIndex, ConstraintStatus> ConstraintStatusColumn;
// Returns true if it is more advantageous to use a dense iteration rather than
// using the non-zeros positions.
//
// TODO(user): The constant should depend on what algorithm is used. Clearing a
// dense vector is a lot more efficient than doing more complex stuff. Clean
// this up by extracting all the currently used constants in one place with
// meaningful names.
template <typename ScatteredRowOrCol>
bool ShouldUseDenseIteration(const ScatteredRowOrCol& v) {
if (v.non_zeros.empty()) return true;
const double kThresholdForUsingDenseRepresentation = 0.8;
return static_cast<double>(v.non_zeros.size()) >
kThresholdForUsingDenseRepresentation *
static_cast<double>(v.values.size().value());
}
template <typename IndexType>
class ScatteredVectorEntry {
public:
using Index = IndexType;
Index index() const { return index_[i_.value()]; }
Fractional coefficient() const {
return coefficient_[index_[i_.value()].value()];
}
protected:
ScatteredVectorEntry(const Index* indices, const Fractional* coefficients,
EntryIndex i)
: i_(i), index_(indices), coefficient_(coefficients) {}
EntryIndex i_;
const Index* index_;
const Fractional* coefficient_;
};
// --------------------------------------------------------
// VectorIterator
// --------------------------------------------------------
@@ -387,9 +351,7 @@ class ScatteredVectorEntry {
// An iterator over the elements of a sparse data structure that stores the
// elements in arrays for indices and coefficients. The iterator is
// built as a wrapper over a sparse vector entry class; the concrete entry class
// is provided through the template argument EntryType and it must either be
// derived from ScatteredVectorEntry or it must provide the same public and
// protected interface.
// is provided through the template argument EntryType.
template <typename EntryType>
class VectorIterator : EntryType {
public:
@@ -411,87 +373,6 @@ class VectorIterator : EntryType {
const Entry& operator*() const { return *this; }
};
// A simple struct that contains a DenseVector and its non-zeros indices.
//
// TODO(user): Move ScatteredVector and related types to new file.
template <typename Index,
typename Iterator = VectorIterator<ScatteredVectorEntry<Index>>>
struct ScatteredVector {
StrictITIVector<Index, Fractional> values;
// This can be left empty in which case we just have the dense representation
// above. Otherwise, it should always be a superset of the actual non-zeros.
bool non_zeros_are_sorted = false;
std::vector<Index> non_zeros;
// Temporary vector used in some sparse computation on the ScatteredColumn.
// True indicate a possible non-zero value. Note that its state is not always
// consistent.
StrictITIVector<Index, bool> is_non_zero;
Fractional operator[](Index index) const { return values[index]; }
Fractional& operator[](Index index) { return values[index]; }
// The iterator syntax for (auto entry : v) where v is a ScatteredVector only
// works when non_zeros is populated (i.e., when the vector is treated as
// sparse).
Iterator begin() const {
DCHECK(!non_zeros.empty() || IsAllZero(values));
return Iterator(this->non_zeros.data(), this->values.data(), EntryIndex(0));
}
Iterator end() const {
return Iterator(this->non_zeros.data(), this->values.data(),
EntryIndex(non_zeros.size()));
}
// Sorting the non-zeros is not always needed, but it allows us to have
// exactly the same behavior while using a sparse iteration or a dense one. So
// we always do it after a Solve().
void SortNonZerosIfNeeded() {
if (!non_zeros_are_sorted) {
std::sort(non_zeros.begin(), non_zeros.end());
non_zeros_are_sorted = true;
}
}
};
// Specializations used in the code.
class ScatteredColumnEntry : public ScatteredVectorEntry<RowIndex> {
public:
// Returns the row of the current entry.
RowIndex row() const { return index(); }
protected:
ScatteredColumnEntry(const RowIndex* indices, const Fractional* coefficients,
EntryIndex i)
: ScatteredVectorEntry<RowIndex>(indices, coefficients, i) {}
};
class ScatteredRowEntry : public ScatteredVectorEntry<ColIndex> {
public:
// Returns the column of the current entry.
ColIndex column() const { return index(); }
protected:
ScatteredRowEntry(const ColIndex* indices, const Fractional* coefficients,
EntryIndex i)
: ScatteredVectorEntry<ColIndex>(indices, coefficients, i) {}
};
using ScatteredColumnIterator = VectorIterator<ScatteredColumnEntry>;
using ScatteredRowIterator = VectorIterator<ScatteredRowEntry>;
struct ScatteredColumn
: public ScatteredVector<RowIndex, ScatteredColumnIterator> {};
struct ScatteredRow : public ScatteredVector<ColIndex, ScatteredRowIterator> {};
inline const ScatteredRow& TransposedView(const ScatteredColumn& c) {
return reinterpret_cast<const ScatteredRow&>(c);
}
inline const ScatteredColumn& TransposedView(const ScatteredRow& r) {
return reinterpret_cast<const ScatteredColumn&>(r);
}
// This is used during the deterministic time computation to convert a given
// number of floating-point operations to something in the same order of
// magnitude as a second (on a 2014 desktop).

View File

@@ -44,7 +44,7 @@ Fractional PreciseSquaredNorm(const SparseColumn& v) {
}
Fractional PreciseSquaredNorm(const ScatteredColumn& v) {
if (ShouldUseDenseIteration(v)) {
if (v.ShouldUseDenseIteration()) {
return PreciseSquaredNorm(v.values);
}
KahanSum sum;

View File

@@ -18,6 +18,7 @@
#include "ortools/base/accurate_sum.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/lp_data/scattered_vector.h"
#include "ortools/lp_data/sparse_column.h"
namespace operations_research {
@@ -113,7 +114,7 @@ template <class DenseRowOrColumn>
Fractional PreciseScalarProduct(const DenseRowOrColumn& u,
const ScatteredColumn& v) {
DCHECK_EQ(u.size().value(), v.values.size().value());
if (ShouldUseDenseIteration(v)) {
if (v.ShouldUseDenseIteration()) {
return PreciseScalarProduct(u, v.values);
}
KahanSum sum;

View File

@@ -34,6 +34,7 @@
#include "ortools/base/integral_types.h"
#include "ortools/lp_data/lp_types.h"
#include "ortools/lp_data/permutation.h"
#include "ortools/lp_data/scattered_vector.h"
#include "ortools/lp_data/sparse_column.h"
#include "ortools/util/return_macros.h"