internal API
This commit is contained in:
@@ -415,6 +415,18 @@ void BasisFactorization::LeftSolveForUnitRow(ColIndex j,
|
||||
y->SortNonZerosIfNeeded();
|
||||
}
|
||||
|
||||
void BasisFactorization::TemporaryLeftSolveForUnitRow(ColIndex j,
|
||||
ScatteredRow* y) const {
|
||||
CHECK(IsRefactorized());
|
||||
SCOPED_TIME_STAT(&stats_);
|
||||
RETURN_IF_NULL(y);
|
||||
BumpDeterministicTimeForSolve(1);
|
||||
ClearAndResizeVectorWithNonZeros(RowToColIndex(matrix_.num_rows()), y);
|
||||
lu_factorization_.LeftSolveUForUnitRow(j, y);
|
||||
lu_factorization_.LeftSolveLWithNonZeros(y, nullptr);
|
||||
y->SortNonZerosIfNeeded();
|
||||
}
|
||||
|
||||
void BasisFactorization::RightSolveForProblemColumn(ColIndex col,
|
||||
ScatteredColumn* d) const {
|
||||
SCOPED_TIME_STAT(&stats_);
|
||||
|
||||
@@ -211,6 +211,9 @@ class BasisFactorization {
|
||||
// coefficient of value 1.0 at position 'j'.
|
||||
void LeftSolveForUnitRow(ColIndex j, ScatteredRow* y) const;
|
||||
|
||||
// Same as LeftSolveForUnitRow() but does not update any internal data.
|
||||
void TemporaryLeftSolveForUnitRow(ColIndex j, ScatteredRow* y) const;
|
||||
|
||||
// Right solves the system B.d = a where the input is the initial value of d.
|
||||
void RightSolve(ScatteredColumn* d) const;
|
||||
|
||||
|
||||
@@ -218,6 +218,10 @@ class RevisedSimplex {
|
||||
// class.
|
||||
ColIndex GetBasis(RowIndex row) const;
|
||||
|
||||
const ScatteredRow& GetUnitRowLeftInverse(RowIndex row) {
|
||||
return update_row_.ComputeAndGetUnitRowLeftInverse(row);
|
||||
}
|
||||
|
||||
// Returns a copy of basis_ vector for outside applications (like cuts) to
|
||||
// have the correspondence between rows and columns of the dictionary.
|
||||
RowToColMapping GetBasisVector() const { return basis_; }
|
||||
|
||||
@@ -57,6 +57,14 @@ const ScatteredRow& UpdateRow::GetUnitRowLeftInverse() const {
|
||||
return unit_row_left_inverse_;
|
||||
}
|
||||
|
||||
const ScatteredRow& UpdateRow::ComputeAndGetUnitRowLeftInverse(
|
||||
RowIndex leaving_row) {
|
||||
Invalidate();
|
||||
basis_factorization_.TemporaryLeftSolveForUnitRow(RowToColIndex(leaving_row),
|
||||
&unit_row_left_inverse_);
|
||||
return unit_row_left_inverse_;
|
||||
}
|
||||
|
||||
void UpdateRow::ComputeUnitRowLeftInverse(RowIndex leaving_row) {
|
||||
SCOPED_TIME_STAT(&stats_);
|
||||
basis_factorization_.LeftSolveForUnitRow(RowToColIndex(leaving_row),
|
||||
|
||||
@@ -92,6 +92,10 @@ class UpdateRow {
|
||||
return DeterministicTimeForFpOperations(num_operations_);
|
||||
}
|
||||
|
||||
// This returns the asked unit row left inverse. It temporarily invalidate
|
||||
// the class state by calling Invalidate().
|
||||
const ScatteredRow& ComputeAndGetUnitRowLeftInverse(RowIndex leaving_row);
|
||||
|
||||
private:
|
||||
// Computes the left inverse of the given unit row, and stores it in
|
||||
// unit_row_left_inverse_.
|
||||
|
||||
@@ -73,6 +73,11 @@ inline double ToDouble(IntegerValue value) {
|
||||
return static_cast<double>(value.value());
|
||||
}
|
||||
|
||||
template <class IntType>
|
||||
inline IntType IntTypeAbs(IntType t) {
|
||||
return IntType(std::abs(t.value()));
|
||||
}
|
||||
|
||||
inline IntegerValue CeilRatio(IntegerValue dividend,
|
||||
IntegerValue positive_divisor) {
|
||||
CHECK_GT(positive_divisor, 0);
|
||||
|
||||
@@ -27,5 +27,65 @@ double ComputeActivity(const LinearConstraint& constraint,
|
||||
return activity;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// TODO(user): Template for any integer type and expose this?
|
||||
IntegerValue ComputeGcd(const std::vector<IntegerValue>& values) {
|
||||
if (values.empty()) return IntegerValue(1);
|
||||
IntegerValue gcd = IntTypeAbs(values.front());
|
||||
const int size = values.size();
|
||||
for (int i = 1; i < size; ++i) {
|
||||
// GCD(gcd, value) = GCD(value, gcd % value);
|
||||
IntegerValue value = IntTypeAbs(values[i]);
|
||||
while (value != 0) {
|
||||
const IntegerValue r = gcd % value;
|
||||
gcd = value;
|
||||
value = r;
|
||||
}
|
||||
if (gcd == 1) break;
|
||||
}
|
||||
return gcd;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void DivideByGCD(LinearConstraint* constraint) {
|
||||
if (constraint->coeffs.empty()) return;
|
||||
const IntegerValue gcd = ComputeGcd(constraint->coeffs);
|
||||
if (gcd == 1) return;
|
||||
|
||||
if (constraint->lb > kMinIntegerValue) {
|
||||
constraint->lb = CeilRatio(constraint->lb, gcd);
|
||||
}
|
||||
if (constraint->ub < kMaxIntegerValue) {
|
||||
constraint->ub = FloorRatio(constraint->ub, gcd);
|
||||
}
|
||||
for (IntegerValue& coeff : constraint->coeffs) coeff /= gcd;
|
||||
}
|
||||
|
||||
void RemoveZeroTerms(LinearConstraint* constraint) {
|
||||
int new_size = 0;
|
||||
const int size = constraint->vars.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (constraint->coeffs[i] == 0) continue;
|
||||
constraint->vars[new_size] = constraint->vars[i];
|
||||
constraint->coeffs[new_size] = constraint->coeffs[i];
|
||||
++new_size;
|
||||
}
|
||||
constraint->vars.resize(new_size);
|
||||
constraint->coeffs.resize(new_size);
|
||||
}
|
||||
|
||||
void MakeAllCoefficientsPositive(LinearConstraint* constraint) {
|
||||
const int size = constraint->vars.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
const IntegerValue coeff = constraint->coeffs[i];
|
||||
if (coeff < 0) {
|
||||
constraint->coeffs[i] = -coeff;
|
||||
constraint->vars[i] = NegationOf(constraint->vars[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sat
|
||||
} // namespace operations_research
|
||||
|
||||
@@ -174,6 +174,16 @@ class LinearConstraintBuilder {
|
||||
double ComputeActivity(const LinearConstraint& constraint,
|
||||
const gtl::ITIVector<IntegerVariable, double>& values);
|
||||
|
||||
// Computes the GCD of the constraint coefficient, and divide them by it. This
|
||||
// also tighten the constraint bounds assumming all the variables are integer.
|
||||
void DivideByGCD(LinearConstraint* constraint);
|
||||
|
||||
// Removes the entries with a coefficient of zero.
|
||||
void RemoveZeroTerms(LinearConstraint* constraint);
|
||||
|
||||
// Makes all coefficients positive by transforming a variable to its negation.
|
||||
void MakeAllCoefficientsPositive(LinearConstraint* constraint);
|
||||
|
||||
} // namespace sat
|
||||
} // namespace operations_research
|
||||
|
||||
|
||||
Reference in New Issue
Block a user