rearchitecture glop/lp_data
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user