use sparse representation in CP-SAT linear constraint manager

This commit is contained in:
Laurent Perron
2021-02-08 17:17:55 +01:00
parent dfe40729e2
commit 548a34dbc6
2 changed files with 18 additions and 18 deletions

View File

@@ -170,11 +170,7 @@ void LinearConstraintManager::ComputeObjectiveParallelism(
CHECK(objective_is_defined_);
// lazy computation of objective norm.
if (!objective_norm_computed_) {
double sum = 0.0;
for (const double coeff : dense_objective_coeffs_) {
sum += coeff * coeff;
}
objective_l2_norm_ = std::sqrt(sum);
objective_l2_norm_ = std::sqrt(sum_of_squared_objective_coeffs_);
objective_norm_computed_ = true;
}
CHECK_GT(objective_l2_norm_, 0.0);
@@ -189,11 +185,9 @@ void LinearConstraintManager::ComputeObjectiveParallelism(
double unscaled_objective_parallelism = 0.0;
for (int i = 0; i < lc.vars.size(); ++i) {
const IntegerVariable var = lc.vars[i];
DCHECK(VariableIsPositive(var));
if (var < dense_objective_coeffs_.size()) {
unscaled_objective_parallelism +=
ToDouble(lc.coeffs[i]) * dense_objective_coeffs_[var];
}
const auto it = objective_map_.find(var);
if (it == objective_map_.end()) continue;
unscaled_objective_parallelism += it->second * ToDouble(lc.coeffs[i]);
}
const double objective_parallelism =
unscaled_objective_parallelism /
@@ -307,10 +301,11 @@ void LinearConstraintManager::SetObjectiveCoefficient(IntegerVariable var,
var = NegationOf(var);
coeff = -coeff;
}
if (var.value() >= dense_objective_coeffs_.size()) {
dense_objective_coeffs_.resize(var.value() + 1, 0.0);
}
dense_objective_coeffs_[var] = ToDouble(coeff);
const double coeff_as_double = ToDouble(coeff);
const auto insert = objective_map_.insert({var, coeff_as_double});
CHECK(insert.second)
<< "SetObjectiveCoefficient() called twice with same variable";
sum_of_squared_objective_coeffs_ += coeff_as_double * coeff_as_double;
}
bool LinearConstraintManager::SimplifyConstraint(LinearConstraint* ct) {

View File

@@ -89,6 +89,9 @@ class LinearConstraintManager {
// The objective is used as one of the criterion to score cuts.
// The more a cut is parallel to the objective, the better its score is.
//
// Currently this should only be called once per IntegerVariable (Checked). It
// is easy to support dynamic modification if it becomes needed.
void SetObjectiveCoefficient(IntegerVariable var, IntegerValue coeff);
// Heuristic to decides what LP is best solved next. The given lp_solution
@@ -198,10 +201,12 @@ class LinearConstraintManager {
// Total deterministic time spent in this class.
double dtime_ = 0.0;
// Dense representation of the objective coeffs indexed by positive variables
// indices. It contains 0.0 where the variables does not appear in the
// objective.
absl::StrongVector<IntegerVariable, double> dense_objective_coeffs_;
// Sparse representation of the objective coeffs indexed by positive variables
// indices. Important: We cannot use a dense representation here in the corner
// case where we have many indepedent LPs. Alternatively, we could share a
// dense vector between all LinearConstraintManager.
double sum_of_squared_objective_coeffs_ = 0.0;
absl::flat_hash_map<IntegerVariable, double> objective_map_;
TimeLimit* time_limit_;
Model* model_;