166 std::vector<std::vector<MatchingType>> &matchings) {
168 Timer const t_update;
174 double max_shift = 0;
176 std::vector<double> weight_diag_matchings(
179 std::vector<size_t> count_diag_matchings(
182 std::vector<double> x(n_goods, 0);
183 std::vector<double> y(n_goods, 0);
184 std::vector<double> crit_coords_x(n_goods, 0);
185 std::vector<double> crit_coords_y(n_goods, 0);
186 std::vector<double> crit_coords_z(n_goods, 0);
188 std::vector<double> min_prices(
189 n_diagrams, std::numeric_limits<double>::max());
193 std::vector<std::pair<Bidder *, double>> points_to_append;
194 std::vector<int> diagonalToNewGood;
200 for(
size_t j = 0; j < matchings.size(); j++) {
202 for(
size_t i = 0; i < matchings[j].size(); i++) {
203 int const bidder_id = std::get<0>(matchings[j][i]);
204 int const good_id = std::get<1>(matchings[j][i]);
205 if(good_id < 0 && bidder_id >= 0) {
207 points_to_append.emplace_back(
210 diagonalToNewGood[-good_id - 1]
211 = n_goods + points_to_append.size() - 1;
214 else if(good_id >= 0 && bidder_id >= 0) {
226 .GetCriticalCoordinates();
227 crit_coords_x[good_id] += critical_coordinates[0];
228 crit_coords_y[good_id] += critical_coordinates[1];
229 crit_coords_z[good_id] += critical_coordinates[2];
231 }
else if(good_id >= 0 && bidder_id < 0) {
234 count_diag_matchings[good_id] = count_diag_matchings[good_id] + 1;
236 weight_diag_matchings[good_id]
237 = weight_diag_matchings[good_id] + weight;
244 for(
size_t i = 0; i < n_goods; i++) {
245 if(count_diag_matchings[i] < n_diagrams) {
256 if(weight_diag_matchings[i] < 1) {
257 x_bar = x[i] / (1 - weight_diag_matchings[i]);
258 y_bar = y[i] / (1 - weight_diag_matchings[i]);
261 x_bar = x[i] / (double)(n_diagrams - count_diag_matchings[i]);
262 y_bar = y[i] / (double)(n_diagrams - count_diag_matchings[i]);
271 new_x = (1 - weight_diag_matchings[i]) * x_bar
272 + weight_diag_matchings[i] * (x_bar + y_bar) / 2.;
273 new_y = (1 - weight_diag_matchings[i]) * y_bar
274 + weight_diag_matchings[i] * (x_bar + y_bar) / 2.;
276 new_x = ((double)(n_diagrams - count_diag_matchings[i]) * x_bar
277 + (double)count_diag_matchings[i] * (x_bar + y_bar) / 2.)
278 / (
double)n_diagrams;
279 new_y = ((double)(n_diagrams - count_diag_matchings[i]) * y_bar
280 + (double)count_diag_matchings[i] * (x_bar + y_bar) / 2.)
281 / (
double)n_diagrams;
285 double const new_crit_coord_x
286 = crit_coords_x[i] / (double)(n_diagrams - count_diag_matchings[i]);
287 double const new_crit_coord_y
288 = crit_coords_y[i] / (double)(n_diagrams - count_diag_matchings[i]);
289 double const new_crit_coord_z
290 = crit_coords_z[i] / (double)(n_diagrams - count_diag_matchings[i]);
298 if(shift > max_shift) {
302 for(
size_t j = 0; j < n_diagrams; j++) {
306 new_crit_coord_x, new_crit_coord_y, new_crit_coord_z);
315 for(
size_t j = 0; j < n_diagrams; j++) {
316 if(min_prices[j] >= std::numeric_limits<double>::max() / 2.) {
323 for(
size_t i = 0; i < n_goods; i++) {
324 if(count_diag_matchings[i] == n_diagrams) {
330 if(shift > max_shift) {
333 for(
size_t j = 0; j < n_diagrams; j++) {
340 for(
size_t k = 0; k < points_to_append.size(); k++) {
342 Bidder *b = points_to_append[k].first;
344 = (b->
x_ + (n_diagrams - 1) * (b->
x_ + b->
y_) / 2.) / (n_diagrams);
346 = (b->
y_ + (n_diagrams - 1) * (b->
x_ + b->
y_) / 2.) / (n_diagrams);
349 double weight = points_to_append[k].second;
350 gx = weight * b->
x_ + (1 - weight) * (b->
x_ + b->
y_) / 2.;
351 gy = weight * b->
y_ + (1 - weight) * (b->
x_ + b->
y_) / 2.;
354 for(
size_t j = 0; j < n_diagrams; j++) {
359 std::get<1>(critical_coordinates),
360 std::get<2>(critical_coordinates));
367 if(shift > max_shift) {
374 for(
size_t j = 0; j < n_diagrams; j++) {
381 new_barycenter.emplace_back(g);
390 std::vector<double> costs(n_goods + points_to_append.size(), 0.);
391 for(
int i = 0; i < 2; ++i) {
392 for(
auto &[b_id, g_id, c] : matchings[i]) {
393 if(g_id < 0 && diagonalToNewGood[-g_id - 1] > 0)
394 g_id = diagonalToNewGood[-g_id - 1];
399 for(
int i = 0; i < 2; ++i) {
400 for(
auto &[b_id, g_id, c] : matchings[i]) {
442 double previous_min_persistence,
443 double min_persistence,
444 std::vector<double> &initial_diagonal_prices,
445 std::vector<double> &initial_off_diagonal_prices,
446 int min_points_to_add,
447 bool add_points_to_barycenter) {
449 double new_min_persistence = min_persistence;
453 size_t max_diagram_size{};
459 int const max_points_to_add = std::max(
460 min_points_to_add, min_points_to_add + (
int)(max_diagram_size / 10));
467 std::vector<double> persistences;
471 if(persistence >= min_persistence
472 && persistence < previous_min_persistence) {
473 candidates_to_be_added[i].push_back(j);
474 idx[i].push_back(idx[i].size());
475 persistences.push_back(persistence);
478 sort(idx[i].
begin(), idx[i].
end(), [&persistences](
int &a,
int &b) {
479 return ((persistences[a] > persistences[b])
480 || ((persistences[a] == persistences[b]) && (a > b)));
482 int const size = candidates_to_be_added[i].size();
483 if(size >= max_points_to_add) {
484 double const last_persistence_added
485 = persistences[idx[i][max_points_to_add - 1]];
486 if(last_persistence_added > new_min_persistence) {
487 new_min_persistence = last_persistence_added;
495 int counter_for_adding_points = 0;
498 int const size = candidates_to_be_added[i].size();
499 for(
int j = 0; j < std::min(max_points_to_add, size); j++) {
510 int const to_be_added_to_barycenter
514 if(to_be_added_to_barycenter == 0 && add_points_to_barycenter) {
517 g.
setPrice(initial_off_diagonal_prices[k]);
523 counter_for_adding_points++;
526 return new_min_persistence;
656 std::vector<std::vector<MatchingType>> previous_matchings;
657 double const min_persistence = 0;
658 double min_cost = std::numeric_limits<double>::max();
659 int last_min_cost_obtained = 0;
670 int const min_points_to_add = std::numeric_limits<int>::max();
672 min_diag_price, min_price,
673 min_points_to_add,
false);
675 bool converged =
false;
676 bool finished =
false;
682 std::pair<std::unique_ptr<KDT>, std::vector<KDT *>> pair;
683 bool use_kdt =
false;
709 &min_diag_price, &all_matchings, use_kdt,
712 this->
printMsg(
"Barycenter cost : " + std::to_string(total_cost),
722 if(min_cost > total_cost) {
723 min_cost = total_cost;
724 last_min_cost_obtained = 0;
726 last_min_cost_obtained += 1;
729 converged = last_min_cost_obtained > 1;
734 previous_matchings = std::move(all_matchings);
750 barycenter.resize(0);
759 std::vector<std::vector<MatchingType>> corrected_matchings
761 return corrected_matchings;