40 original_problem_ = linear_problem;
44 original_problem_->GetTransposeSparseMatrix();
48 const ColIndex num_ct =
RowToColIndex(original_problem_->num_constraints());
49 for (ColIndex
ct(0);
ct < num_ct; ++
ct) {
52 const RowIndex first_row = sparse_constraint.
GetFirstRow();
53 for (EntryIndex e(1); e < sparse_constraint.
num_entries(); ++e) {
54 partition.MergePartsOf(first_row.value(),
55 sparse_constraint.
EntryRow(e).value());
60 std::vector<int> classes;
61 const int num_classes = partition.FillEquivalenceClasses(&classes);
62 clusters_.resize(num_classes);
63 for (
int i = 0; i < classes.size(); ++i) {
64 clusters_[classes[i]].push_back(ColIndex(i));
66 for (
int i = 0;
i < num_classes; ++
i) {
67 std::sort(clusters_[i].begin(), clusters_[i].
end());
71int LPDecomposer::GetNumberOfProblems()
const {
83 CHECK_GE(problem_index, 0);
84 CHECK_LT(problem_index, clusters_.size());
88 absl::MutexLock mutex_lock(&mutex_);
89 const std::vector<ColIndex>& cluster = clusters_[problem_index];
91 original_problem_->num_variables(), kInvalidCol);
93 original_problem_->num_constraints());
97 const SparseMatrix& original_matrix = original_problem_->GetSparseMatrix();
99 original_problem_->GetTransposeSparseMatrix();
100 for (
int i = 0; i < cluster.size(); ++i) {
101 const ColIndex global_col = cluster[i];
103 CHECK_EQ(local_col, ColIndex(i));
104 CHECK(global_to_local[global_col] == kInvalidCol ||
105 global_to_local[global_col] == local_col)
106 <<
"If the mapping is already assigned it has to be the same.";
107 global_to_local[global_col] = local_col;
110 original_problem_->GetVariableName(global_col));
112 original_problem_->GetVariableType(global_col));
114 local_col, original_problem_->variable_lower_bounds()[global_col],
115 original_problem_->variable_upper_bounds()[global_col]);
117 local_col, original_problem_->objective_coefficients()[global_col]);
119 for (
const SparseColumn::Entry e : original_matrix.
column(global_col)) {
120 constraints_to_use.Set(e.row());
124 for (
const RowIndex global_row :
125 constraints_to_use.PositionsSetAtLeastOnce()) {
128 original_problem_->GetConstraintName(global_row));
130 local_row, original_problem_->constraint_lower_bounds()[global_row],
131 original_problem_->constraint_upper_bounds()[global_row]);
133 for (
const SparseColumn::Entry e :
134 transposed_matrix.
column(RowToColIndex(global_row))) {
135 const ColIndex global_col = RowToColIndex(e.row());
136 const ColIndex local_col = global_to_local[global_col];
142DenseRow LPDecomposer::AggregateAssignments(
144 CHECK_EQ(assignments.size(), clusters_.size());
146 absl::MutexLock mutex_lock(&mutex_);
147 DenseRow global_assignment(original_problem_->num_variables(),
149 for (
int problem = 0; problem < assignments.size(); ++problem) {
150 const DenseRow& local_assignment = assignments[problem];
151 const std::vector<ColIndex>& cluster = clusters_[problem];
152 for (
int i = 0; i < local_assignment.
size(); ++i) {
153 const ColIndex global_col = cluster[i];
154 global_assignment[global_col] = local_assignment[ColIndex(i)];
157 return global_assignment;
160DenseRow LPDecomposer::ExtractLocalAssignment(
int problem_index,
162 CHECK_GE(problem_index, 0);
163 CHECK_LT(problem_index, clusters_.size());
164 CHECK_EQ(assignment.size(), original_problem_->num_variables());
166 absl::MutexLock mutex_lock(&mutex_);
167 const std::vector<ColIndex>& cluster = clusters_[problem_index];
169 for (
int i = 0; i < cluster.size(); ++i) {
170 const ColIndex global_col = cluster[i];
171 local_assignment[ColIndex(i)] = assignment[global_col];
173 return local_assignment;