29 std::vector<int> &sizes,
31 std::vector<KDT *> &correspondence_kdt_map,
32 std::vector<double> *min_diag_price,
33 std::vector<double> *min_price,
34 std::vector<std::vector<MatchingType>> *all_matchings,
36 bool actual_distance) {
37 Timer const time_matchings;
39 double local_cost = *total_cost;
40#ifdef TTK_ENABLE_OPENMP
41#pragma omp parallel for num_threads(threadNumber_) schedule(dynamic, 1) \
42 reduction(+ : local_cost)
58 std::vector<MatchingType> matchings;
60 all_matchings->at(i) = matchings;
62 local_cost += sqrt(cost);
69 precision_[i] = quotient < 1 ? 1. / sqrt(1 - quotient) - 1 : 10;
77 *total_cost = local_cost;
82 std::vector<int> &sizes,
84 std::vector<KDT *> &correspondence_kdt_map,
85 std::vector<double> *min_diag_price,
86 std::vector<std::vector<MatchingType>> *all_matchings,
88 bool actual_distance) {
89 double local_cost = *total_cost;
90#ifdef TTK_ENABLE_OPENMP
91#pragma omp parallel for num_threads(threadNumber_) schedule(dynamic, 1) \
92 reduction(+ : local_cost)
99 std::vector<MatchingType> matchings;
100 double const cost = auction.
run(matchings, i);
101 all_matchings->at(i) = matchings;
102 if(actual_distance) {
103 local_cost += sqrt(cost);
113 *total_cost = local_cost;
138 std::vector<std::vector<MatchingType>> &previous_matchings) {
140 std::vector<std::vector<MatchingType>> corrected_matchings(
numberOfInputs_);
147 new_to_old_id[new_id] = j;
151 std::vector<MatchingType> matchings_diagram_i;
152 for(
size_t j = 0; j < previous_matchings[i].size(); j++) {
154 int const new_id = std::get<0>(m);
155 if(new_id >= 0 && std::get<1>(m) >= 0) {
156 std::get<0>(m) = new_to_old_id[new_id];
157 matchings_diagram_i.push_back(m);
160 corrected_matchings[i] = matchings_diagram_i;
162 return corrected_matchings;
166 std::vector<std::vector<MatchingType>> &matchings) {
168 Timer const t_update;
174 double max_shift = 0;
176 std::vector<size_t> count_diag_matchings(
179 std::vector<double> x(n_goods, 0);
180 std::vector<double> y(n_goods, 0);
181 std::vector<double> crit_coords_x(n_goods, 0);
182 std::vector<double> crit_coords_y(n_goods, 0);
183 std::vector<double> crit_coords_z(n_goods, 0);
185 std::vector<double> min_prices(
186 n_diagrams, std::numeric_limits<double>::max());
188 std::vector<Bidder *>
190 std::vector<int> diagonalToNewGood;
195 for(
size_t j = 0; j < matchings.size(); j++) {
196 for(
size_t i = 0; i < matchings[j].size(); i++) {
197 int const bidder_id = std::get<0>(matchings[j][i]);
198 int const good_id = std::get<1>(matchings[j][i]);
199 if(good_id < 0 && bidder_id >= 0) {
203 diagonalToNewGood[-good_id - 1]
204 = n_goods + points_to_append.size() - 1;
207 else if(good_id >= 0 && bidder_id >= 0) {
214 .GetCriticalCoordinates();
215 crit_coords_x[good_id] += critical_coordinates[0];
216 crit_coords_y[good_id] += critical_coordinates[1];
217 crit_coords_z[good_id] += critical_coordinates[2];
219 }
else if(good_id >= 0 && bidder_id < 0) {
222 count_diag_matchings[good_id] = count_diag_matchings[good_id] + 1;
228 for(
size_t i = 0; i < n_goods; i++) {
229 if(count_diag_matchings[i] < n_diagrams) {
233 = x[i] / (double)(n_diagrams - count_diag_matchings[i]);
235 = y[i] / (double)(n_diagrams - count_diag_matchings[i]);
239 = ((double)(n_diagrams - count_diag_matchings[i]) * x_bar
240 + (double)count_diag_matchings[i] * (x_bar + y_bar) / 2.)
241 / (
double)n_diagrams;
243 = ((double)(n_diagrams - count_diag_matchings[i]) * y_bar
244 + (double)count_diag_matchings[i] * (x_bar + y_bar) / 2.)
245 / (
double)n_diagrams;
247 double const new_crit_coord_x
248 = crit_coords_x[i] / (double)(n_diagrams - count_diag_matchings[i]);
249 double const new_crit_coord_y
250 = crit_coords_y[i] / (double)(n_diagrams - count_diag_matchings[i]);
251 double const new_crit_coord_z
252 = crit_coords_z[i] / (double)(n_diagrams - count_diag_matchings[i]);
260 if(shift > max_shift) {
264 for(
size_t j = 0; j < n_diagrams; j++) {
268 new_crit_coord_x, new_crit_coord_y, new_crit_coord_z);
277 for(
size_t j = 0; j < n_diagrams; j++) {
278 if(min_prices[j] >= std::numeric_limits<double>::max() / 2.) {
285 for(
size_t i = 0; i < n_goods; i++) {
286 if(count_diag_matchings[i] == n_diagrams) {
292 if(shift > max_shift) {
295 for(
size_t j = 0; j < n_diagrams; j++) {
302 for(
size_t k = 0; k < points_to_append.size(); k++) {
304 Bidder *b = points_to_append[k];
306 = (b->
x_ + (n_diagrams - 1) * (b->
x_ + b->
y_) / 2.) / (n_diagrams);
308 = (b->
y_ + (n_diagrams - 1) * (b->
x_ + b->
y_) / 2.) / (n_diagrams);
310 for(
size_t j = 0; j < n_diagrams; j++) {
315 std::get<1>(critical_coordinates),
316 std::get<2>(critical_coordinates));
323 if(shift > max_shift) {
330 for(
size_t j = 0; j < n_diagrams; j++) {
337 new_barycenter.emplace_back(g);
346 std::vector<double> costs(n_goods + points_to_append.size(), 0.);
347 for(
int i = 0; i < 2; ++i) {
348 for(
auto &[b_id, g_id, c] : matchings[i]) {
349 if(g_id < 0 && diagonalToNewGood[-g_id - 1] > 0)
350 g_id = diagonalToNewGood[-g_id - 1];
355 for(
int i = 0; i < 2; ++i) {
356 for(
auto &[b_id, g_id, c] : matchings[i]) {
398 double previous_min_persistence,
399 double min_persistence,
400 std::vector<double> &initial_diagonal_prices,
401 std::vector<double> &initial_off_diagonal_prices,
402 int min_points_to_add,
403 bool add_points_to_barycenter) {
405 double new_min_persistence = min_persistence;
409 size_t max_diagram_size{};
415 int const max_points_to_add = std::max(
416 min_points_to_add, min_points_to_add + (
int)(max_diagram_size / 10));
423 std::vector<double> persistences;
427 if(persistence >= min_persistence
428 && persistence < previous_min_persistence) {
429 candidates_to_be_added[i].push_back(j);
430 idx[i].push_back(idx[i].size());
431 persistences.push_back(persistence);
434 sort(idx[i].
begin(), idx[i].
end(), [&persistences](
int &a,
int &b) {
435 return ((persistences[a] > persistences[b])
436 || ((persistences[a] == persistences[b]) && (a > b)));
438 int const size = candidates_to_be_added[i].size();
439 if(size >= max_points_to_add) {
440 double const last_persistence_added
441 = persistences[idx[i][max_points_to_add - 1]];
442 if(last_persistence_added > new_min_persistence) {
443 new_min_persistence = last_persistence_added;
451 int counter_for_adding_points = 0;
454 int const size = candidates_to_be_added[i].size();
455 for(
int j = 0; j < std::min(max_points_to_add, size); j++) {
466 int const to_be_added_to_barycenter
470 if(to_be_added_to_barycenter == 0 && add_points_to_barycenter) {
473 g.
setPrice(initial_off_diagonal_prices[k]);
479 counter_for_adding_points++;
482 return new_min_persistence;
612 std::vector<std::vector<MatchingType>> previous_matchings;
613 double const min_persistence = 0;
614 double min_cost = std::numeric_limits<double>::max();
615 int last_min_cost_obtained = 0;
626 int const min_points_to_add = std::numeric_limits<int>::max();
628 min_diag_price, min_price,
629 min_points_to_add,
false);
631 bool converged =
false;
632 bool finished =
false;
638 std::pair<std::unique_ptr<KDT>, std::vector<KDT *>> pair;
639 bool use_kdt =
false;
665 &min_diag_price, &all_matchings, use_kdt,
668 this->
printMsg(
"Barycenter cost : " + std::to_string(total_cost),
678 if(min_cost > total_cost) {
679 min_cost = total_cost;
680 last_min_cost_obtained = 0;
682 last_min_cost_obtained += 1;
685 converged = last_min_cost_obtained > 1;
690 previous_matchings = std::move(all_matchings);
706 barycenter.resize(0);
715 std::vector<std::vector<MatchingType>> corrected_matchings
717 return corrected_matchings;
void runMatching(double *total_cost, double epsilon, std::vector< int > &sizes, KDT &kdt, std::vector< KDT * > &correspondence_kdt_map, std::vector< double > *min_diag_price, std::vector< double > *min_price, std::vector< std::vector< MatchingType > > *all_matchings, bool use_kdt, bool actual_distance)