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]),
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) {
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]) {
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) {
455 this->
printMsg(
"Found a abnormally high persistence in min diagram",
470 this->
printMsg(
"Found a abnormally high persistence in sad diagram",
477 for(
size_t i = addedFirstPairMax; i <
centroids_max_[c].size(); ++i) {
492 this->
printMsg(
"Found a abnormally high persistence in min diagram",
509 std::vector<std::vector<std::vector<std::vector<MatchingType>>>>
510 &previous_matchings) {
511 for(
int c = 0; c <
k_; c++) {
512 for(
size_t i = 0; i <
clustering_[c].size(); i++) {
516 std::vector<int> new_to_old_id(
521 new_to_old_id[new_id] = j;
525 std::vector<MatchingType> matchings_diagram_i;
526 for(
size_t j = 0; j < previous_matchings[c][0][i].size(); j++) {
528 int const new_id = std::get<0>(m);
529 if(new_id >= 0 && std::get<1>(m) >= 0) {
530 std::get<0>(m) = new_to_old_id[new_id];
531 matchings_diagram_i.emplace_back(m);
532 }
else if(std::get<1>(m)
535 matchings_diagram_i.emplace_back(m);
538 previous_matchings[c][0][i].resize(matchings_diagram_i.size());
539 previous_matchings[c][0][i] = matchings_diagram_i;
543 std::vector<int> new_to_old_id(
548 new_to_old_id[new_id] = j;
553 std::vector<MatchingType> matchings_diagram_i;
554 for(
size_t j = 0; j < previous_matchings[c][1][i].size(); j++) {
556 int const new_id = std::get<0>(m);
557 if(new_id >= 0 && std::get<1>(m) >= 0) {
558 int const old_id = new_to_old_id[new_id];
560 std::get<0>(m) = old_id;
561 matchings_diagram_i.emplace_back(m);
565 std::get<0>(m) = old_id;
566 matchings_diagram_i.emplace_back(m);
569 }
else if(std::get<1>(m)
572 matchings_diagram_i.emplace_back(m);
575 previous_matchings[c][1][i].resize(matchings_diagram_i.size());
576 previous_matchings[c][1][i] = matchings_diagram_i;
580 std::vector<int> new_to_old_id(
585 new_to_old_id[new_id] = j;
590 std::vector<MatchingType> matchings_diagram_i;
591 for(
size_t j = 0; j < previous_matchings[c][2][i].size(); j++) {
593 int const new_id = std::get<0>(m);
594 if(new_id >= 0 && std::get<1>(m) >= 0) {
595 int const old_id = new_to_old_id[new_id];
597 std::get<0>(m) = old_id;
598 matchings_diagram_i.emplace_back(m);
602 std::get<0>(m) = old_id;
603 matchings_diagram_i.emplace_back(m);
606 }
else if(std::get<1>(m)
609 matchings_diagram_i.emplace_back(m);
612 previous_matchings[c][2][i].resize(matchings_diagram_i.size());
613 previous_matchings[c][2][i] = matchings_diagram_i;
948 std::vector<int> indexes_clusters;
950 indexes_clusters.emplace_back(random_idx);
968 const auto square = [](
const double a) {
return a * a; };
970 while((
int)indexes_clusters.size() <
k_) {
975 double maximal_distance = 0;
976 int candidate_centroid = 0;
980 min_distance_to_centroid[i] = std::numeric_limits<double>::max();
981 if(std::find(indexes_clusters.begin(), indexes_clusters.end(), i)
982 != indexes_clusters.end()) {
984 min_distance_to_centroid[i] = 0;
987 for(
size_t j = 0; j < indexes_clusters.size(); ++j) {
1008 if(distance < min_distance_to_centroid[i]) {
1009 min_distance_to_centroid[i] = distance;
1013 probabilities[i] = square(min_distance_to_centroid[i]);
1017 if(
deterministic_ && min_distance_to_centroid[i] > maximal_distance) {
1018 maximal_distance = min_distance_to_centroid[i];
1019 candidate_centroid = i;
1023 std::random_device rd;
1024 std::mt19937 gen(rd());
1025 std::discrete_distribution<int> distribution(
1026 probabilities.begin(), probabilities.end());
1029 candidate_centroid = distribution(gen);
1032 indexes_clusters.emplace_back(candidate_centroid);
1482 std::vector<std::vector<double>> *min_price,
1483 std::vector<std::vector<double>> *min_diag_price,
1484 std::vector<std::vector<std::vector<std::vector<MatchingType>>>>
1485 &all_matchings_per_type_and_cluster,
1486 int only_matchings) {
1488 std::vector<double> max_shift_vector(3);
1489 max_shift_vector[0] = 0;
1490 max_shift_vector[1] = 0;
1491 max_shift_vector[2] = 0;
1492 double max_shift_c_min = 0;
1493 double max_shift_c_sad = 0;
1494 double max_shift_c_max = 0;
1495 double max_wasserstein_shift = 0;
1496 bool precision_min =
true;
1497 bool precision_sad =
true;
1498 bool precision_max =
true;
1513 for(
int c = 0; c <
k_; ++c) {
1515 std::vector<GoodDiagram> centroids_with_price_min,
1516 centroids_with_price_sad, centroids_with_price_max;
1521 std::vector<int>::iterator
const i = std::find(
1529 centroids_with_price_min.emplace_back(
1533 centroids_with_price_sad.emplace_back(
1537 centroids_with_price_max.emplace_back(
1541 int number_of_points_min = 0;
1542 int number_of_points_max = 0;
1543 int number_of_points_sad = 0;
1548 centroids_with_price_min.emplace_back(
1556 centroids_with_price_sad.emplace_back(
1560 number_of_points_sad
1565 centroids_with_price_max.emplace_back(
1584 double estimated_delta_lim
1586 / sqrt(1 - number_of_points_min *
epsilon_[0] / sq_dist_min)
1588 if(estimated_delta_lim > 1) {
1589 estimated_delta_lim = 1;
1592 &(centroids_with_price_min[count]),
1593 estimated_delta_lim);
1598 double estimated_delta_lim
1600 / sqrt(1 - number_of_points_sad *
epsilon_[1] / sq_dist_sad)
1602 if(estimated_delta_lim > 1) {
1603 estimated_delta_lim = 1;
1606 &(centroids_with_price_sad[count]),
1607 estimated_delta_lim);
1612 double estimated_delta_lim
1614 / sqrt(1 - number_of_points_max *
epsilon_[2] / sq_dist_max)
1616 if(estimated_delta_lim > 1) {
1617 estimated_delta_lim = 1;
1620 &(centroids_with_price_max[count]),
1621 estimated_delta_lim);
1627 double total_cost = 0;
1628 double wasserstein_shift = 0;
1633 std::vector<std::vector<MatchingType>> all_matchings;
1634 std::vector<int> sizes;
1635 Timer const time_preprocess_bary;
1636 std::vector<BidderDiagram> diagrams_c_min;
1641 sizes.resize(diagrams_c_min.size());
1642 for(
size_t i = 0; i < diagrams_c_min.size(); i++) {
1643 sizes[i] = diagrams_c_min[i].size();
1648 std::vector<GoodDiagram> barycenter_goods(
clustering_[c].size());
1649 for(
size_t i_diagram = 0; i_diagram <
clustering_[c].size();
1651 barycenter_goods[i_diagram]
1655 all_matchings.resize(diagrams_c_min.size());
1663 diagrams_c_min.resize(
1665 all_matchings.resize(
1670 bool use_kdt =
false;
1677 &total_cost,
epsilon_[0], sizes, *pair.first, pair.second,
1678 &(min_diag_price->at(0)), &(min_price->at(0)), &(all_matchings),
1679 use_kdt, only_matchings);
1680 for(
size_t ii = 0; ii < all_matchings.size(); ii++) {
1681 all_matchings_per_type_and_cluster[c][0][ii].resize(
1682 all_matchings[ii].size());
1683 all_matchings_per_type_and_cluster[c][0][ii] = all_matchings[ii];
1686 all_matchings_per_type_and_cluster[c][0][ii].resize(0);
1692 Timer const time_update;
1693 if(!only_matchings) {
1698 if(max_shift_c_min > max_shift_vector[0]) {
1699 max_shift_vector[0] = max_shift_c_min;
1705 centroids_with_price_min
1725 std::vector<std::vector<MatchingType>> all_matchings;
1727 std::vector<int> sizes;
1729 std::vector<BidderDiagram> diagrams_c_min;
1734 sizes.resize(diagrams_c_min.size());
1735 for(
size_t i = 0; i < diagrams_c_min.size(); i++) {
1736 sizes[i] = diagrams_c_min[i].size();
1740 std::vector<GoodDiagram> barycenter_goods(
clustering_[c].size());
1741 for(
size_t i_diagram = 0; i_diagram <
clustering_[c].size();
1743 barycenter_goods[i_diagram]
1747 all_matchings.resize(diagrams_c_min.size());
1755 all_matchings.resize(
1757 diagrams_c_min.resize(
1762 bool use_kdt =
false;
1769 &total_cost,
epsilon_[1], sizes, *pair.first, pair.second,
1770 &(min_diag_price->at(1)), &(min_price->at(1)), &(all_matchings),
1771 use_kdt, only_matchings);
1772 for(
size_t ii = 0; ii < all_matchings.size(); ii++) {
1773 all_matchings_per_type_and_cluster[c][1][ii].resize(
1774 all_matchings[ii].size());
1775 all_matchings_per_type_and_cluster[c][1][ii] = all_matchings[ii];
1778 all_matchings_per_type_and_cluster[c][1][ii].resize(0);
1783 if(!only_matchings) {
1790 if(max_shift_c_sad > max_shift_vector[1]) {
1791 max_shift_vector[1] = max_shift_c_sad;
1797 centroids_with_price_sad
1814 std::vector<std::vector<MatchingType>> all_matchings;
1815 Timer const time_preprocess_bary;
1817 std::vector<int> sizes;
1818 std::vector<BidderDiagram> diagrams_c_min;
1823 sizes.resize(diagrams_c_min.size());
1824 for(
size_t i = 0; i < diagrams_c_min.size(); i++) {
1825 sizes[i] = diagrams_c_min[i].size();
1829 std::vector<GoodDiagram> barycenter_goods(
clustering_[c].size());
1830 for(
size_t i_diagram = 0; i_diagram <
clustering_[c].size();
1832 barycenter_goods[i_diagram]
1836 all_matchings.resize(diagrams_c_min.size());
1845 diagrams_c_min.resize(
1847 all_matchings.resize(
1852 bool use_kdt =
false;
1859 &total_cost,
epsilon_[2], sizes, *pair.first, pair.second,
1860 &(min_diag_price->at(2)), &(min_price->at(2)), &(all_matchings),
1861 use_kdt, only_matchings);
1862 for(
size_t ii = 0; ii < all_matchings.size(); ii++) {
1863 all_matchings_per_type_and_cluster[c][2][ii].resize(
1864 all_matchings[ii].size());
1865 all_matchings_per_type_and_cluster[c][2][ii] = all_matchings[ii];
1868 all_matchings_per_type_and_cluster[c][2][ii].resize(0);
1874 Timer const time_update;
1875 if(!only_matchings) {
1879 if(max_shift_c_max > max_shift_vector[2]) {
1880 max_shift_vector[2] = max_shift_c_max;
1886 centroids_with_price_max
1904 if(wasserstein_shift > max_wasserstein_shift) {
1905 max_wasserstein_shift = wasserstein_shift;
1940 return max_shift_vector;
2010 std::vector<double> &previous_min_persistence,
2011 std::vector<double> &min_persistence,
2012 std::vector<std::vector<double>> &initial_diagonal_prices,
2013 std::vector<std::vector<double>> &initial_off_diagonal_prices,
2014 std::vector<int> &min_points_to_add,
2015 bool add_points_to_barycenter,
2016 bool first_enrichment) {
2018 std::vector<double> new_min_persistence
2019 = first_enrichment ? previous_min_persistence : min_persistence;
2022 new_min_persistence[0] = previous_min_persistence[0];
2025 new_min_persistence[1] = previous_min_persistence[1];
2028 new_min_persistence[2] = previous_min_persistence[2];
2033 size_t max_diagram_size_min{};
2034 size_t max_diagram_size_sad{};
2035 size_t max_diagram_size_max{};
2057 int const max_points_to_add_min
2058 = std::max(min_points_to_add[0],
2059 min_points_to_add[0] + (
int)(max_diagram_size_min / 10));
2060 int const max_points_to_add_sad
2061 = std::max(min_points_to_add[1],
2062 min_points_to_add[1] + (
int)(max_diagram_size_sad / 10));
2063 int const max_points_to_add_max
2064 = std::max(min_points_to_add[2],
2065 min_points_to_add[2] + (
int)(max_diagram_size_max / 10));
2068 std::vector<std::vector<int>> candidates_to_be_added_min(
numberOfInputs_);
2069 std::vector<std::vector<int>> candidates_to_be_added_sad(
numberOfInputs_);
2070 std::vector<std::vector<int>> candidates_to_be_added_max(
numberOfInputs_);
2077 std::vector<double> persistences;
2079 double last_added_persistence = number_of_added_pairs
2081 .at(number_of_added_pairs - 1)
2083 : previous_min_persistence[0];
2086 const auto persistence = b.getPersistence();
2087 if(persistence >= min_persistence[0]
2088 && persistence < last_added_persistence) {
2089 candidates_to_be_added_min[i].emplace_back(j);
2090 idx_min[i].emplace_back(idx_min[i].size());
2091 persistences.emplace_back(persistence);
2095 idx_min[i].
begin(), idx_min[i].
end(), [&persistences](
int &a,
int &b) {
2096 return ((persistences[a] > persistences[b])
2097 || ((persistences[a] == persistences[b]) && (a > b)));
2099 int size = candidates_to_be_added_min[i].size();
2101 double last_persistence_added_min
2102 = persistences[idx_min[i][std::min(size, max_points_to_add_min) - 1]];
2103 if(first_enrichment) {
2106 new_min_persistence[0] = last_persistence_added_min;
2108 if(last_persistence_added_min > new_min_persistence[0])
2109 new_min_persistence[0] = last_persistence_added_min;
2112 if(last_persistence_added_min > new_min_persistence[0]) {
2113 new_min_persistence[0] = last_persistence_added_min;
2122 std::vector<double> persistences;
2124 double last_added_persistence = number_of_added_pairs
2126 .at(number_of_added_pairs - 1)
2128 : previous_min_persistence[1];
2131 const auto persistence = b.getPersistence();
2132 if(persistence >= min_persistence[1]
2133 && persistence < last_added_persistence) {
2134 candidates_to_be_added_sad[i].emplace_back(j);
2135 idx_sad[i].emplace_back(idx_sad[i].size());
2136 persistences.emplace_back(persistence);
2140 idx_sad[i].
begin(), idx_sad[i].
end(), [&persistences](
int &a,
int &b) {
2141 return ((persistences[a] > persistences[b])
2142 || ((persistences[a] == persistences[b]) && (a > b)));
2144 int size = candidates_to_be_added_sad[i].size();
2146 double last_persistence_added_sad
2147 = persistences[idx_sad[i][std::min(size, max_points_to_add_sad) - 1]];
2148 if(first_enrichment) {
2151 new_min_persistence[1] = last_persistence_added_sad;
2153 if(last_persistence_added_sad > new_min_persistence[1])
2154 new_min_persistence[1] = last_persistence_added_sad;
2157 if(last_persistence_added_sad > new_min_persistence[1]) {
2158 new_min_persistence[1] = last_persistence_added_sad;
2166 std::vector<double> persistences;
2168 double last_added_persistence = number_of_added_pairs
2170 .at(number_of_added_pairs - 1)
2172 : previous_min_persistence[2];
2175 const auto persistence = b.getPersistence();
2177 if(persistence >= min_persistence[2]
2178 && persistence < last_added_persistence) {
2179 candidates_to_be_added_max[i].emplace_back(j);
2180 idx_max[i].emplace_back(idx_max[i].size());
2181 persistences.emplace_back(persistence);
2185 idx_max[i].
begin(), idx_max[i].
end(), [&persistences](
int &a,
int &b) {
2186 return ((persistences[a] > persistences[b])
2187 || ((persistences[a] == persistences[b]) && (a > b)));
2189 int size = candidates_to_be_added_max[i].size();
2191 double last_persistence_added_max
2192 = persistences[idx_max[i][std::min(size, max_points_to_add_max) - 1]];
2193 if(first_enrichment) {
2196 new_min_persistence[2] = last_persistence_added_max;
2198 if(last_persistence_added_max > new_min_persistence[2])
2199 new_min_persistence[2] = last_persistence_added_max;
2202 if(last_persistence_added_max > new_min_persistence[2]) {
2203 new_min_persistence[2] = last_persistence_added_max;
2212 int counter_for_adding_points = 0;
2214 int const size = candidates_to_be_added_min[i].size();
2215 for(
int j = 0; j < std::min(max_points_to_add_min, size); j++) {
2217 candidates_to_be_added_min[i][idx_min[i][j]]);
2219 if(persistence >= new_min_persistence[0] or first_enrichment) {
2225 [candidates_to_be_added_min[i][idx_min[i][j]]]
2229 for(
int c = 0; c <
k_; ++c) {
2234 - persistence / sqrt(2),
2247 int const to_be_added_to_barycenter
2250 if(to_be_added_to_barycenter == 0 && add_points_to_barycenter) {
2255 g.
setPrice(initial_off_diagonal_prices[0][k]);
2267 counter_for_adding_points++;
2272 int counter_for_adding_points = 0;
2274 int const size = candidates_to_be_added_sad[i].size();
2275 for(
int j = 0; j < std::min(max_points_to_add_sad, size); j++) {
2277 candidates_to_be_added_sad[i][idx_sad[i][j]]);
2279 if(persistence >= new_min_persistence[1] or first_enrichment) {
2285 [candidates_to_be_added_sad[i][idx_sad[i][j]]]
2289 for(
int c = 0; c <
k_; ++c) {
2294 - persistence / sqrt(2),
2307 int const to_be_added_to_barycenter
2310 if(to_be_added_to_barycenter == 0 && add_points_to_barycenter) {
2315 g.
setPrice(initial_off_diagonal_prices[1][k]);
2323 counter_for_adding_points++;
2328 int counter_for_adding_points = 0;
2330 int const size = candidates_to_be_added_max[i].size();
2331 for(
int j = 0; j < std::min(max_points_to_add_max, size); j++) {
2333 candidates_to_be_added_max[i][idx_max[i][j]]);
2335 if(persistence >= new_min_persistence[2] or first_enrichment) {
2341 [candidates_to_be_added_max[i][idx_max[i][j]]]
2345 for(
int c = 0; c <
k_; ++c) {
2350 - persistence / sqrt(2),
2363 int const to_be_added_to_barycenter
2366 if(to_be_added_to_barycenter == 0 && add_points_to_barycenter) {
2371 g.
setPrice(initial_off_diagonal_prices[2][k]);
2383 counter_for_adding_points++;
2388 return new_min_persistence;
2629 std::vector<std::vector<MatchingType>> &matchings,
2630 std::vector<std::vector<int>> &bidders_ids,
2631 std::vector<BidderDiagram> ¤t_bidder_diagrams,
2632 std::vector<BidderDiagram> &bidder_diagrams,
2635 auto &matchings0 = matchings[0];
2636 auto &diagram0 = bidder_diagrams[0];
2637 auto ¤t_diagram0 = current_bidder_diagrams[0];
2638 auto &ids0 = bidders_ids[0];
2640 auto &matchings1 = matchings[1];
2641 auto &diagram1 = bidder_diagrams[1];
2642 auto ¤t_diagram1 = current_bidder_diagrams[1];
2643 auto &ids1 = bidders_ids[1];
2645 std::vector<int> new_to_old_id(current_diagram1.size());
2647 for(
size_t j = 0; j < ids1.size(); j++) {
2648 int const new_id = ids1[j];
2650 new_to_old_id[new_id] = j;
2654 std::vector<MatchingType> matching_to_add(0);
2655 std::vector<MatchingType> matching_to_add2(0);
2657 for(
size_t i = 0; i < matchings1.size(); i++) {
2659 int const bidderId = std::get<0>(t);
2660 int const goodId = std::get<1>(t);
2663 Bidder const b = diagram1.at(new_to_old_id[bidderId]);
2664 double const bx = b.
x_;
2665 double const by = b.
y_;
2667 Good const g = barycenter.at(goodId);
2668 double const gx = g.
x_;
2669 double const gy = g.
y_;
2670 barycenter.at(goodId).x_ = (bx + gx) / 2;
2671 barycenter.at(goodId).y_ = (by + gy) / 2;
2674 std::get<2>(t) /= 4;
2677 double gx = (bx + by) / 2;
2678 double gy = (bx + by) / 2;
2685 = std::make_tuple(bidderId, barycenter.size(), cost);
2686 MatchingType const t3 = std::make_tuple(-1, barycenter.size(), cost);
2687 Good const g =
Good(gx, gy,
false, barycenter.size());
2689 barycenter.emplace_back(g);
2690 matching_to_add.emplace_back(t2);
2691 matching_to_add2.emplace_back(t3);
2695 Good const g = barycenter.at(goodId);
2696 double const gx = (g.
x_ + g.
y_) / 2;
2697 double const gy = (g.
x_ + g.
y_) / 2;
2698 barycenter.at(goodId).
x_ = (gx + g.
x_) / 2;
2699 barycenter.at(goodId).y_ = (gy + g.
y_) / 2;
2700 std::get<2>(t) /= 4;
2704 for(
size_t j = 0; j < matching_to_add.size(); j++) {
2705 matchings1.emplace_back(matching_to_add[j]);
2707 for(
size_t j = 0; j < matching_to_add2.size(); j++) {
2708 matchings0.emplace_back(matching_to_add2[j]);
2714 std::vector<int> new_to_old_id2(current_diagram0.size());
2716 for(
size_t j = 0; j < ids0.size(); j++) {
2717 int const new_id = ids0[j];
2719 new_to_old_id2[new_id] = j;
2723 for(
size_t i = 0; i < matchings0.size(); i++) {
2725 int const bidderId = std::get<0>(t);
2726 int const goodId = std::get<1>(t);
2728 if(bidderId >= 0 and goodId >= 0) {
2729 Bidder const b = diagram0.at(new_to_old_id2[bidderId]);
2730 double const bx = b.
x_;
2731 double const by = b.
y_;
2732 Good const g = barycenter.at(goodId);
2733 double const gx = g.
x_;
2734 double const gy = g.
y_;
2737 std::get<2>(t) = cost;