use sparse representation in CP-SAT linear constraint manager
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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_;
|
||||
|
||||
Reference in New Issue
Block a user