22#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>
59 from_deleted_and_into_new_variable_ids = 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 const google::protobuf::RepeatedField<int64_t>& from_new,
218 google::protobuf::RepeatedField<int64_t>& into_old,
219 const google::protobuf::RepeatedField<int64_t>& deleted) {
220 google::protobuf::RepeatedField<int64_t> result;
228 const auto add_if_not_deleted = [&](
const int64_t id) {
229 while (deleted_i < deleted.size() && deleted[deleted_i] < id) {
232 if (deleted_i == deleted.size() || deleted[deleted_i] != id) {
237 while (from_new_i < from_new.size() && into_old_i < into_old.size()) {
238 if (from_new[from_new_i] < into_old[into_old_i]) {
239 add_if_not_deleted(from_new[from_new_i]);
241 }
else if (from_new[from_new_i] > into_old[into_old_i]) {
242 add_if_not_deleted(into_old[into_old_i]);
245 add_if_not_deleted(from_new[from_new_i]);
254 for (; from_new_i < from_new.size(); ++from_new_i) {
255 add_if_not_deleted(from_new[from_new_i]);
257 for (; into_old_i < into_old.size(); ++into_old_i) {
258 add_if_not_deleted(into_old[into_old_i]);
261 into_old.Swap(&result);
265 const SparseDoubleMatrixProto& from_new, SparseDoubleMatrixProto& into_old,
266 const google::protobuf::RepeatedField<int64_t>& deleted_rows,
267 const google::protobuf::RepeatedField<int64_t>& deleted_columns) {
268 SparseDoubleMatrixProto result;
269 auto& result_row_ids = *result.mutable_row_ids();
270 auto& result_column_ids = *result.mutable_column_ids();
271 auto& result_coefficients = *result.mutable_coefficients();
284 const absl::flat_hash_set<int64_t> deleted_columns_set(
285 deleted_columns.begin(), deleted_columns.end());
289 int deleted_rows_i = 0;
295 const auto add_if_not_deleted = [&](
const int64_t row_id,
296 const int64_t col_id,
298 while (deleted_rows_i < deleted_rows.size() &&
299 deleted_rows[deleted_rows_i] < row_id) {
302 if ((deleted_rows_i != deleted_rows.size() &&
303 deleted_rows[deleted_rows_i] == row_id) ||
304 deleted_columns_set.contains(col_id)) {
307 result_row_ids.Add(row_id);
308 result_column_ids.Add(col_id);
312 while (from_new_i < from_new.row_ids_size() &&
313 into_old_i < into_old.row_ids_size()) {
317 const auto from_new_coordinates = std::make_pair(
318 from_new.row_ids(from_new_i), from_new.column_ids(from_new_i));
319 const auto into_old_coordinates = std::make_pair(
320 into_old.row_ids(into_old_i), into_old.column_ids(into_old_i));
321 if (from_new_coordinates < into_old_coordinates) {
322 add_if_not_deleted(from_new_coordinates.first,
323 from_new_coordinates.second,
324 from_new.coefficients(from_new_i));
326 }
else if (from_new_coordinates > into_old_coordinates) {
327 add_if_not_deleted(into_old_coordinates.first,
328 into_old_coordinates.second,
329 into_old.coefficients(into_old_i));
332 add_if_not_deleted(from_new_coordinates.first,
333 from_new_coordinates.second,
334 from_new.coefficients(from_new_i));
343 for (; from_new_i < from_new.row_ids_size(); ++from_new_i) {
344 add_if_not_deleted(from_new.row_ids(from_new_i),
345 from_new.column_ids(from_new_i),
346 from_new.coefficients(from_new_i));
348 for (; into_old_i < into_old.row_ids_size(); ++into_old_i) {
349 add_if_not_deleted(into_old.row_ids(into_old_i),
350 into_old.column_ids(into_old_i),
351 into_old.coefficients(into_old_i));
354 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.