9 epsilon = 1e-6 * max_price;
44 if(idx_reassigned >= 0) {
54 for(
size_t i = 0; i <
goods_.size(); ++i) {
57 if(price > max_price) {
65 if(price > max_price) {
74 std::vector<MatchingType> &matchings,
bool get_diagonal_matches) {
75 double wassersteinDistance = 0;
76 for(
size_t i = 0; i <
bidders_.size(); i++) {
86 MatchingType const t = std::make_tuple(i, good_id, cost);
87 matchings.emplace_back(t);
90 this->
printWrn(
"both the bidder and the good are diagonal points");
93 if(get_diagonal_matches) {
94 MatchingType const t = std::make_tuple(i, good_id, cost);
95 matchings.emplace_back(t);
98 wassersteinDistance += cost;
104 if(get_diagonal_matches) {
106 matchings.emplace_back(t);
108 wassersteinDistance += cost;
111 return wassersteinDistance;
116 for(
unsigned int i = 0; i <
bidders_.size(); ++i) {
121 double bestCost = std::numeric_limits<double>::max();
122 std::vector<KDT *> neighbours;
123 std::vector<double> costs;
125 std::array<double, 5> coordinates;
127 kdt_.getKClosest(1, coordinates, neighbours, costs, kdt_index);
128 int const bestIndex = neighbours[0]->id_;
132 for(
unsigned int j = 0; j <
goods_.size(); ++j) {
133 double const cost =
bidders_[i].cost(
143 g.projectOnDiagonal();
144 double const cost =
bidders_[i].cost(
156 const int kdt_index) {
169 double const wassersteinDistance
171 return wassersteinDistance;
176 const int wasserstein,
177 const double geometricalFactor,
178 const double nonMatchingWeight)
const {
183 return nonMatchingWeight
187 + (1 - geometricalFactor)
190 return nonMatchingWeight
193 + (1 - geometricalFactor)
196 return geometricalFactor
199 + (1 - geometricalFactor)
213 double geometricalFactor,
214 double nonMatchingWeight) {
215 double best_val = std::numeric_limits<double>::lowest();
216 double second_val = std::numeric_limits<double>::lowest();
218 for(
size_t i = 0; i < goods->size(); i++) {
219 Good &g = (*goods)[i];
221 = -this->
cost(g, wasserstein, geometricalFactor, nonMatchingWeight);
224 second_val = best_val;
227 }
else if(val > second_val) {
234 = -this->
cost(g, wasserstein, geometricalFactor, nonMatchingWeight);
237 second_val = best_val;
240 }
else if(val > second_val) {
244 if(second_val == std::numeric_limits<double>::lowest()) {
246 second_val = best_val;
248 if(best_good ==
nullptr) {
251 double const old_price = best_good->getPrice();
252 double new_price = old_price + best_val - second_val + epsilon;
253 if(new_price > std::numeric_limits<double>::max() / 2) {
254 new_price = old_price + epsilon;
262 int const idx_reassigned = best_good->getOwner();
263 best_good->assign(this->position_in_auction_, new_price);
264 return idx_reassigned;
272 double geometricalFactor,
273 double nonMatchingWeight,
274 std::priority_queue<std::pair<int, double>,
275 std::vector<std::pair<int, double>>,
283 bool updated_top_pair
286 bool const non_empty_goods = goods->size() > 0;
287 std::pair<int, double> best_pair;
288 if(non_empty_goods) {
289 while(!updated_top_pair) {
290 std::pair<int, double> top_pair = diagonal_queue.top();
291 diagonal_queue.pop();
293 double const queue_weight = top_pair.second;
294 const auto &good = (*goods)[top_pair.first];
295 if(good.getPrice() > queue_weight) {
297 std::get<1>(top_pair) = good.getPrice();
298 diagonal_queue.push(top_pair);
300 updated_top_pair =
true;
301 best_pair = top_pair;
306 std::pair<int, double> second_pair;
307 if(non_empty_goods && diagonal_queue.size() > 0) {
308 bool updated_second_pair =
false;
309 while(!updated_second_pair) {
310 second_pair = diagonal_queue.top();
311 double const queue_weight = second_pair.second;
312 const auto &good = (*goods)[second_pair.first];
313 if(good.getPrice() != queue_weight) {
315 diagonal_queue.pop();
316 std::get<1>(second_pair) = good.getPrice();
317 diagonal_queue.push(second_pair);
319 updated_second_pair =
true;
326 double second_val = 0;
327 if(non_empty_goods) {
328 best_val = -best_pair.second;
329 second_val = diagonal_queue.size() > 0 ? -second_pair.second : best_val;
330 best_good = &(*goods)[best_pair.first];
334 bool is_twin =
false;
337 = -this->
cost(g, wasserstein, geometricalFactor, nonMatchingWeight);
339 if(non_empty_goods) {
341 second_val = best_val;
345 }
else if(val > second_val || diagonal_queue.empty()) {
352 second_val = best_val;
355 if(second_val == std::numeric_limits<double>::lowest()) {
357 second_val = best_val;
359 double const old_price = best_good->getPrice();
360 double new_price = old_price + best_val - second_val + epsilon;
361 if(new_price > std::numeric_limits<double>::max() / 2) {
362 new_price = old_price + epsilon;
371 int const idx_reassigned = best_good->getOwner();
372 best_good->assign(this->position_in_auction_, new_price);
374 std::get<1>(best_pair) = new_price;
376 if(non_empty_goods) {
377 diagonal_queue.push(best_pair);
379 return idx_reassigned;
387 double geometricalFactor,
388 double nonMatchingWeight,
389 std::vector<KDT *> &correspondence_kdt_map,
390 std::priority_queue<std::pair<int, double>,
391 std::vector<std::pair<int, double>>,
393 const int kdt_index) {
401 bool updated_top_pair
404 bool const non_empty_goods = goods->size() > 0;
405 std::pair<int, double> best_pair;
406 if(non_empty_goods) {
407 while(!updated_top_pair) {
408 std::pair<int, double> top_pair = diagonal_queue.top();
409 double const queue_weight = top_pair.second;
410 const auto &good = (*goods)[top_pair.first];
412 diagonal_queue.pop();
413 if(good.getPrice() > queue_weight) {
415 std::get<1>(top_pair) = good.getPrice();
416 diagonal_queue.push(top_pair);
418 updated_top_pair =
true;
419 best_pair = top_pair;
423 std::pair<int, double> second_pair;
424 if(non_empty_goods && diagonal_queue.size() > 0) {
425 bool updated_second_pair =
false;
426 while(!updated_second_pair) {
427 second_pair = diagonal_queue.top();
428 double const queue_weight = second_pair.second;
429 const auto &good = (*goods)[second_pair.first];
430 if(good.getPrice() > queue_weight) {
432 diagonal_queue.pop();
433 std::get<1>(second_pair) = good.getPrice();
434 diagonal_queue.push(second_pair);
436 updated_second_pair =
true;
443 double second_val = 0;
444 if(non_empty_goods) {
445 best_val = -best_pair.second;
446 second_val = diagonal_queue.size() > 0 ? -second_pair.second : best_val;
447 best_good = &(*goods)[best_pair.first];
451 bool is_twin =
false;
454 = -this->
cost(g, wasserstein, geometricalFactor, nonMatchingWeight);
456 if(non_empty_goods) {
458 second_val = best_val;
462 }
else if(val > second_val || diagonal_queue.empty()) {
469 second_val = best_val;
472 if(second_val == std::numeric_limits<double>::lowest()) {
474 second_val = best_val;
476 double const old_price = best_good->getPrice();
477 double new_price = old_price + best_val - second_val + epsilon;
478 if(new_price > std::numeric_limits<double>::max() / 2) {
479 new_price = old_price + epsilon;
488 int const idx_reassigned = best_good->getOwner();
489 best_good->assign(this->position_in_auction_, new_price);
492 correspondence_kdt_map[best_good->id_]->updateWeight(new_price, kdt_index);
493 if(non_empty_goods) {
494 diagonal_queue.push(best_pair);
497 if(non_empty_goods) {
498 std::get<1>(best_pair) = new_price;
499 diagonal_queue.push(best_pair);
502 return idx_reassigned;
509 double geometricalFactor,
510 double nonMatchingWeight,
512 const int kdt_index) {
515 std::vector<KDT *> neighbours;
516 std::vector<double> costs;
518 std::array<double, 5> coordinates;
521 kdt->
getKClosest(2, coordinates, neighbours, costs, kdt_index);
522 double best_val, second_val;
525 if(costs.size() == 2) {
526 std::array<int, 2> idx{0, 1};
527 std::sort(idx.begin(), idx.end(),
528 [&costs](
int &a,
int &b) { return costs[a] < costs[b]; });
530 closest_kdt = neighbours[idx[0]];
531 best_good = &(*goods)[closest_kdt->
id_];
534 best_val = -costs[idx[0]];
535 second_val = -costs[idx[1]];
538 closest_kdt = neighbours[0];
539 best_good = &(*goods)[closest_kdt->
id_];
540 best_val = -costs[0];
541 second_val = best_val;
544 bool twin_chosen =
false;
547 = -this->
cost(g, wasserstein, geometricalFactor, nonMatchingWeight);
550 second_val = best_val;
554 }
else if(val > second_val) {
558 if(second_val == std::numeric_limits<double>::lowest()) {
560 second_val = best_val;
562 double const old_price = best_good->getPrice();
563 double new_price = old_price + best_val - second_val + epsilon;
564 if(new_price > std::numeric_limits<double>::max() / 2) {
565 new_price = old_price + epsilon;
572 int const idx_reassigned = best_good->getOwner();
574 best_good->assign(this->position_in_auction_, new_price);
579 return idx_reassigned;
int runDiagonalBidding(GoodDiagram *goods, Good &twinGood, int wasserstein, double epsilon, double geometricalFactor, double nonMatchingWeight, std::priority_queue< std::pair< int, double >, std::vector< std::pair< int, double > >, Compare > &diagonal_queue)
int runKDTBidding(GoodDiagram *goods, Good &diagonalGood, int wasserstein, double epsilon, double geometricalFactor, double nonMatchingWeight, KDT *kdt, const int kdt_index=0)
void setPricePaid(const double price)
int runBidding(GoodDiagram *goods, Good &diagonalGood, int wasserstein, double epsilon, double geometricalFactor, double nonMatchingWeight)
void setProperty(const Good &g)
const Good & getProperty() const
KDTree< double, std::array< double, 5 > > KDT
int runDiagonalKDTBidding(GoodDiagram *goods, Good &diagonalGood, int wasserstein, double epsilon, double geometricalFactor, double nonMatchingWeight, std::vector< KDT * > &correspondence_kdt_map, std::priority_queue< std::pair< int, double >, std::vector< std::pair< int, double > >, Compare > &diagonal_queue, const int kdt_index=0)
int printWrn(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
void updateWeight(const dataType new_weight, const int weight_index=0)
void getKClosest(const unsigned int k, const Container &coordinates, KDTreeMap &neighbours, std::vector< dataType > &costs, const int weight_index=0)
void SetCriticalCoordinates(const float coords_x, const float coords_y, const float coords_z)
std::array< float, 3 > coords_
PersistenceDiagramAuctionActor()=default
double getPairGeometricalLength(const int wasserstein) const
void GetKDTCoordinates(double geometricalFactor, std::array< double, 5 > &coordinates) const
double cost(const PersistenceDiagramAuctionActor &g, const int wasserstein, const double geometricalFactor, const double nonMatchingWeight) const
void runAuctionRound(int &n_biddings, const int kdt_index=0)
double getRelativePrecision()
std::vector< KDT * > & correspondence_kdt_map_
std::priority_queue< std::pair< int, double >, std::vector< std::pair< int, double > >, Compare > diagonal_queue_
GoodDiagram diagonal_goods_
double initLowerBoundCost(const int kdt_index=0)
double getMatchingsAndDistance(std::vector< MatchingType > &matchings, bool get_diagonal_matches=false)
double nonMatchingWeight_
void initLowerBoundCostWeight(double delta_lim)
void buildUnassignedBidders()
double geometricalFactor_
std::queue< int > unassignedBidders_
T1 pow(const T1 val, const T2 n)
std::tuple< int, int, double > MatchingType
Matching between two Persistence Diagram pairs.
std::vector< Good > GoodDiagram