25 std::vector<DiagramType> &final_centroids,
26 std::vector<std::vector<std::vector<std::vector<MatchingType>>>>
27 &all_matchings_per_type_and_cluster) {
29 all_matchings_per_type_and_cluster.resize(
k_);
30 for(
int c = 0; c <
k_; c++) {
31 all_matchings_per_type_and_cluster[c].resize(3);
32 for(
int i = 0; i < 3; i++) {
36 int matchings_only =
false;
46 matchings_only =
true;
51 std::vector<bool *> current_prec;
56 std::vector<bool *> current_dos;
57 current_dos.emplace_back(&
do_min_);
58 current_dos.emplace_back(&
do_sad_);
59 current_dos.emplace_back(&
do_max_);
60 bool converged =
false;
61 std::vector<bool> diagrams_complete(3);
62 for(
int c = 0; c < 3; c++) {
66 double total_time = 0;
70 cost_ = std::numeric_limits<double>::max();
71 double min_cost_min = std::numeric_limits<double>::max();
72 double min_cost_max = std::numeric_limits<double>::max();
73 double min_cost_sad = std::numeric_limits<double>::max();
75 double last_min_cost_obtained_min = -1;
76 double last_min_cost_obtained_sad = -1;
77 double last_min_cost_obtained_max = -1;
78 std::vector<double> epsilon0(3);
79 std::vector<double> epsilon_candidate(3);
80 std::vector<double> rho(3);
83 std::vector<double> max_persistence(3);
84 std::vector<double> lowest_persistence(3);
85 std::vector<double> min_persistence(3);
87 const auto square = [](
const double a) {
return a * a; };
89 for(
int i_crit = 0; i_crit < 3; i_crit++) {
92 min_persistence[i_crit] = 0;
93 epsilon_[i_crit] = square(0.5 * max_persistence[i_crit])
99 std::vector<int> min_points_to_add(3);
100 min_points_to_add[0] = 10;
101 min_points_to_add[1] = 10;
102 min_points_to_add[2] = 10;
106 min_points_to_add[0] = std::numeric_limits<int>::max();
107 min_points_to_add[1] = std::numeric_limits<int>::max();
108 min_points_to_add[2] = std::numeric_limits<int>::max();
110 std::vector<std::vector<double>> min_diag_price(3);
111 std::vector<std::vector<double>> min_off_diag_price(3);
112 for(
int c = 0; c < 3; ++c) {
114 min_diag_price[c].emplace_back(0);
115 min_off_diag_price[c].emplace_back(0);
119 max_persistence, min_persistence, min_diag_price, min_off_diag_price,
120 min_points_to_add,
false,
true);
122 for(
int c = 0; c < 3; c++) {
123 if(min_persistence[c] <= lowest_persistence[c]) {
124 diagrams_complete[c] =
true;
127 bool all_diagrams_complete
128 = diagrams_complete[0] && diagrams_complete[1] && diagrams_complete[2];
129 if(all_diagrams_complete) {
158 for(
int i_crit = 0; i_crit < 3; i_crit++) {
159 if(*(current_dos[i_crit])) {
160 rho[i_crit] = min_persistence[i_crit] > 0
172 for(
int i_crit = 0; i_crit < 3; i_crit++) {
173 if(*(current_dos[i_crit])) {
174 epsilon_candidate[i_crit] = square(min_persistence[i_crit]) / 8.;
175 if(epsilon_candidate[i_crit] >
epsilon_[i_crit]) {
178 epsilon_[i_crit] = epsilon_candidate[i_crit];
186 min_persistence[0] = 0;
187 min_points_to_add[0] = std::numeric_limits<int>::max();
192 min_persistence[1] = 0;
193 min_points_to_add[1] = std::numeric_limits<int>::max();
198 min_persistence[2] = 0;
199 min_points_to_add[2] = std::numeric_limits<int>::max();
204 min_persistence, rho, min_diag_price, min_off_diag_price,
205 min_points_to_add,
true,
false);
209 for(
int i_crit = 0; i_crit < 3; i_crit++) {
210 if(*(current_dos[i_crit])) {
211 if(min_persistence[i_crit] <= lowest_persistence[i_crit]) {
212 diagrams_complete[i_crit] =
true;
217 if(diagrams_complete[0] && diagrams_complete[1]
218 && diagrams_complete[2]) {
220 all_diagrams_complete =
true;
226 &min_off_diag_price, &min_diag_price,
227 all_matchings_per_type_and_cluster, matchings_only);
238 for(
int i_crit = 0; i_crit < 3; i_crit++) {
239 if(*(current_dos[i_crit]) ) {
240 epsilon_candidate[i_crit] = std::min(
241 std::max(max_shift_vec[i_crit] / 8.,
epsilon_[i_crit] / 5.),
244 if((epsilon_candidate[i_crit] <
epsilon_[i_crit]
245 && !diagrams_complete[i_crit])
246 || diagrams_complete[i_crit]) {
247 epsilon_[i_crit] = epsilon_candidate[i_crit];
255 this->
printMsg(
"[min barycenter] epsilon under minimal value ",
259 diagrams_complete[0] =
true;
262 this->
printMsg(
"[sad barycenter] epsilon under minimal value ",
266 diagrams_complete[1] =
true;
269 this->
printWrn(
"[max barycenter] epsilon under minimal value ");
272 diagrams_complete[2] =
true;
275 if(diagrams_complete[0] && diagrams_complete[1]
276 && diagrams_complete[2]) {
278 all_diagrams_complete =
true;
291 +
" epsilon " + std::to_string(
epsilon_[0]) +
" "
295 this->
printMsg(
" complete " + std::to_string(diagrams_complete[0]) +
" "
296 + std::to_string(diagrams_complete[1]) +
" "
297 + std::to_string(diagrams_complete[2]),
308 if(cost_min_ < min_cost_min && n_iterations_ > 2
309 && diagrams_complete[0] ) {
311 last_min_cost_obtained_min = 0;
313 last_min_cost_obtained_min += 1;
314 if(last_min_cost_obtained_min > 1) {
319 if(cost_sad_ < min_cost_sad && n_iterations_ > 2
320 && diagrams_complete[1] ) {
322 last_min_cost_obtained_sad = 0;
324 last_min_cost_obtained_sad += 1;
325 if(last_min_cost_obtained_sad > 1 && diagrams_complete[1]) {
330 if(cost_max_ < min_cost_max && n_iterations_ > 2
331 && diagrams_complete[2] ) {
333 last_min_cost_obtained_max = 0;
335 last_min_cost_obtained_max += 1;
336 if(last_min_cost_obtained_max > 1 && diagrams_complete[2]) {
345 converged = converged
347 && !
do_max_ && (precision_criterion_reached))
362 all_diagrams_complete =
true;
363 diagrams_complete[0] =
true;
364 diagrams_complete[1] =
true;
365 diagrams_complete[2] =
true;
370 <<
" == complete : " << all_diagrams_complete
372 <<
" , converged : " << converged << std::endl;
378 std::vector<std::vector<std::string>>
const rows{
379 {
" Min-saddle cost", std::to_string(
cost_min_)},
380 {
" Saddle-saddle cost", std::to_string(
cost_sad_)},
381 {
" Saddle-max cost", std::to_string(
cost_max_)},
382 {matchings_only ?
"Wasserstein Distance" :
"Final Cost",
393 this->
printMsg(
"Clustering result:");
406 final_centroids.resize(
k_);
408 for(
int c = 0; c <
k_; c++) {
418 for(
int c = 0; c <
k_; ++c) {
422 int const removeFirstPairMin
424 int addedFirstPairMax = 0;
425 int addedFirstPairMin = removeFirstPairMin;
435 addedFirstPairMax = 1;
443 addedFirstPairMin = 1;
447 for(
size_t i = addedFirstPairMin; i <
centroids_min_[c].size(); ++i) {
454 this->
printMsg(
"Found a abnormally high persistence in min diagram",
468 this->
printMsg(
"Found a abnormally high persistence in sad diagram",
475 for(
size_t i = addedFirstPairMax; i <
centroids_max_[c].size(); ++i) {
490 this->
printMsg(
"Found a abnormally high persistence in min diagram",
507 std::vector<std::vector<std::vector<std::vector<MatchingType>>>>
508 &previous_matchings) {
509 for(
int c = 0; c < k_; c++) {
510 for(
size_t i = 0; i < clustering_[c].size(); i++) {
511 int const diagram_id = clustering_[c][i];
512 if(original_dos[0]) {
514 std::vector<int> new_to_old_id(
515 current_bidder_diagrams_min_[diagram_id].size(), -1);
516 for(
size_t j = 0; j < current_bidder_ids_min_[diagram_id].size(); j++) {
517 int const new_id = current_bidder_ids_min_[diagram_id][j];
519 new_to_old_id[new_id] = j;
523 std::vector<MatchingType> matchings_diagram_i;
524 for(
size_t j = 0; j < previous_matchings[c][0][i].size(); j++) {
526 int const new_id = std::get<0>(m);
527 if(new_id >= 0 && std::get<1>(m) >= 0) {
528 std::get<0>(m) = new_to_old_id[new_id];
529 matchings_diagram_i.emplace_back(m);
530 }
else if(std::get<1>(m)
533 matchings_diagram_i.emplace_back(m);
536 previous_matchings[c][0][i].resize(matchings_diagram_i.size());
537 previous_matchings[c][0][i] = matchings_diagram_i;
539 if(original_dos[1]) {
541 std::vector<int> new_to_old_id(
542 current_bidder_diagrams_saddle_[diagram_id].size());
543 for(
size_t j = 0; j < current_bidder_ids_sad_[diagram_id].size(); j++) {
544 int const new_id = current_bidder_ids_sad_[diagram_id][j];
546 new_to_old_id[new_id] = j;
551 std::vector<MatchingType> matchings_diagram_i;
552 for(
size_t j = 0; j < previous_matchings[c][1][i].size(); j++) {
554 int const new_id = std::get<0>(m);
555 if(new_id >= 0 && std::get<1>(m) >= 0) {
556 int const old_id = new_to_old_id[new_id];
558 std::get<0>(m) = old_id;
559 matchings_diagram_i.emplace_back(m);
563 std::get<0>(m) = old_id;
564 matchings_diagram_i.emplace_back(m);
567 }
else if(std::get<1>(m)
570 matchings_diagram_i.emplace_back(m);
573 previous_matchings[c][1][i].resize(matchings_diagram_i.size());
574 previous_matchings[c][1][i] = matchings_diagram_i;
576 if(original_dos[2]) {
578 std::vector<int> new_to_old_id(
579 current_bidder_diagrams_max_[diagram_id].size());
580 for(
size_t j = 0; j < current_bidder_ids_max_[diagram_id].size(); j++) {
581 int const new_id = current_bidder_ids_max_[diagram_id][j];
583 new_to_old_id[new_id] = j;
588 std::vector<MatchingType> matchings_diagram_i;
589 for(
size_t j = 0; j < previous_matchings[c][2][i].size(); j++) {
591 int const new_id = std::get<0>(m);
592 if(new_id >= 0 && std::get<1>(m) >= 0) {
593 int const old_id = new_to_old_id[new_id];
595 std::get<0>(m) = old_id;
596 matchings_diagram_i.emplace_back(m);
600 std::get<0>(m) = old_id;
601 matchings_diagram_i.emplace_back(m);
604 }
else if(std::get<1>(m)
607 matchings_diagram_i.emplace_back(m);
610 previous_matchings[c][2][i].resize(matchings_diagram_i.size());
611 previous_matchings[c][2][i] = matchings_diagram_i;
946 std::vector<int> indexes_clusters;
947 int const random_idx = deterministic_ ? 0 : rand() % numberOfInputs_;
948 indexes_clusters.emplace_back(random_idx);
952 = diagramToCentroid(current_bidder_diagrams_min_[random_idx]);
953 centroids_min_.emplace_back(centroid_min);
957 = diagramToCentroid(current_bidder_diagrams_saddle_[random_idx]);
958 centroids_saddle_.emplace_back(centroid_sad);
962 = diagramToCentroid(current_bidder_diagrams_max_[random_idx]);
963 centroids_max_.emplace_back(centroid_max);
966 const auto square = [](
const double a) {
return a * a; };
968 while((
int)indexes_clusters.size() < k_) {
969 std::vector<double> min_distance_to_centroid(numberOfInputs_);
970 std::vector<double> probabilities(numberOfInputs_);
973 double maximal_distance = 0;
974 int candidate_centroid = 0;
976 for(
int i = 0; i < numberOfInputs_; i++) {
978 min_distance_to_centroid[i] = std::numeric_limits<double>::max();
979 if(std::find(indexes_clusters.begin(), indexes_clusters.end(), i)
980 != indexes_clusters.end()) {
982 min_distance_to_centroid[i] = 0;
985 for(
size_t j = 0; j < indexes_clusters.size(); ++j) {
990 = centroidWithZeroPrices(centroids_min_[j]);
991 distance += computeDistance(
992 current_bidder_diagrams_min_[i], centroid_min, 0.01);
996 = centroidWithZeroPrices(centroids_saddle_[j]);
997 distance += computeDistance(
998 current_bidder_diagrams_saddle_[i], centroid_saddle, 0.01);
1002 = centroidWithZeroPrices(centroids_max_[j]);
1003 distance += computeDistance(
1004 current_bidder_diagrams_max_[i], centroid_max, 0.01);
1006 if(distance < min_distance_to_centroid[i]) {
1007 min_distance_to_centroid[i] = distance;
1011 probabilities[i] = square(min_distance_to_centroid[i]);
1015 if(deterministic_ && min_distance_to_centroid[i] > maximal_distance) {
1016 maximal_distance = min_distance_to_centroid[i];
1017 candidate_centroid = i;
1021 std::random_device rd;
1022 std::mt19937 gen(rd());
1023 std::discrete_distribution<int> distribution(
1024 probabilities.begin(), probabilities.end());
1026 if(!deterministic_) {
1027 candidate_centroid = distribution(gen);
1030 indexes_clusters.emplace_back(candidate_centroid);
1033 = diagramToCentroid(current_bidder_diagrams_min_[candidate_centroid]);
1034 centroids_min_.emplace_back(centroid_min);
1037 GoodDiagram const centroid_sad = diagramToCentroid(
1038 current_bidder_diagrams_saddle_[candidate_centroid]);
1039 centroids_saddle_.emplace_back(centroid_sad);
1043 = diagramToCentroid(current_bidder_diagrams_max_[candidate_centroid]);
1044 centroids_max_.emplace_back(centroid_max);
1279 getCentroidDistanceMatrix();
1280 old_clustering_ = clustering_;
1283 initializeEmptyClusters();
1284 bool const do_min = original_dos[0];
1285 bool const do_sad = original_dos[1];
1286 bool const do_max = original_dos[2];
1288 for(
int i = 0; i < numberOfInputs_; ++i) {
1292 D1_min = diagramWithZeroPrices(current_bidder_diagrams_min_[i]);
1295 D1_sad = diagramWithZeroPrices(current_bidder_diagrams_saddle_[i]);
1298 D1_max = diagramWithZeroPrices(current_bidder_diagrams_max_[i]);
1301 for(
int c = 0; c < k_; ++c) {
1302 if(inv_clustering_[i] == -1) {
1305 if(deterministic_) {
1306 inv_clustering_[i] = i % k_;
1308 std::cout <<
" - ASSIGNED TO A RANDOM CLUSTER " <<
'\n';
1309 inv_clustering_[i] = rand() % (k_);
1314 centroids_with_price_min_[i]
1315 = centroidWithZeroPrices(centroids_min_[inv_clustering_[i]]);
1318 centroids_with_price_saddle_[i]
1319 = centroidWithZeroPrices(centroids_saddle_[inv_clustering_[i]]);
1322 centroids_with_price_max_[i]
1323 = centroidWithZeroPrices(centroids_max_[inv_clustering_[i]]);
1327 if(c != inv_clustering_[i] && u_[i] > l_[i][c]
1328 && u_[i] > 0.5 * centroidsDistanceMatrix_[inv_clustering_[i]][c]) {
1331 double distance = 0;
1332 GoodDiagram centroid_min, centroid_sad, centroid_max;
1335 = centroidWithZeroPrices(centroids_min_[inv_clustering_[i]]);
1336 distance += computeDistance(D1_min, centroid_min, 0.01);
1340 = centroidWithZeroPrices(centroids_saddle_[inv_clustering_[i]]);
1341 distance += computeDistance(D1_sad, centroid_sad, 0.01);
1345 = centroidWithZeroPrices(centroids_max_[inv_clustering_[i]]);
1346 distance += computeDistance(D1_max, centroid_max, 0.01);
1350 l_[i][inv_clustering_[i]] = distance;
1353 if((n_iterations_ > 2 || n_iterations_ < 1)
1354 && (u_[i] > l_[i][c]
1356 > 0.5 * centroidsDistanceMatrix_[inv_clustering_[i]][c])) {
1358 GoodDiagram centroid_min, centroid_sad, centroid_max;
1359 double distance = 0;
1362 centroid_min = centroidWithZeroPrices(centroids_min_[c]);
1364 = diagramWithZeroPrices(current_bidder_diagrams_min_[i]);
1365 distance += computeDistance(diagram_min, centroid_min, 0.01);
1368 centroid_sad = centroidWithZeroPrices(centroids_saddle_[c]);
1370 = diagramWithZeroPrices(current_bidder_diagrams_saddle_[i]);
1371 distance += computeDistance(diagram_sad, centroid_sad, 0.01);
1374 centroid_max = centroidWithZeroPrices(centroids_max_[c]);
1376 = diagramWithZeroPrices(current_bidder_diagrams_max_[i]);
1377 distance += computeDistance(diagram_max, centroid_max, 0.01);
1379 l_[i][c] = distance;
1382 if(distance < u_[i]) {
1384 resetDosToOriginalValues();
1385 barycenter_inputs_reset_flag =
true;
1387 inv_clustering_[i] = c;
1390 centroids_with_price_min_[i]
1391 = centroidWithZeroPrices(centroids_min_[c]);
1394 centroids_with_price_saddle_[i]
1395 = centroidWithZeroPrices(centroids_saddle_[c]);
1398 centroids_with_price_max_[i]
1399 = centroidWithZeroPrices(centroids_max_[c]);
1406 invertInverseClusters();
1407 for(
int c = 0; c < k_; ++c) {
1408 if(clustering_[c].empty()) {
1409 std::cout <<
"Adding artificial centroid because a cluster was empty"
1411 bool idx_acceptable =
false;
1414 std::vector<double> copy_of_u(u_.size());
1416 while(!idx_acceptable) {
1417 auto argMax = std::max_element(copy_of_u.begin(), copy_of_u.end());
1418 idx = std::distance(copy_of_u.begin(), argMax);
1419 if(inv_clustering_[idx] < k_ && inv_clustering_[idx] >= 0
1420 && clustering_[inv_clustering_[idx]].size() > 1) {
1421 idx_acceptable =
true;
1422 int const cluster_removal = inv_clustering_[idx];
1424 clustering_[cluster_removal].erase(
1425 std::remove(clustering_[cluster_removal].
begin(),
1426 clustering_[cluster_removal].
end(), idx),
1427 clustering_[cluster_removal].
end());
1429 if(copy_of_u.size() > (
size_t)idx) {
1430 copy_of_u.erase(argMax);
1432 idx_acceptable =
true;
1433 int cluster_max = 0;
1434 if(!clustering_[cluster_max].empty()) {
1435 idx = clustering_[cluster_max][0];
1437 for(
int i_test = 1; i_test < k_; i_test++) {
1438 if(clustering_[i_test].size() > clustering_[cluster_max].size()) {
1439 cluster_max = i_test;
1440 idx = clustering_[cluster_max][0];
1443 int const cluster_removal = inv_clustering_[idx];
1444 clustering_[cluster_removal].erase(
1445 std::remove(clustering_[cluster_removal].
begin(),
1446 clustering_[cluster_removal].
end(), idx),
1447 clustering_[cluster_removal].
end());
1452 clustering_[c].emplace_back(idx);
1453 inv_clustering_[idx] = c;
1457 = diagramToCentroid(current_bidder_diagrams_min_[idx]);
1458 centroids_with_price_min_[idx]
1459 = centroidWithZeroPrices(centroids_min_[c]);
1462 centroids_saddle_[c]
1463 = diagramToCentroid(current_bidder_diagrams_saddle_[idx]);
1464 centroids_with_price_saddle_[idx]
1465 = centroidWithZeroPrices(centroids_saddle_[c]);
1469 = diagramToCentroid(current_bidder_diagrams_max_[idx]);
1470 centroids_with_price_max_[idx]
1471 = centroidWithZeroPrices(centroids_max_[c]);
1473 resetDosToOriginalValues();
1474 barycenter_inputs_reset_flag =
true;
1480 std::vector<std::vector<double>> *min_price,
1481 std::vector<std::vector<double>> *min_diag_price,
1482 std::vector<std::vector<std::vector<std::vector<MatchingType>>>>
1483 &all_matchings_per_type_and_cluster,
1484 int only_matchings) {
1485 barycenter_inputs_reset_flag =
true;
1486 std::vector<double> max_shift_vector(3);
1487 max_shift_vector[0] = 0;
1488 max_shift_vector[1] = 0;
1489 max_shift_vector[2] = 0;
1490 double max_shift_c_min = 0;
1491 double max_shift_c_sad = 0;
1492 double max_shift_c_max = 0;
1493 double max_wasserstein_shift = 0;
1494 bool precision_min =
true;
1495 bool precision_sad =
true;
1496 bool precision_max =
true;
1498 double const sq_dist_min = cost_min_;
1499 double const sq_dist_sad = cost_sad_;
1500 double const sq_dist_max = cost_max_;
1511 for(
int c = 0; c < k_; ++c) {
1512 if(!clustering_[c].empty()) {
1513 std::vector<GoodDiagram> centroids_with_price_min,
1514 centroids_with_price_sad, centroids_with_price_max;
1516 for(
int const idx : clustering_[c]) {
1519 std::vector<int>::iterator
const i = std::find(
1520 old_clustering_[c].
begin(), old_clustering_[c].
end(), idx);
1521 int const pos = (i == old_clustering_[c].end())
1523 : std::distance(old_clustering_[c].
begin(), i);
1527 centroids_with_price_min.emplace_back(
1528 centroids_with_price_min_[idx]);
1531 centroids_with_price_sad.emplace_back(
1532 centroids_with_price_saddle_[idx]);
1535 centroids_with_price_max.emplace_back(
1536 centroids_with_price_max_[idx]);
1539 int number_of_points_min = 0;
1540 int number_of_points_max = 0;
1541 int number_of_points_sad = 0;
1546 centroids_with_price_min.emplace_back(
1547 centroidWithZeroPrices(centroids_min_[c]));
1548 current_bidder_diagrams_min_[idx]
1549 = diagramWithZeroPrices(current_bidder_diagrams_min_[idx]);
1550 number_of_points_min += centroids_with_price_min_[idx].size()
1551 + current_bidder_diagrams_min_[idx].size();
1554 centroids_with_price_sad.emplace_back(
1555 centroidWithZeroPrices(centroids_saddle_[c]));
1556 current_bidder_diagrams_saddle_[idx]
1557 = diagramWithZeroPrices(current_bidder_diagrams_saddle_[idx]);
1558 number_of_points_sad
1559 += centroids_with_price_saddle_[idx].size()
1560 + current_bidder_diagrams_saddle_[idx].size();
1563 centroids_with_price_max.emplace_back(
1564 centroidWithZeroPrices(centroids_max_[c]));
1565 current_bidder_diagrams_max_[idx]
1566 = diagramWithZeroPrices(current_bidder_diagrams_max_[idx]);
1567 number_of_points_max += centroids_with_price_max_[idx].size()
1568 + current_bidder_diagrams_max_[idx].size();
1571 if(n_iterations_ > 1) {
1582 double estimated_delta_lim
1584 / sqrt(1 - number_of_points_min * epsilon_[0] / sq_dist_min)
1586 if(estimated_delta_lim > 1) {
1587 estimated_delta_lim = 1;
1589 computeDistance(&(current_bidder_diagrams_min_[idx]),
1590 &(centroids_with_price_min[count]),
1591 estimated_delta_lim);
1596 double estimated_delta_lim
1598 / sqrt(1 - number_of_points_sad * epsilon_[1] / sq_dist_sad)
1600 if(estimated_delta_lim > 1) {
1601 estimated_delta_lim = 1;
1603 computeDistance(&(current_bidder_diagrams_saddle_[idx]),
1604 &(centroids_with_price_sad[count]),
1605 estimated_delta_lim);
1610 double estimated_delta_lim
1612 / sqrt(1 - number_of_points_max * epsilon_[2] / sq_dist_max)
1614 if(estimated_delta_lim > 1) {
1615 estimated_delta_lim = 1;
1617 computeDistance(&(current_bidder_diagrams_max_[idx]),
1618 &(centroids_with_price_max[count]),
1619 estimated_delta_lim);
1625 double total_cost = 0;
1626 double wasserstein_shift = 0;
1631 std::vector<std::vector<MatchingType>> all_matchings;
1632 std::vector<int> sizes;
1633 Timer const time_preprocess_bary;
1634 std::vector<BidderDiagram> diagrams_c_min;
1635 if(barycenter_inputs_reset_flag) {
1636 for(
int const idx : clustering_[c]) {
1637 diagrams_c_min.emplace_back(current_bidder_diagrams_min_[idx]);
1639 sizes.resize(diagrams_c_min.size());
1640 for(
size_t i = 0; i < diagrams_c_min.size(); i++) {
1641 sizes[i] = diagrams_c_min[i].size();
1643 barycenter_computer_min_[c].setNumberOfInputs(diagrams_c_min.size());
1644 barycenter_computer_min_[c].setCurrentBidders(diagrams_c_min);
1646 std::vector<GoodDiagram> barycenter_goods(clustering_[c].size());
1647 for(
size_t i_diagram = 0; i_diagram < clustering_[c].size();
1649 barycenter_goods[i_diagram]
1650 = centroids_with_price_min_[clustering_[c][i_diagram]];
1652 barycenter_computer_min_[c].setCurrentBarycenter(barycenter_goods);
1653 all_matchings.resize(diagrams_c_min.size());
1655 sizes.resize(barycenter_computer_min_[c].getCurrentBidders().size());
1657 i < barycenter_computer_min_[c].getCurrentBidders().size(); i++) {
1659 = barycenter_computer_min_[c].getCurrentBidders().at(i).size();
1661 diagrams_c_min.resize(
1662 barycenter_computer_min_[c].getCurrentBidders().size());
1663 all_matchings.resize(
1664 barycenter_computer_min_[c].getCurrentBidders().size());
1668 bool use_kdt =
false;
1669 if(!barycenter_computer_min_[c].getCurrentBarycenter()[0].empty()) {
1670 pair = barycenter_computer_min_[c].getKDTree();
1674 barycenter_computer_min_[c].runMatching(
1675 &total_cost, epsilon_[0], sizes, *pair.first, pair.second,
1676 &(min_diag_price->at(0)), &(min_price->at(0)), &(all_matchings),
1677 use_kdt, only_matchings);
1678 for(
size_t ii = 0; ii < all_matchings.size(); ii++) {
1679 all_matchings_per_type_and_cluster[c][0][ii].resize(
1680 all_matchings[ii].size());
1681 all_matchings_per_type_and_cluster[c][0][ii] = all_matchings[ii];
1683 for(
int ii = all_matchings.size(); ii < numberOfInputs_; ii++) {
1684 all_matchings_per_type_and_cluster[c][0][ii].resize(0);
1688 = barycenter_computer_min_[c].isPrecisionObjectiveMet(deltaLim_, 0);
1689 cost_min_ += total_cost;
1690 Timer const time_update;
1691 if(!only_matchings) {
1693 = barycenter_computer_min_[c].updateBarycenter(all_matchings);
1696 if(max_shift_c_min > max_shift_vector[0]) {
1697 max_shift_vector[0] = max_shift_c_min;
1702 diagrams_c_min = barycenter_computer_min_[c].getCurrentBidders();
1703 centroids_with_price_min
1704 = barycenter_computer_min_[c].getCurrentBarycenter();
1706 for(
int const idx : clustering_[c]) {
1707 current_bidder_diagrams_min_[idx] = diagrams_c_min[i];
1708 centroids_with_price_min_[idx] = centroids_with_price_min[i];
1712 GoodDiagram const old_centroid = centroids_min_[c];
1713 centroids_min_[c] = centroidWithZeroPrices(
1714 centroids_with_price_min_[clustering_[c][0]]);
1716 if(use_accelerated_) {
1718 += computeDistance(old_centroid, centroids_min_[c], 0.01);
1723 std::vector<std::vector<MatchingType>> all_matchings;
1725 std::vector<int> sizes;
1727 std::vector<BidderDiagram> diagrams_c_min;
1728 if(barycenter_inputs_reset_flag) {
1729 for(
int const idx : clustering_[c]) {
1730 diagrams_c_min.emplace_back(current_bidder_diagrams_saddle_[idx]);
1732 sizes.resize(diagrams_c_min.size());
1733 for(
size_t i = 0; i < diagrams_c_min.size(); i++) {
1734 sizes[i] = diagrams_c_min[i].size();
1736 barycenter_computer_sad_[c].setNumberOfInputs(diagrams_c_min.size());
1737 barycenter_computer_sad_[c].setCurrentBidders(diagrams_c_min);
1738 std::vector<GoodDiagram> barycenter_goods(clustering_[c].size());
1739 for(
size_t i_diagram = 0; i_diagram < clustering_[c].size();
1741 barycenter_goods[i_diagram]
1742 = centroids_with_price_saddle_[clustering_[c][i_diagram]];
1744 barycenter_computer_sad_[c].setCurrentBarycenter(barycenter_goods);
1745 all_matchings.resize(diagrams_c_min.size());
1747 sizes.resize(barycenter_computer_sad_[c].getCurrentBidders().size());
1749 i < barycenter_computer_sad_[c].getCurrentBidders().size(); i++) {
1751 = barycenter_computer_sad_[c].getCurrentBidders().at(i).size();
1753 all_matchings.resize(
1754 barycenter_computer_sad_[c].getCurrentBidders().size());
1755 diagrams_c_min.resize(
1756 barycenter_computer_sad_[c].getCurrentBidders().size());
1760 bool use_kdt =
false;
1761 if(!barycenter_computer_sad_[c].getCurrentBarycenter()[0].empty()) {
1762 pair = barycenter_computer_sad_[c].getKDTree();
1766 barycenter_computer_sad_[c].runMatching(
1767 &total_cost, epsilon_[1], sizes, *pair.first, pair.second,
1768 &(min_diag_price->at(1)), &(min_price->at(1)), &(all_matchings),
1769 use_kdt, only_matchings);
1770 for(
size_t ii = 0; ii < all_matchings.size(); ii++) {
1771 all_matchings_per_type_and_cluster[c][1][ii].resize(
1772 all_matchings[ii].size());
1773 all_matchings_per_type_and_cluster[c][1][ii] = all_matchings[ii];
1775 for(
int ii = all_matchings.size(); ii < numberOfInputs_; ii++) {
1776 all_matchings_per_type_and_cluster[c][1][ii].resize(0);
1780 = barycenter_computer_sad_[c].isPrecisionObjectiveMet(deltaLim_, 0);
1781 if(!only_matchings) {
1783 = barycenter_computer_sad_[c].updateBarycenter(all_matchings);
1786 cost_sad_ += total_cost;
1788 if(max_shift_c_sad > max_shift_vector[1]) {
1789 max_shift_vector[1] = max_shift_c_sad;
1794 diagrams_c_min = barycenter_computer_sad_[c].getCurrentBidders();
1795 centroids_with_price_sad
1796 = barycenter_computer_sad_[c].getCurrentBarycenter();
1798 for(
int const idx : clustering_[c]) {
1799 current_bidder_diagrams_saddle_[idx] = diagrams_c_min[i];
1800 centroids_with_price_saddle_[idx] = centroids_with_price_sad[i];
1803 GoodDiagram const old_centroid = centroids_saddle_[c];
1804 centroids_saddle_[c] = centroidWithZeroPrices(
1805 centroids_with_price_saddle_[clustering_[c][0]]);
1806 if(use_accelerated_)
1808 += computeDistance(old_centroid, centroids_saddle_[c], 0.01);
1812 std::vector<std::vector<MatchingType>> all_matchings;
1813 Timer const time_preprocess_bary;
1815 std::vector<int> sizes;
1816 std::vector<BidderDiagram> diagrams_c_min;
1817 if(barycenter_inputs_reset_flag) {
1818 for(
int const idx : clustering_[c]) {
1819 diagrams_c_min.emplace_back(current_bidder_diagrams_max_[idx]);
1821 sizes.resize(diagrams_c_min.size());
1822 for(
size_t i = 0; i < diagrams_c_min.size(); i++) {
1823 sizes[i] = diagrams_c_min[i].size();
1825 barycenter_computer_max_[c].setNumberOfInputs(diagrams_c_min.size());
1826 barycenter_computer_max_[c].setCurrentBidders(diagrams_c_min);
1827 std::vector<GoodDiagram> barycenter_goods(clustering_[c].size());
1828 for(
size_t i_diagram = 0; i_diagram < clustering_[c].size();
1830 barycenter_goods[i_diagram]
1831 = centroids_with_price_max_[clustering_[c][i_diagram]];
1833 barycenter_computer_max_[c].setCurrentBarycenter(barycenter_goods);
1834 all_matchings.resize(diagrams_c_min.size());
1836 sizes.resize(barycenter_computer_max_[c].getCurrentBidders().size());
1838 i < barycenter_computer_max_[c].getCurrentBidders().size(); i++) {
1840 = barycenter_computer_max_[c].getCurrentBidders().at(i).size();
1843 diagrams_c_min.resize(
1844 barycenter_computer_max_[c].getCurrentBidders().size());
1845 all_matchings.resize(
1846 barycenter_computer_max_[c].getCurrentBidders().size());
1850 bool use_kdt =
false;
1851 if(!barycenter_computer_max_[c].getCurrentBarycenter()[0].empty()) {
1852 pair = barycenter_computer_max_[c].getKDTree();
1856 barycenter_computer_max_[c].runMatching(
1857 &total_cost, epsilon_[2], sizes, *pair.first, pair.second,
1858 &(min_diag_price->at(2)), &(min_price->at(2)), &(all_matchings),
1859 use_kdt, only_matchings);
1860 for(
size_t ii = 0; ii < all_matchings.size(); ii++) {
1861 all_matchings_per_type_and_cluster[c][2][ii].resize(
1862 all_matchings[ii].size());
1863 all_matchings_per_type_and_cluster[c][2][ii] = all_matchings[ii];
1865 for(
int ii = all_matchings.size(); ii < numberOfInputs_; ii++) {
1866 all_matchings_per_type_and_cluster[c][2][ii].resize(0);
1869 = barycenter_computer_max_[c].isPrecisionObjectiveMet(deltaLim_, 0);
1871 cost_max_ += total_cost;
1872 Timer const time_update;
1873 if(!only_matchings) {
1875 = barycenter_computer_max_[c].updateBarycenter(all_matchings);
1877 if(max_shift_c_max > max_shift_vector[2]) {
1878 max_shift_vector[2] = max_shift_c_max;
1883 diagrams_c_min = barycenter_computer_max_[c].getCurrentBidders();
1884 centroids_with_price_max
1885 = barycenter_computer_max_[c].getCurrentBarycenter();
1887 for(
int const idx : clustering_[c]) {
1888 current_bidder_diagrams_max_[idx] = diagrams_c_min[i];
1889 centroids_with_price_max_[idx] = centroids_with_price_max[i];
1892 GoodDiagram const old_centroid = centroids_max_[c];
1893 centroids_max_[c] = centroidWithZeroPrices(
1894 centroids_with_price_max_[clustering_[c][0]]);
1895 if(use_accelerated_) {
1897 += computeDistance(old_centroid, centroids_max_[c], 0.01);
1901 cost_ = cost_min_ + cost_sad_ + cost_max_;
1902 if(wasserstein_shift > max_wasserstein_shift) {
1903 max_wasserstein_shift = wasserstein_shift;
1905 if(use_accelerated_) {
1906 for(
int i = 0; i < numberOfInputs_; ++i) {
1917 for(
int const idx : clustering_[c]) {
1933 precision_min_ = precision_min;
1934 precision_sad_ = precision_sad;
1935 precision_max_ = precision_max;
1936 precision_criterion_ = precision_min && precision_sad && precision_max;
1937 barycenter_inputs_reset_flag =
false;
1938 return max_shift_vector;
2008 std::vector<double> &previous_min_persistence,
2009 std::vector<double> &min_persistence,
2010 std::vector<std::vector<double>> &initial_diagonal_prices,
2011 std::vector<std::vector<double>> &initial_off_diagonal_prices,
2012 std::vector<int> &min_points_to_add,
2013 bool add_points_to_barycenter,
2014 bool first_enrichment) {
2016 std::vector<double> new_min_persistence = min_persistence;
2019 new_min_persistence[0] = previous_min_persistence[0];
2022 new_min_persistence[1] = previous_min_persistence[1];
2025 new_min_persistence[2] = previous_min_persistence[2];
2030 size_t max_diagram_size_min{};
2031 size_t max_diagram_size_sad{};
2032 size_t max_diagram_size_max{};
2034 for(
int i = 0; i < numberOfInputs_; i++) {
2035 if(current_bidder_diagrams_min_[i].size() > max_diagram_size_min) {
2036 max_diagram_size_min = current_bidder_diagrams_min_[i].size();
2041 for(
int i = 0; i < numberOfInputs_; i++) {
2042 if(current_bidder_diagrams_saddle_[i].size() > max_diagram_size_sad) {
2043 max_diagram_size_sad = current_bidder_diagrams_saddle_[i].size();
2048 for(
int i = 0; i < numberOfInputs_; i++) {
2049 if(current_bidder_diagrams_max_[i].size() > max_diagram_size_max) {
2050 max_diagram_size_max = current_bidder_diagrams_max_[i].size();
2054 int const max_points_to_add_min
2055 = std::max(min_points_to_add[0],
2056 min_points_to_add[0] + (
int)(max_diagram_size_min / 10));
2057 int const max_points_to_add_sad
2058 = std::max(min_points_to_add[1],
2059 min_points_to_add[1] + (
int)(max_diagram_size_sad / 10));
2060 int const max_points_to_add_max
2061 = std::max(min_points_to_add[2],
2062 min_points_to_add[2] + (
int)(max_diagram_size_max / 10));
2065 std::vector<std::vector<int>> candidates_to_be_added_min(numberOfInputs_);
2066 std::vector<std::vector<int>> candidates_to_be_added_sad(numberOfInputs_);
2067 std::vector<std::vector<int>> candidates_to_be_added_max(numberOfInputs_);
2068 std::vector<std::vector<int>> idx_min(numberOfInputs_);
2069 std::vector<std::vector<int>> idx_sad(numberOfInputs_);
2070 std::vector<std::vector<int>> idx_max(numberOfInputs_);
2073 for(
int i = 0; i < numberOfInputs_; i++) {
2074 std::vector<double> persistences;
2075 for(
size_t j = 0; j < bidder_diagrams_min_[i].size(); j++) {
2076 Bidder const b = bidder_diagrams_min_[i].at(j);
2078 if(persistence >= min_persistence[0]
2079 && persistence <= previous_min_persistence[0]) {
2080 candidates_to_be_added_min[i].emplace_back(j);
2081 idx_min[i].emplace_back(idx_min[i].size());
2082 persistences.emplace_back(persistence);
2086 idx_min[i].
begin(), idx_min[i].
end(), [&persistences](
int &a,
int &b) {
2087 return ((persistences[a] > persistences[b])
2088 || ((persistences[a] == persistences[b]) && (a > b)));
2090 int const size = candidates_to_be_added_min[i].size();
2091 if(size >= max_points_to_add_min) {
2092 double const last_persistence_added_min
2093 = persistences[idx_min[i][max_points_to_add_min - 1]];
2094 if(first_enrichment) {
2097 new_min_persistence[0] = last_persistence_added_min;
2099 if(last_persistence_added_min < new_min_persistence[0])
2100 new_min_persistence[0] = last_persistence_added_min;
2103 if(last_persistence_added_min > new_min_persistence[0]) {
2104 new_min_persistence[0] = last_persistence_added_min;
2112 for(
int i = 0; i < numberOfInputs_; i++) {
2113 std::vector<double> persistences;
2114 for(
size_t j = 0; j < bidder_diagrams_saddle_[i].size(); j++) {
2115 Bidder const b = bidder_diagrams_saddle_[i].at(j);
2117 if(persistence >= min_persistence[1]
2118 && persistence <= previous_min_persistence[1]) {
2119 candidates_to_be_added_sad[i].emplace_back(j);
2120 idx_sad[i].emplace_back(idx_sad[i].size());
2121 persistences.emplace_back(persistence);
2125 idx_sad[i].
begin(), idx_sad[i].
end(), [&persistences](
int &a,
int &b) {
2126 return ((persistences[a] > persistences[b])
2127 || ((persistences[a] == persistences[b]) && (a > b)));
2129 int const size = candidates_to_be_added_sad[i].size();
2130 if(size >= max_points_to_add_sad) {
2131 double const last_persistence_added_sad
2132 = persistences[idx_sad[i][max_points_to_add_sad - 1]];
2133 if(first_enrichment) {
2136 new_min_persistence[1] = last_persistence_added_sad;
2138 if(last_persistence_added_sad < new_min_persistence[1])
2139 new_min_persistence[1] = last_persistence_added_sad;
2142 if(last_persistence_added_sad > new_min_persistence[1]) {
2143 new_min_persistence[1] = last_persistence_added_sad;
2150 for(
int i = 0; i < numberOfInputs_; i++) {
2151 std::vector<double> persistences;
2152 for(
size_t j = 0; j < bidder_diagrams_max_[i].size(); j++) {
2153 Bidder const b = bidder_diagrams_max_[i].at(j);
2155 if(persistence >= min_persistence[2]
2156 && persistence <= previous_min_persistence[2]) {
2157 candidates_to_be_added_max[i].emplace_back(j);
2158 idx_max[i].emplace_back(idx_max[i].size());
2159 persistences.emplace_back(persistence);
2163 idx_max[i].
begin(), idx_max[i].
end(), [&persistences](
int &a,
int &b) {
2164 return ((persistences[a] > persistences[b])
2165 || ((persistences[a] == persistences[b]) && (a > b)));
2167 int const size = candidates_to_be_added_max[i].size();
2168 if(size >= max_points_to_add_max) {
2169 double const last_persistence_added_max
2170 = persistences[idx_max[i][max_points_to_add_max - 1]];
2171 if(first_enrichment) {
2174 new_min_persistence[2] = last_persistence_added_max;
2176 if(last_persistence_added_max < new_min_persistence[2])
2177 new_min_persistence[2] = last_persistence_added_max;
2180 if(last_persistence_added_max > new_min_persistence[2]) {
2181 new_min_persistence[2] = last_persistence_added_max;
2190 int counter_for_adding_points = 0;
2191 for(
int i = 0; i < numberOfInputs_; i++) {
2192 int const size = candidates_to_be_added_min[i].size();
2193 for(
int j = 0; j < std::min(max_points_to_add_min, size); j++) {
2194 Bidder b = bidder_diagrams_min_[i].at(
2195 candidates_to_be_added_min[i][idx_min[i][j]]);
2197 if(persistence >= new_min_persistence[0]) {
2198 b.
id_ = current_bidder_diagrams_min_[i].size();
2201 current_bidder_diagrams_min_[i].emplace_back(b);
2202 current_bidder_ids_min_[i]
2203 [candidates_to_be_added_min[i][idx_min[i][j]]]
2204 = current_bidder_diagrams_min_[i].size() - 1;
2206 if(use_accelerated_ && n_iterations_ > 0) {
2207 for(
int c = 0; c < k_; ++c) {
2212 - persistence / sqrt(2),
2221 Geometry::pow(u_[i], 1. / wasserstein_) + persistence / sqrt(2),
2225 int const to_be_added_to_barycenter
2226 = deterministic_ ? counter_for_adding_points % numberOfInputs_
2227 : rand() % numberOfInputs_;
2228 if(to_be_added_to_barycenter == 0 && add_points_to_barycenter) {
2229 for(
int k = 0; k < numberOfInputs_; k++) {
2230 if(inv_clustering_[i] == inv_clustering_[k]) {
2232 b.
x_, b.
y_,
false, centroids_with_price_min_[k].size());
2233 g.
setPrice(initial_off_diagonal_prices[0][k]);
2236 centroids_with_price_min_[k].emplace_back(g);
2240 b.
x_, b.
y_,
false, centroids_min_[inv_clustering_[i]].size());
2242 centroids_min_[inv_clustering_[i]].emplace_back(g);
2245 counter_for_adding_points++;
2250 int counter_for_adding_points = 0;
2251 for(
int i = 0; i < numberOfInputs_; i++) {
2252 int const size = candidates_to_be_added_sad[i].size();
2253 for(
int j = 0; j < std::min(max_points_to_add_sad, size); j++) {
2254 Bidder b = bidder_diagrams_saddle_[i].at(
2255 candidates_to_be_added_sad[i][idx_sad[i][j]]);
2257 if(persistence >= new_min_persistence[1]) {
2258 b.
id_ = current_bidder_diagrams_saddle_[i].size();
2261 current_bidder_diagrams_saddle_[i].emplace_back(b);
2262 current_bidder_ids_sad_[i]
2263 [candidates_to_be_added_sad[i][idx_sad[i][j]]]
2264 = current_bidder_diagrams_saddle_[i].size() - 1;
2266 if(use_accelerated_ && n_iterations_ > 0) {
2267 for(
int c = 0; c < k_; ++c) {
2272 - persistence / sqrt(2),
2281 Geometry::pow(u_[i], 1. / wasserstein_) + persistence / sqrt(2),
2285 int const to_be_added_to_barycenter
2286 = deterministic_ ? counter_for_adding_points % numberOfInputs_
2287 : rand() % numberOfInputs_;
2288 if(to_be_added_to_barycenter == 0 && add_points_to_barycenter) {
2289 for(
int k = 0; k < numberOfInputs_; k++) {
2290 if(inv_clustering_[i] == inv_clustering_[k]) {
2292 b.
x_, b.
y_,
false, centroids_with_price_saddle_[k].size());
2293 g.
setPrice(initial_off_diagonal_prices[1][k]);
2296 centroids_with_price_saddle_[k].emplace_back(g);
2301 counter_for_adding_points++;
2306 int counter_for_adding_points = 0;
2307 for(
int i = 0; i < numberOfInputs_; i++) {
2308 int const size = candidates_to_be_added_max[i].size();
2309 for(
int j = 0; j < std::min(max_points_to_add_max, size); j++) {
2310 Bidder b = bidder_diagrams_max_[i].at(
2311 candidates_to_be_added_max[i][idx_max[i][j]]);
2313 if(persistence >= new_min_persistence[2]) {
2314 b.
id_ = current_bidder_diagrams_max_[i].size();
2317 current_bidder_diagrams_max_[i].emplace_back(b);
2318 current_bidder_ids_max_[i]
2319 [candidates_to_be_added_max[i][idx_max[i][j]]]
2320 = current_bidder_diagrams_max_[i].size() - 1;
2322 if(use_accelerated_ && n_iterations_ > 0) {
2323 for(
int c = 0; c < k_; ++c) {
2328 - persistence / sqrt(2),
2337 Geometry::pow(u_[i], 1. / wasserstein_) + persistence / sqrt(2),
2341 int const to_be_added_to_barycenter
2342 = deterministic_ ? counter_for_adding_points % numberOfInputs_
2343 : rand() % numberOfInputs_;
2344 if(to_be_added_to_barycenter == 0 && add_points_to_barycenter) {
2345 for(
int k = 0; k < numberOfInputs_; k++) {
2346 if(inv_clustering_[i] == inv_clustering_[k]) {
2348 b.
x_, b.
y_,
false, centroids_with_price_max_[k].size());
2349 g.
setPrice(initial_off_diagonal_prices[2][k]);
2352 centroids_with_price_max_[k].emplace_back(g);
2356 b.
x_, b.
y_,
false, centroids_max_[inv_clustering_[i]].size());
2358 centroids_max_[inv_clustering_[i]].emplace_back(g);
2361 counter_for_adding_points++;
2366 return new_min_persistence;
2370 std::vector<double> & ) {
2373 barycenter_computer_min_.resize(k_);
2374 for(
int c = 0; c < k_; c++) {
2375 std::vector<BidderDiagram> diagrams_c;
2376 for(
int const idx : clustering_[c]) {
2377 diagrams_c.emplace_back(current_bidder_diagrams_min_[idx]);
2379 barycenter_computer_min_[c] = {};
2380 barycenter_computer_min_[c].setThreadNumber(threadNumber_);
2381 barycenter_computer_min_[c].setWasserstein(wasserstein_);
2382 barycenter_computer_min_[c].setDiagramType(0);
2383 barycenter_computer_min_[c].setUseProgressive(
false);
2384 barycenter_computer_min_[c].setDeterministic(
true);
2385 barycenter_computer_min_[c].setGeometricalFactor(geometrical_factor_);
2386 barycenter_computer_min_[c].setDebugLevel(debugLevel_);
2387 barycenter_computer_min_[c].setNumberOfInputs(diagrams_c.size());
2388 barycenter_computer_min_[c].setCurrentBidders(diagrams_c);
2389 barycenter_computer_min_[c].setNonMatchingWeight(nonMatchingWeight_);
2393 barycenter_computer_sad_.resize(k_);
2394 for(
int c = 0; c < k_; c++) {
2395 std::vector<BidderDiagram> diagrams_c;
2396 for(
int const idx : clustering_[c]) {
2397 diagrams_c.emplace_back(current_bidder_diagrams_saddle_[idx]);
2399 barycenter_computer_sad_[c] = {};
2400 barycenter_computer_sad_[c].setThreadNumber(threadNumber_);
2401 barycenter_computer_sad_[c].setWasserstein(wasserstein_);
2402 barycenter_computer_sad_[c].setDiagramType(1);
2403 barycenter_computer_sad_[c].setUseProgressive(
false);
2404 barycenter_computer_sad_[c].setDeterministic(
true);
2405 barycenter_computer_sad_[c].setGeometricalFactor(geometrical_factor_);
2406 barycenter_computer_sad_[c].setDebugLevel(debugLevel_);
2407 barycenter_computer_sad_[c].setNumberOfInputs(diagrams_c.size());
2408 barycenter_computer_sad_[c].setCurrentBidders(diagrams_c);
2409 barycenter_computer_sad_[c].setNonMatchingWeight(nonMatchingWeight_);
2411 std::vector<GoodDiagram> barycenter_goods(clustering_[c].size());
2412 for(
size_t i_diagram = 0; i_diagram < clustering_[c].size();
2414 barycenter_goods[i_diagram]
2415 = centroids_with_price_saddle_[clustering_[c][i_diagram]];
2417 barycenter_computer_sad_[c].setCurrentBarycenter(barycenter_goods);
2421 barycenter_computer_max_.resize(k_);
2422 for(
int c = 0; c < k_; c++) {
2423 std::vector<BidderDiagram> diagrams_c;
2424 for(
int const idx : clustering_[c]) {
2425 diagrams_c.emplace_back(current_bidder_diagrams_max_[idx]);
2427 barycenter_computer_max_[c] = {};
2428 barycenter_computer_max_[c].setDiagrams(inputDiagramsMax_);
2429 barycenter_computer_max_[c].setThreadNumber(threadNumber_);
2430 barycenter_computer_max_[c].setWasserstein(wasserstein_);
2431 barycenter_computer_max_[c].setDiagramType(2);
2432 barycenter_computer_max_[c].setUseProgressive(
false);
2433 barycenter_computer_max_[c].setDeterministic(
true);
2434 barycenter_computer_max_[c].setGeometricalFactor(geometrical_factor_);
2435 barycenter_computer_max_[c].setDebugLevel(debugLevel_);
2436 barycenter_computer_max_[c].setNumberOfInputs(diagrams_c.size());
2437 barycenter_computer_max_[c].setCurrentBidders(diagrams_c);
2438 barycenter_computer_max_[c].setNonMatchingWeight(nonMatchingWeight_);
2440 std::vector<GoodDiagram> barycenter_goods(clustering_[c].size());
2441 for(
size_t i_diagram = 0; i_diagram < clustering_[c].size();
2443 barycenter_goods[i_diagram]
2444 = centroids_with_price_max_[clustering_[c][i_diagram]];
2446 barycenter_computer_max_[c].setCurrentBarycenter(barycenter_goods);
2579 std::vector<std::vector<MatchingType>> &matchings,
2580 std::vector<std::vector<int>> &bidders_ids,
2581 std::vector<BidderDiagram> ¤t_bidder_diagrams,
2582 std::vector<BidderDiagram> &bidder_diagrams,
2585 auto &matchings0 = matchings[0];
2586 auto &diagram0 = bidder_diagrams[0];
2587 auto ¤t_diagram0 = current_bidder_diagrams[0];
2588 auto &ids0 = bidders_ids[0];
2590 auto &matchings1 = matchings[1];
2591 auto &diagram1 = bidder_diagrams[1];
2592 auto ¤t_diagram1 = current_bidder_diagrams[1];
2593 auto &ids1 = bidders_ids[1];
2595 std::vector<int> new_to_old_id(current_diagram1.size());
2597 for(
size_t j = 0; j < ids1.size(); j++) {
2598 int const new_id = ids1[j];
2600 new_to_old_id[new_id] = j;
2604 std::vector<MatchingType> matching_to_add(0);
2605 std::vector<MatchingType> matching_to_add2(0);
2607 for(
size_t i = 0; i < matchings1.size(); i++) {
2609 int const bidderId = std::get<0>(t);
2610 int const goodId = std::get<1>(t);
2613 Bidder const b = diagram1.at(new_to_old_id[bidderId]);
2614 double const bx = b.
x_;
2615 double const by = b.
y_;
2617 Good const g = barycenter.at(goodId);
2618 double const gx = g.
x_;
2619 double const gy = g.
y_;
2620 barycenter.at(goodId).x_ = (bx + gx) / 2;
2621 barycenter.at(goodId).y_ = (by + gy) / 2;
2624 std::get<2>(t) /= 4;
2627 double gx = (bx + by) / 2;
2628 double gy = (bx + by) / 2;
2631 double const cost = nonMatchingWeight_
2635 = std::make_tuple(bidderId, barycenter.size(), cost);
2636 MatchingType const t3 = std::make_tuple(-1, barycenter.size(), cost);
2637 Good const g =
Good(gx, gy,
false, barycenter.size());
2639 barycenter.emplace_back(g);
2640 matching_to_add.emplace_back(t2);
2641 matching_to_add2.emplace_back(t3);
2645 Good const g = barycenter.at(goodId);
2646 double const gx = (g.
x_ + g.
y_) / 2;
2647 double const gy = (g.
x_ + g.
y_) / 2;
2648 barycenter.at(goodId).
x_ = (gx + g.
x_) / 2;
2649 barycenter.at(goodId).y_ = (gy + g.
y_) / 2;
2650 std::get<2>(t) /= 4;
2654 for(
size_t j = 0; j < matching_to_add.size(); j++) {
2655 matchings1.emplace_back(matching_to_add[j]);
2657 for(
size_t j = 0; j < matching_to_add2.size(); j++) {
2658 matchings0.emplace_back(matching_to_add2[j]);
2664 std::vector<int> new_to_old_id2(current_diagram0.size());
2666 for(
size_t j = 0; j < ids0.size(); j++) {
2667 int const new_id = ids0[j];
2669 new_to_old_id2[new_id] = j;
2673 for(
size_t i = 0; i < matchings0.size(); i++) {
2675 int const bidderId = std::get<0>(t);
2676 int const goodId = std::get<1>(t);
2678 if(bidderId >= 0 and goodId >= 0) {
2679 Bidder const b = diagram0.at(new_to_old_id2[bidderId]);
2680 double const bx = b.
x_;
2681 double const by = b.
y_;
2682 Good const g = barycenter.at(goodId);
2683 double const gx = g.
x_;
2684 double const gy = g.
y_;
2687 std::get<2>(t) = cost;