24#include "absl/container/flat_hash_set.h"
26#include "ortools/math_opt/model.pb.h"
27#include "ortools/math_opt/model_update.pb.h"
28#include "ortools/math_opt/sparse_containers.pb.h"
34 ModelUpdateProto& into_old) {
40 *into_old.mutable_deleted_variable_ids(),
41 into_old.new_variables().ids());
43 from_new.deleted_linear_constraint_ids(),
44 *into_old.mutable_deleted_linear_constraint_ids(),
45 into_old.new_linear_constraints().ids());
58 google::protobuf::RepeatedField<int64_t> from_deleted_and_into_new_variable_ids =
59 from_new.deleted_variable_ids();
60 from_deleted_and_into_new_variable_ids.MergeFrom(
61 into_old.new_variables().ids());
63 google::protobuf::RepeatedField<int64_t>
64 from_deleted_and_into_new_linear_constraint_ids =
65 from_new.deleted_linear_constraint_ids();
66 from_deleted_and_into_new_linear_constraint_ids.MergeFrom(
67 into_old.new_linear_constraints().ids());
71 from_new.variable_updates().lower_bounds(),
72 *into_old.mutable_variable_updates()->mutable_lower_bounds(),
73 from_deleted_and_into_new_variable_ids);
75 from_new.variable_updates().upper_bounds(),
76 *into_old.mutable_variable_updates()->mutable_upper_bounds(),
77 from_deleted_and_into_new_variable_ids);
79 from_new.variable_updates().integers(),
80 *into_old.mutable_variable_updates()->mutable_integers(),
81 from_deleted_and_into_new_variable_ids);
85 from_new.linear_constraint_updates().lower_bounds(),
86 *into_old.mutable_linear_constraint_updates()->mutable_lower_bounds(),
87 from_deleted_and_into_new_linear_constraint_ids);
89 from_new.linear_constraint_updates().upper_bounds(),
90 *into_old.mutable_linear_constraint_updates()->mutable_upper_bounds(),
91 from_deleted_and_into_new_linear_constraint_ids);
108 if (!from_new.new_variables().ids().empty() &&
109 !into_old.new_variables().ids().empty()) {
110 CHECK_GT(*from_new.new_variables().ids().begin(),
111 *into_old.new_variables().ids().rbegin());
114 into_old.new_variables().ids(),
115 *into_old.mutable_new_variables()->mutable_lower_bounds(),
116 from_new.deleted_variable_ids(),
117 from_new.variable_updates().lower_bounds());
119 into_old.new_variables().ids(),
120 *into_old.mutable_new_variables()->mutable_upper_bounds(),
121 from_new.deleted_variable_ids(),
122 from_new.variable_updates().upper_bounds());
124 into_old.new_variables().ids(),
125 *into_old.mutable_new_variables()->mutable_integers(),
126 from_new.deleted_variable_ids(),
127 from_new.variable_updates().integers());
129 into_old.new_variables().ids(),
130 *into_old.mutable_new_variables()->mutable_names(),
131 from_new.deleted_variable_ids(),
135 *into_old.mutable_new_variables()->mutable_ids(),
136 from_new.deleted_variable_ids());
137 into_old.mutable_new_variables()->MergeFrom(from_new.new_variables());
141 if (!from_new.new_linear_constraints().ids().empty() &&
142 !into_old.new_linear_constraints().ids().empty()) {
143 CHECK_GT(*from_new.new_linear_constraints().ids().begin(),
144 *into_old.new_linear_constraints().ids().rbegin());
147 into_old.new_linear_constraints().ids(),
149 *into_old.mutable_new_linear_constraints()->mutable_lower_bounds(),
150 from_new.deleted_linear_constraint_ids(),
151 from_new.linear_constraint_updates().lower_bounds());
153 into_old.new_linear_constraints().ids(),
155 *into_old.mutable_new_linear_constraints()->mutable_upper_bounds(),
156 from_new.deleted_linear_constraint_ids(),
157 from_new.linear_constraint_updates().upper_bounds());
159 into_old.new_linear_constraints().ids(),
160 *into_old.mutable_new_linear_constraints()->mutable_names(),
161 from_new.deleted_linear_constraint_ids(),
165 *into_old.mutable_new_linear_constraints()->mutable_ids(),
166 from_new.deleted_linear_constraint_ids());
167 into_old.mutable_new_linear_constraints()->MergeFrom(
168 from_new.new_linear_constraints());
171 if (from_new.objective_updates().has_direction_update()) {
172 into_old.mutable_objective_updates()->set_direction_update(
173 from_new.objective_updates().direction_update());
175 if (from_new.objective_updates().has_offset_update()) {
176 into_old.mutable_objective_updates()->set_offset_update(
177 from_new.objective_updates().offset_update());
180 from_new.objective_updates().linear_coefficients(),
181 *into_old.mutable_objective_updates()->mutable_linear_coefficients(),
182 from_new.deleted_variable_ids());
184 from_new.objective_updates().quadratic_coefficients(),
185 *into_old.mutable_objective_updates()->mutable_quadratic_coefficients(),
186 from_new.deleted_variable_ids(),
187 from_new.deleted_variable_ids());
191 from_new.linear_constraint_matrix_updates(),
192 *into_old.mutable_linear_constraint_matrix_updates(),
193 from_new.deleted_linear_constraint_ids(),
194 from_new.deleted_variable_ids());
200 const google::protobuf::RepeatedField<int64_t>& deleted) {
201 int next_insertion_point = 0;
203 for (
const int64_t
id : ids) {
204 while (deleted_i < deleted.size() && deleted[deleted_i] <
id) {
207 if (deleted_i < deleted.size() && deleted[deleted_i] ==
id) {
210 ids[next_insertion_point] = id;
211 ++next_insertion_point;
213 ids.Truncate(next_insertion_point);
217 google::protobuf::RepeatedField<int64_t>& into_old,
218 const google::protobuf::RepeatedField<int64_t>& deleted) {
219 google::protobuf::RepeatedField<int64_t> result;
227 const auto add_if_not_deleted = [&](
const int64_t id) {
228 while (deleted_i < deleted.size() && deleted[deleted_i] < id) {
231 if (deleted_i == deleted.size() || deleted[deleted_i] != id) {
236 while (from_new_i < from_new.size() && into_old_i < into_old.size()) {
237 if (from_new[from_new_i] < into_old[into_old_i]) {
238 add_if_not_deleted(from_new[from_new_i]);
240 }
else if (from_new[from_new_i] > into_old[into_old_i]) {
241 add_if_not_deleted(into_old[into_old_i]);
244 add_if_not_deleted(from_new[from_new_i]);
253 for (; from_new_i < from_new.size(); ++from_new_i) {
254 add_if_not_deleted(from_new[from_new_i]);
256 for (; into_old_i < into_old.size(); ++into_old_i) {
257 add_if_not_deleted(into_old[into_old_i]);
260 into_old.Swap(&result);
264 const SparseDoubleMatrixProto& from_new, SparseDoubleMatrixProto& into_old,
265 const google::protobuf::RepeatedField<int64_t>& deleted_rows,
266 const google::protobuf::RepeatedField<int64_t>& deleted_columns) {
267 SparseDoubleMatrixProto result;
268 auto& result_row_ids = *result.mutable_row_ids();
269 auto& result_column_ids = *result.mutable_column_ids();
270 auto& result_coefficients = *result.mutable_coefficients();
283 const absl::flat_hash_set<int64_t> deleted_columns_set(
284 deleted_columns.begin(), deleted_columns.end());
288 int deleted_rows_i = 0;
294 const auto add_if_not_deleted = [&](
const int64_t row_id,
295 const int64_t col_id,
297 while (deleted_rows_i < deleted_rows.size() &&
298 deleted_rows[deleted_rows_i] < row_id) {
301 if ((deleted_rows_i != deleted_rows.size() &&
302 deleted_rows[deleted_rows_i] == row_id) ||
303 deleted_columns_set.contains(col_id)) {
306 result_row_ids.Add(row_id);
307 result_column_ids.Add(col_id);
311 while (from_new_i < from_new.row_ids_size() &&
312 into_old_i < into_old.row_ids_size()) {
316 const auto from_new_coordinates = std::make_pair(
317 from_new.row_ids(from_new_i), from_new.column_ids(from_new_i));
318 const auto into_old_coordinates = std::make_pair(
319 into_old.row_ids(into_old_i), into_old.column_ids(into_old_i));
320 if (from_new_coordinates < into_old_coordinates) {
321 add_if_not_deleted(from_new_coordinates.first,
322 from_new_coordinates.second,
323 from_new.coefficients(from_new_i));
325 }
else if (from_new_coordinates > into_old_coordinates) {
326 add_if_not_deleted(into_old_coordinates.first,
327 into_old_coordinates.second,
328 into_old.coefficients(into_old_i));
331 add_if_not_deleted(from_new_coordinates.first,
332 from_new_coordinates.second,
333 from_new.coefficients(from_new_i));
342 for (; from_new_i < from_new.row_ids_size(); ++from_new_i) {
343 add_if_not_deleted(from_new.row_ids(from_new_i),
344 from_new.column_ids(from_new_i),
345 from_new.coefficients(from_new_i));
347 for (; into_old_i < into_old.row_ids_size(); ++into_old_i) {
348 add_if_not_deleted(into_old.row_ids(into_old_i),
349 into_old.column_ids(into_old_i),
350 into_old.coefficients(into_old_i));
353 into_old.Swap(&result);
#define CHECK_GT(val1, val2)
void MergeIntoSparseDoubleMatrix(const SparseDoubleMatrixProto &from_new, SparseDoubleMatrixProto &into_old, const google::protobuf::RepeatedField< int64_t > &deleted_rows, const google::protobuf::RepeatedField< int64_t > &deleted_columns)
void MergeIntoSortedIds(const google::protobuf::RepeatedField< int64_t > &from_new, google::protobuf::RepeatedField< int64_t > &into_old, const google::protobuf::RepeatedField< int64_t > &deleted)
void UpdateNewElementProperty(const google::protobuf::RepeatedField< int64_t > &ids, RepeatedField &values, const google::protobuf::RepeatedField< int64_t > &deleted, const SparseVector &updates)
void RemoveDeletedIds(google::protobuf::RepeatedField< int64_t > &ids, const google::protobuf::RepeatedField< int64_t > &deleted)
void MergeIntoSparseVector(const SparseVector &from_new, SparseVector &into_old, const google::protobuf::RepeatedField< int64_t > &deleted)
void MergeIntoUpdate(const ModelUpdateProto &from_new, ModelUpdateProto &into_old)
Collection of objects used to extend the Constraint Solver library.