From 44079d5cbbab5eeea367e9420b29c5b6f48eede8 Mon Sep 17 00:00:00 2001 From: Markus Teich Date: Tue, 1 Nov 2016 13:16:41 +0100 Subject: [PATCH] handle n <= m case in m+1st price auctions The lowest possible price from the price map will be the price each bidder has to pay. Since the seller can define the price map, he can set the lowest price to the lowest he is willing to sell one item at. --- brandt.c | 41 ++++++++++++++++++++++++++++++++++++++++- test_brandt.c | 26 ++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/brandt.c b/brandt.c index dab0ad2..ff106fb 100644 --- a/brandt.c +++ b/brandt.c @@ -67,6 +67,31 @@ BRANDT_bidder_start (struct BRANDT_Auction *auction, atype = auction->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice; outcome = auction->outcome_public ? outcome_public : outcome_private; + if (auction_mPlusFirstPrice == atype && n <= auction->m) + { /* fewer bidders than items to sell. every bidder won with lowest price */ + struct BRANDT_Result *res; + if (auction->outcome_public) + { + res = GNUNET_new_array (n, struct BRANDT_Result); + for (uint16_t h = 0; h < n; h++) + { + res[h].bidder = h; + res[h].price = 0; + res[h].status = BRANDT_bidder_won; + } + auction->result (auction->closure, res, n); + } + else + { + res = GNUNET_new (struct BRANDT_Result); + res->bidder = i; + res->price = 0; + res->status = BRANDT_bidder_won; + auction->result (auction->closure, res, 1); + } + return; + } + /* On M+1st price auctions we multiply the amount of prizes by the amount of * bidders and resctrict each bidder to his own distinct subset of the * prices. This is done for tie breaking. An additional proof is used in the @@ -104,12 +129,26 @@ seller_start (void *arg) ad->task = NULL; - if (0 == (ad->n = ad->start (ad->closure))) + ad->n = ad->start (ad->closure); + if (0 == ad->n) { weprintf ("no bidders registered for auction"); ad->result (ad->closure, NULL, 0); return; } + else if (ad->n <= ad->m) + { + struct BRANDT_Result *res = GNUNET_new_array (ad->n, struct BRANDT_Result); + + weprintf ("less bidders than needed, selling for lowest price"); + for (uint16_t i = 0; i < ad->n; i++) + { + res[i].bidder = i; + res[i].price = 0; + res[i].status = BRANDT_bidder_won; + } + ad->result (ad->closure, res, ad->n); + } atype = ad->m > 0 ? auction_mPlusFirstPrice : auction_firstPrice; outcome = ad->outcome_public ? outcome_public : outcome_private; diff --git a/test_brandt.c b/test_brandt.c index 1fb985c..46ec90d 100644 --- a/test_brandt.c +++ b/test_brandt.c @@ -84,6 +84,29 @@ expected_outcome (uint16_t i) return ret; } + /* fewer bidders than needed -> everyone wins with lowest price */ + if (tcase.n <= tcase.m) + { + if (tcase.outcome_public || i == tcase.n) + { + ret = GNUNET_new_array (tcase.n, struct BRANDT_Result); + for (uint16_t h = 0; h < tcase.n; h++) + { + ret[h].bidder = h; + ret[h].price = 0; + ret[h].status = BRANDT_bidder_won; + } + } + else + { + ret = GNUNET_new (struct BRANDT_Result); + ret->bidder = i; + ret->price = 0; + ret->status = BRANDT_bidder_won; + } + return ret; + } + /* find M+1st highest bidder to determine selling price */ for (uint16_t h = 0; h < tcase.n; h++) if (tcase.bids[h] > mpf_highest_bid) @@ -387,6 +410,9 @@ main (int argc, char *argv[]) test_auction (0, 2, NULL, 0, 1) || test_auction (0, 2, NULL, 1, 0) || test_auction (0, 2, NULL, 2, 0) || + test_auction (1, 2, (uint16_t[]) { 1 }, 1, 0) || + test_auction (1, 2, (uint16_t[]) { 0 }, 2, 0) || + test_auction (2, 2, (uint16_t[]) { 1, 0 }, 2, 0) || test_auction (2, 2, (uint16_t[]) { 1, 0 }, 1, 0) || test_auction (3, 2, (uint16_t[]) { 0, 0, 1 }, 2, 0) || test_auction (3, 2, (uint16_t[]) { 0, 1, 1 }, 0, 0) ||