diff --git a/Vickrey Clark Grove Auction/ReadMe.md b/Vickrey Clark Grove Auction/ReadMe.md new file mode 100644 index 0000000..9b8eb68 --- /dev/null +++ b/Vickrey Clark Grove Auction/ReadMe.md @@ -0,0 +1,275 @@ +# How To Run +1. Install dotnet3.0 on your machine. +1. Navigate inside the release folder and launch a command/terminal window. Enter the following command + ```dotnet '.\Vickery Clark Grove Auction.dll'``` + +# What I have learned + + I have a much better understanding of the VCG auction. Figuring out a concise reusable algorithm to calculate the total price per bidder was very enlightning. + +# Interesting Simulations + +1. Given parameters in assignment. + +```Please input the auctions parameters in the form : +5 3 + +Enter number of clicks for each Ad placement 0 being the top: +Ad Placement 0: +500 +Ad Placement 1: +300 +Ad Placement 2: +100 + +Enter bids for each bidder: +A0's bid amount: +.5 +A1's bid amount: +.4 +A2's bid amount: +.3 +A3's bid amount: +.2 +A4's bid amount: +.1 + +A0 pays: $160.00 +A1 pays: $80.00 +A2 pays: $20.00 +A3 pays: $0.00 +A4 pays: $0.00 +``` + +2. Interesting because 2 bidders have the same bid. + +``` +Please input the auctions parameters in the form : +3 1 + +Enter number of clicks for each Ad placement 0 being the top: +Ad Placement 0: +150 + +Enter bids for each bidder: +A0's bid amount: +200 +A1's bid amount: +1 +A2's bid amount: +200 + +A2 pays: $30,000.00 +A0 pays: $0.00 +A1 pays: $0.00 +``` + +3. This one is interesting as the third bidder gets it for free. This could be beneficial if you were bidding as two seperate entities. +You could bid the same price multiple times and get free ad space. + +``` +Please input the auctions parameters in the form : +3 3 + +Enter number of clicks for each Ad placement 0 being the top: +Ad Placement 0: +300 +Ad Placement 1: +200 +Ad Placement 2: +150 + +Enter bids for each bidder: +A0's bid amount: +.5 +A1's bid amount: +.75 +A2's bid amount: +.75 + +A2 pays: $100.00 +A1 pays: $25.00 +A0 pays: $0.00 + +``` + +4. More advertisement spaces than bidders + +``` +Please input the auctions parameters in the form : +3 4 + +Enter number of clicks for each Ad placement 0 being the top: +Ad Placement 0: +200 +Ad Placement 1: +100 +Ad Placement 2: +50 +Ad Placement 3: +25 + +Enter bids for each bidder: +A0's bid amount: +25 +A1's bid amount: +.5 +A2's bid amount: +.3 + +A0 pays: $65.00 +A1 pays: $15.00 +A2 pays: $0.00 +``` + +5. Bidders dont win in order. +``` +Please input the auctions parameters in the form : +4 4 + +Enter number of clicks for each Ad placement 0 being the top: +Ad Placement 0: +500 +Ad Placement 1: +400 +Ad Placement 2: +200 +Ad Placement 3: +75 + +Enter bids for each bidder: +A0's bid amount: +.75 +A1's bid amount: +.77 +A2's bid amount: +.56 +A3's bid amount: +.80 + +A3 pays: $297.00 +A1 pays: $220.00 +A0 pays: $70.00 +A2 pays: $0.00 +``` + +# Code +```using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; + +namespace Vickrey_Clark_Grove_Auction +{ + internal static class VCGAuction + { + public static void Main(string[] args) + { + var parameters = GetAuctionParameters(); + CalculateAgentCost(parameters); + } + + private static List< Tuple> GetBids(int biddersCount) + { + Console.WriteLine("\nEnter bids for each bidder: "); + var bids = new List< Tuple>(); + for (var i = 0; i < biddersCount; i++) + { + var success = false; + while(!success) + { + Console.WriteLine($"A{i}'s bid amount: "); + var input = Console.ReadLine()?.Split().Select(x => double.TryParse(x, out var i) ? i : -1).ToList(); + if (input == null || input.Count != 1) + Console.WriteLine("Enter correct number of integers!"); + else if (Math.Abs(input[0] - (-1)) < 0) + Console.WriteLine("Enter valid input!"); + else + { + success = true; + bids.Add(new Tuple(bids.Count, input[0])); + } + } + } + + return bids; + } + + private static Tuple GetBidderCountAdvertisingCount() + { + var success = false; + var biddersAndSlots = new List(); + while (!success) + { + Console.WriteLine( + $"Please input the auctions parameters in the form : "); + biddersAndSlots = Console.ReadLine()?.Split().Select(x => Int32.TryParse(x, out var i) ? i : -1).ToList(); + if (biddersAndSlots == null || biddersAndSlots.Count != 2) + Console.WriteLine("Enter correct number of integers!"); + else if (biddersAndSlots.Contains(-1)) + Console.WriteLine("Enter valid input!"); + else + success = true; + } + + var bidderCount = biddersAndSlots[0]; + var advertisingCount = biddersAndSlots[1]; + var bidderAndAdvertisingCount = new Tuple(bidderCount, advertisingCount); + return bidderAndAdvertisingCount; + } + + private static Tuple, List>> GetAuctionParameters() + { + var (bidCount, adCount) = GetBidderCountAdvertisingCount(); + var slotClickCount = GetAdClickCount(adCount); + var bids = GetBids(bidCount); + var info = new Tuple, List>>(slotClickCount, bids); + return info; + } + + private static List GetAdClickCount(int slotCount) + { + Console.WriteLine("\nEnter number of clicks for each Ad placement 0 being the top: "); + var clickCounts = new List(); + for (var i = 0; i < slotCount; i++) + { + var success = false; + while(!success) + { + Console.WriteLine($"Ad Placement {i}: "); + var input = Console.ReadLine()?.Split().Select(x => Int32.TryParse(x, out var i) ? i : -1).ToList(); + if (input == null || input.Count != 1) + Console.WriteLine("Enter correct number of integers!"); + else if (input[0] == -1) + Console.WriteLine("Enter valid input!"); + else + { + success = true; + clickCounts.Add(input[0]); + } + } + } + + return clickCounts; + } + + private static void CalculateAgentCost(Tuple, List>> parameters) + { + Console.WriteLine(); + var ci = new CultureInfo("en-us"); + var (clicks, bids) = parameters; + bids.OrderBy(x => x.Item2); + bids.Reverse(); + for (var i = 0; i < bids.Count; i++) + { + var total = 0.0; + for (var j = i; j < clicks.Count && j + 1 < bids.Count; j++) + { + total += bids[j+1].Item2 * (clicks[j] - (j + 1 == clicks.Count? 0 : clicks[j + 1])); + } + Console.WriteLine($"A{bids[i].Item1} pays: {total.ToString("C2",ci)}"); + } + } + } +} +```