class TwoAuctionPerfectInformationUser(Module): def __init__(self, module_name: str, module_file: str, module_handle, config_group: str): super(TwoAuctionPerfectInformationUser, self).__init__(module_name, module_file, module_handle, config_group) self.config_param_list = {} self.proc_module = ProcModule() self.domain = 0 self.logger = log().get_logger() def init_module(self, config_params: Dict[str, FieldValue]): self.config_param_list = config_params self.domain = self.proc_module.get_param_value('domainid', config_params) def check_parameters(self, request_params): required_fields = set() required_fields.add( self.proc_module.field_def_manager.get_field("quantity")['key']) required_fields.add( self.proc_module.field_def_manager.get_field("totalbudget")['key']) required_fields.add( self.proc_module.field_def_manager.get_field("maxvalue")['key']) for field in required_fields: if field not in request_params: raise ValueError( "two auction perfect information: ending check - it does not pass the check, \ field not included {0}".format(field['key'])) def create_bidding_object(self, auction_key: str, quantity: float, unit_budget: float, unit_price: float, start: datetime, stop: datetime) -> BiddingObject: """ Create bidding objects :param auction_key: :param quantity: :param unit_budget: :param unit_price: :param start: :param stop: :return: """ self.logger.debug("starting create bidding object") if unit_budget < unit_price: unit_price = unit_budget # build the elements of the bidding object elements = dict() config_elements = dict() record_id = "record_1" self.proc_module.insert_string_field("recordid", record_id, config_elements) self.proc_module.insert_float_field("quantity", quantity, config_elements) self.proc_module.insert_double_field("unitprice", unit_price, config_elements) elements[record_id] = config_elements # build the options (time intervals) options = dict() option_id = 'option_1' config_options = dict() self.proc_module.insert_datetime_field("start", start, config_options) self.proc_module.insert_datetime_field("stop", stop, config_options) options[option_id] = config_options bidding_object_id = self.proc_module.get_bidding_object_id() bidding_object_key = str(self.domain) + '.' + bidding_object_id bidding_object = BiddingObject(auction_key, bidding_object_key, AuctioningObjectType.BID, elements, options) self.logger.debug("ending create bidding object") return bidding_object def destroy_module(self): pass def execute(self, request_params: Dict[str, FieldValue], auction_key: str, start: datetime, stop: datetime, bids: dict) -> list: return [] def execute_user(self, request_params: Dict[str, FieldValue], auctions: dict, start: datetime, stop: datetime) -> list: """ :param request_params: :param auctions: :param start: :param stop: :return: """ self.logger.debug( "two auction perfect information module: start execute with # {0} of auctions" .format(len(auctions))) list_return = [] self.check_parameters(request_params) if len(auctions) > 0: self.logger.debug( "two auction perfect information - before setting up parameters" ) # Get the total money and budget and divide them by the number of auctions total_budget = self.proc_module.get_param_value( "totalbudget", request_params) max_unit_valuation = self.proc_module.get_param_value( "maxvalue", request_params) quantity = self.proc_module.get_param_value( "quantity", request_params) budget_by_auction = total_budget / len(auctions) valuation_by_auction = max_unit_valuation / len(auctions) unit_price = valuation_by_auction if budget_by_auction < valuation_by_auction: unit_price = budget_by_auction for auction_key in auctions: bidding_object = self.create_bidding_object( auction_key, quantity, budget_by_auction, unit_price, start, stop) list_return.append(bidding_object) return list_return def reset(self): print('reset') def get_module_info(self, option: ModuleInformation) -> str: self.logger.debug( "two auction perfect information module: start getModuleInfo") if option == ModuleInformation.I_MODNAME: return "Two auction perfect information User procedure" elif option == ModuleInformation.I_ID: return "two auction perfect information" elif option == ModuleInformation.I_VERSION: return "0.1" elif option == ModuleInformation.I_CREATED: return "2015/12/30" elif option == ModuleInformation.I_MODIFIED: return "2015/12/30" elif option == ModuleInformation.I_BRIEF: return "Bidding process for the perfect information two auction mechanism" elif option == ModuleInformation.I_VERBOSE: return "The auction just choose the minimum between the budget and unit price given as parameters" elif option == ModuleInformation.I_HTMLDOCS: return "http://www.uniandes.edu.co/... " elif option == ModuleInformation.I_PARAMS: return "IPAP_FT_QUANTITY, IPAP_FT_UNITBUDGET, IPAP_FT_MAXUNITVALUATION, \ IPAP_FT_STARTSECONDS, IPAP_FT_ENDSECONDS" elif option == ModuleInformation.I_RESULTS: return "A bidding for the request" elif option == ModuleInformation.I_AUTHOR: return "Andres Marentes" elif option == ModuleInformation.I_AFFILI: return "Universidad de los Andes, Colombia" elif option == ModuleInformation.I_EMAIL: return "*****@*****.**" elif option == ModuleInformation.I_HOMEPAGE: return "http://homepage" else: return ''
class BasicModuleUser(Module): def __init__(self, module_name: str, module_file: str, module_handle, config_group: str): super(BasicModuleUser, self).__init__(module_name, module_file, module_handle, config_group) self.config_param_list = {} self.proc_module = ProcModule() self.domain = 0 self.logger = log().get_logger() def init_module(self, config_params: Dict[str, FieldValue]): self.config_param_list = config_params self.domain = self.proc_module.get_param_value('domainid', config_params) def check_parameters(self, request_params): required_fields = set() required_fields.add( self.proc_module.field_def_manager.get_field("quantity")['key']) required_fields.add( self.proc_module.field_def_manager.get_field("totalbudget")['key']) required_fields.add( self.proc_module.field_def_manager.get_field("maxvalue")['key']) for field in required_fields: if field not in request_params: raise ValueError( "basic module: ending check - it does not pass the check, field not included {0}" .format(field)) def create_bidding_object(self, auction_key: str, quantity: float, unit_budget: float, unit_price: float, start: datetime, stop: datetime) -> BiddingObject: self.logger.debug("starting create bidding object") if unit_budget < unit_price: unit_price = unit_budget # build the elements of the bidding object elements = dict() config_elements = dict() record_id = "record_1" self.proc_module.insert_string_field("recordid", record_id, config_elements) self.proc_module.insert_float_field("quantity", quantity, config_elements) self.proc_module.insert_double_field("unitprice", unit_price, config_elements) elements[record_id] = config_elements # build the options (time intervals) options = dict() option_id = 'option_1' config_options = dict() self.proc_module.insert_datetime_field("start", start, config_options) self.proc_module.insert_datetime_field("stop", stop, config_options) options[option_id] = config_options bidding_object_id = self.proc_module.get_bidding_object_id() bidding_object_key = str(self.domain) + '.' + bidding_object_id bidding_object = BiddingObject(auction_key, bidding_object_key, AuctioningObjectType.BID, elements, options) self.logger.debug("ending create bidding object") return bidding_object def destroy_module(self): pass def execute(self, request_params: Dict[str, FieldValue], auction_key: str, start: datetime, stop: datetime, bids: dict) -> list: return [] def execute_user(self, request_params: Dict[str, FieldValue], auctions: dict, start: datetime, stop: datetime) -> list: """ :param request_params: :param auctions: :param start: :param stop: :return: """ self.logger.debug("starting execute user") try: self.check_parameters(request_params) total_budget = self.proc_module.get_param_value( "totalbudget", request_params) max_unit_valuation = self.proc_module.get_param_value( "maxvalue", request_params) quantity = self.proc_module.get_param_value( "quantity", request_params) budget_by_auction = total_budget / len(auctions) valuation_by_auction = max_unit_valuation / len(auctions) self.logger.debug("after setting up parameters") list_return = [] for auction_key in auctions: bidding_object = self.create_bidding_object( auction_key, quantity, budget_by_auction, valuation_by_auction, start, stop) list_return.append(bidding_object) self.logger.debug("ending execute user") return list_return except Exception as e: self.logger.error(str(e)) def reset(self): print('reset')
class BasicModule(Module): def __init__(self, module_name: str, module_file: str, module_handle, config_group: str): super(BasicModule, self).__init__(module_name, module_file, module_handle, config_group) self.config_params = {} self.logger = log().get_logger() self.bandwidth = 0 self.reserved_price = 0 self.domain = 0 self.proc_module = ProcModule() def init_module(self, config_params: Dict[str, FieldValue]): """ Initializes the module :param config_params: dictionary with the given configuration parameters """ self.logger.debug('in init_module') self.config_params = config_params self.domain = self.proc_module.get_param_value('domainid', config_params) def destroy_module(self): """ method to be executed when destroying the class :return: """ print('in destroy_module') def execute(self, request_params: Dict[str, FieldValue], auction_key: str, start: datetime, stop: datetime, bids: dict) -> list: """ Executes the auction procedure for an specific auction. :param request_params: request params included :param auction_key: auction key identifying the auction :param start: start datetime :param stop: stop datetime :param bids: bidding objects included :return: """ self.logger.debug("bas module: start execute num bids:{0}".format( str(len(bids)))) for bid_key in bids: self.logger.info("Bid key in auction process:{0}".format(bid_key)) tot_demand = self.proc_module.calculate_requested_quantities(bids) bandwidth_to_sell = self.proc_module.get_param_value( 'bandwidth', request_params) reserve_price = self.proc_module.get_param_value( 'reserveprice', request_params) # Order bids classifying them by whether they compete on the low and high auction. bids_low_rct, bids_high_rct = self.proc_module.separate_bids(bids, 0.5) # Calculate the number of requested quantities on both auctions. nl = self.proc_module.calculate_requested_quantities(bids_low_rct) nh = self.proc_module.calculate_requested_quantities(bids_high_rct) ordered_bids = defaultdict(list) for bidding_object_key in bids: bidding_object = bids[bidding_object_key] elements = bidding_object.elements for element_name in elements: config_params = elements[element_name] price = ParseFormats.parse_float( config_params["unitprice"].value) quantity = ParseFormats.parse_float( config_params["quantity"].value) alloc = AllocProc(bidding_object.get_parent_key(), bidding_object.get_key(), element_name, bidding_object.get_session(), quantity, price) ordered_bids[price].append(alloc) qty_available = bandwidth_to_sell sell_price = 0 self.logger.debug( "bas module - qty available:{0}".format(qty_available)) sorted_prices = sorted(ordered_bids.keys(), reverse=True) for price in sorted_prices: alloc_temp = ordered_bids[price] if price < reserve_price: for i in range(0, len(alloc_temp)): alloc_temp[i].quantity = 0 else: for i in range(0, len(alloc_temp)): if qty_available < alloc_temp[i].quantity: alloc_temp[i].quantity = qty_available if qty_available > 0: sell_price = price qty_available = 0 else: qty_available = qty_available - alloc_temp[i].quantity sell_price = price # There are more units available than requested if qty_available > 0: sell_price = reserve_price self.logger.debug("bas module: after executing the auction") allocations = {} # Creates allocations sorted_prices = sorted(ordered_bids.keys(), reverse=True) for price in sorted_prices: alloc_temp = ordered_bids[price] for i in range(0, len(alloc_temp)): key = self.proc_module.make_key( alloc_temp[i].auction_key, alloc_temp[i].bidding_object_key) if key in allocations: self.proc_module.increment_quantity_allocation( allocations[alloc_temp[i].bidding_object_key], alloc_temp[i].quantity) else: allocation = self.proc_module.create_allocation( self.domain, alloc_temp[i].session_id, alloc_temp[i].bidding_object_key, start, stop, alloc_temp[i].quantity, sell_price) allocations[key] = allocation # Convert from the map to the final allocationDB result allocation_res = [] for allocation_key in allocations: allocation = allocations[allocation_key] allocation_res.append(allocation) self.logger.info("allocation key: {0} - bidding object {1}".format( allocation_key, allocation.get_parent_key())) # Write a log with data of the auction self.logger.debug("starttime: {0} endtime:{1}".format( str(start), str(stop))) self.logger.debug( "demand: {0} - demand low: {1} demand high {2}".format( str(tot_demand), str(nl), str(nh))) self.logger.debug("qty_sell: {0}".format( str(bandwidth_to_sell - qty_available))) self.logger.debug("reservedPrice:{0} sell price:{1}".format( str(reserve_price), str(sell_price))) self.logger.info( "bas module: end execute - nbr allocations: {0}".format( len(allocation_res))) return allocation_res def execute_user(self, request_params: Dict[str, FieldValue], auctions: dict, start: datetime, stop: datetime) -> list: """ Executes the module for an agent :param request_params: request params included :param auctions: list of auction to create bids :param start: start datetime :param stop: stop datetime :return: list of bids created. """ print('in execute_user') return [] def reset(self): """ restart the module :return: """ print('in reset')
class TwoAuctionPerfectInformation(Module): def __init__(self, module_name: str, module_file: str, module_handle, config_group: str): super(TwoAuctionPerfectInformation, self).__init__(module_name, module_file, module_handle, config_group) self.config_params = {} self.logger = log().get_logger() self.bandwidth = 0 self.reserved_price = 0 self.domain = 0 self.proc_module = ProcModule() def init_module(self, config_params: Dict[str, FieldValue]): """ Initializes the module :param config_params: dictionary with the given configuration parameters """ self.logger.debug('in init_module') self.config_params = config_params self.domain = self.proc_module.get_param_value('domainid', config_params) def destroy_module(self): """ method to be executed when destroying the class :return: """ self.logger.debug('in destroy_module') def create_request( self, bids: Dict[str, BiddingObject]) -> (DefaultDict[float, list]): """ Creates allocation requests for low and high auctions. It promotes some high auction bid into the low auction :param self: :param bids: bids competing in the auction :return: allocations request in the auction. """ self.logger.debug("create request bids {0}".format(str(len(bids)))) # go through all high budget bids and pass some of their units as low auction requests. auction_allocs: DefaultDict[float, list] = defaultdict(list) for bidding_object_key in bids: bidding_object = bids[bidding_object_key] elements = bidding_object.elements for element_name in elements: config_params = elements[element_name] price = ParseFormats.parse_float( config_params["unitprice"].value) quantity = ParseFormats.parse_float( config_params["quantity"].value) alloc = AllocProc(bidding_object.get_parent_key(), bidding_object.get_key(), element_name, bidding_object.get_session(), quantity, price) auction_allocs[price].append(alloc) self.logger.debug("create requests after budget bids {0}".format( str(len(auction_allocs)))) return auction_allocs def execute_auction(self, start: datetime, stop: datetime, bids_to_fulfill: DefaultDict[float, list], qty_available: float, reserved_price: float) -> (dict, float): """ Executes a second price auction for high budget users. :param start: datetime when the allocation will start :param stop: datetime when the allocation will stop :param bids_to_fulfill: allocation requests to be allocated :param qty_available: quantity available to allocations :param reserved_price: minimum price for selling and to be used in the allocation. :return: """ sell_price = 0 allocations = {} sorted_prices = sorted(bids_to_fulfill.keys(), reverse=True) for price in sorted_prices: alloc_temp = bids_to_fulfill[price] if price < reserved_price: for i in range(0, len(alloc_temp)): alloc_temp[i].quantity = 0 else: for i in range(0, len(alloc_temp)): if qty_available < alloc_temp[i].quantity: alloc_temp[i].quantity = qty_available if qty_available > 0: sell_price = price qty_available = 0 else: qty_available = qty_available - alloc_temp[i].quantity sell_price = price # There are more units available than requested if qty_available > 0: sell_price = reserved_price # Creates allocations sorted_prices = sorted(bids_to_fulfill.keys(), reverse=True) for price in sorted_prices: alloc_temp: List[AllocProc] = bids_to_fulfill[price] for i in range(0, len(alloc_temp)): key = self.proc_module.make_key( alloc_temp[i].auction_key, alloc_temp[i].bidding_object_key) if key in allocations: self.proc_module.increment_quantity_allocation( allocations[alloc_temp[i].bidding_object_key], alloc_temp[i].quantity) else: allocation = self.proc_module.create_allocation( self.domain, alloc_temp[i].session_id, alloc_temp[i].bidding_object_key, start, stop, alloc_temp[i].quantity, sell_price) allocations[key] = allocation self.logger.debug( "two auction module: after create allocations - # nbr created: {0}" .format(len(allocations))) return allocations, sell_price def execute(self, request_params: Dict[str, FieldValue], auction_key: str, start: datetime, stop: datetime, bids: dict) -> list: """ Executes the auction procedure for an specific auction. :param request_params: request params included :param auction_key: auction key identifying the auction :param start: start datetime :param stop: stop datetime :param bids: bidding objects included :return: """ self.logger.debug("bas module: start execute num bids:{0}".format( str(len(bids)))) bandwidth_to_sell_low = self.proc_module.get_param_value( 'bandwidth01', request_params) bandwidth_to_sell_high = self.proc_module.get_param_value( 'bandwidth02', request_params) self.logger.debug( 'bandwidth_to_sell_low:{0} - bandwidth_to_sell_high:{1}'.format( str(bandwidth_to_sell_low), str(bandwidth_to_sell_high))) reserve_price_low: float = self.proc_module.get_param_value( 'reserveprice01', request_params) reserve_price_high: float = self.proc_module.get_param_value( 'reserveprice02', request_params) self.logger.debug( 'reserve_price_low: {0} - reserve_price_high:{1}'.format( str(reserve_price_low), str(reserve_price_high))) bl = self.proc_module.get_param_value('maxvalue01', request_params) bids_low, bids_high = self.proc_module.separate_bids(bids, bl) # Calculate the number of quantities requested on both auctions. nh = ceil(self.proc_module.calculate_requested_quantities(bids_high)) tot_demand = self.proc_module.calculate_requested_quantities(bids) if (tot_demand > (bandwidth_to_sell_low + bandwidth_to_sell_high)) and ( bandwidth_to_sell_high < nh): alloc_low = self.create_request(bids_low) allocations_low, sell_price_low = self.execute_auction( start, stop, alloc_low, bandwidth_to_sell_low, reserve_price_low) alloc_high = self.create_request(bids_high) allocations_high, sell_price_high = self.execute_auction( start, stop, alloc_high, bandwidth_to_sell_high, reserve_price_high) # Convert from the map to the final returning vector allocation_res = [] for allocation_key in allocations_low: allocation_res.append(allocations_low[allocation_key]) for allocation_key in allocations_high: allocation_res.append(allocations_high[allocation_key]) else: allocs = self.create_request(bids) allocations, sell_price = self.execute_auction( start, stop, allocs, bandwidth_to_sell_low + bandwidth_to_sell_high, reserve_price_low) # Convert from the map to the final returning vector allocation_res = [] for allocation_key in allocations: allocation_res.append(allocations[allocation_key]) self.logger.debug("two auction generalized module: end execute") return allocation_res def execute_user(self, request_params: Dict[str, FieldValue], auctions: dict, start: datetime, stop: datetime) -> list: """ Executes the module for an agent :param request_params: request params included :param auctions: list of auction to create bids :param start: start datetime :param stop: stop datetime :return: list of bids created. """ return [] def reset(self): """ restart the module :return: """ print('in reset') def get_module_info(self, option: ModuleInformation) -> str: """ Gets module information for who is implementing the mechanism. :param option: option (type of information) to be reported. :return: string with the information """ self.logger.debug( "two auction generalized module: start getModuleInfo") if option == ModuleInformation.I_MODNAME: return "Two Auction Perfect Information Module" elif option == ModuleInformation.I_ID: return "TwoAuctionPerfectInformation" elif option == ModuleInformation.I_VERSION: return "0.1" elif option == ModuleInformation.I_CREATED: return "2015/12/01" elif option == ModuleInformation.I_MODIFIED: return "2015/12/01" elif option == ModuleInformation.I_BRIEF: return "Auction process for spliting in low and high budget users" elif option == ModuleInformation.I_VERBOSE: return "It assumes that users are splitted as low and high budget" elif option == ModuleInformation.I_HTMLDOCS: return "http://www.uniandes.edu.co/... " elif option == ModuleInformation.I_PARAMS: return "BANDWIDTH01(bandwidth low auction) BANDWIDTH02(bandwidth high auction) \ RESERVEDPRICE0 (reserved price low auction) RESERVEDPRICE1 (reserved price high auction) \ MAXVALUE0(discriminating price low auction) MAXVALUE1(discriminating price high auction)" elif option == ModuleInformation.I_RESULTS: return "The set of assigments" elif option == ModuleInformation.I_AUTHOR: return "Andres Marentes" elif option == ModuleInformation.I_AFFILI: return "Universidad de los Andes, Colombia" elif option == ModuleInformation.I_EMAIL: return "*****@*****.**" elif option == ModuleInformation.I_HOMEPAGE: return "http://homepage" else: return ''
class SubsidyAuction(Module): def __init__(self, module_name: str, module_file: str, module_handle, config_group: str): super(SubsidyAuction, self).__init__(module_name, module_file, module_handle, config_group) self.config_params = {} self.logger = log().get_logger() self.bandwidth = 0 self.reserved_price = 0 self.domain = 0 self.proc_module = ProcModule() def init_module(self, config_params: Dict[str, FieldValue]): """ Initializes the module :param config_params: dictionary with the given configuration parameters """ self.logger.debug('in init_module') self.config_params = config_params self.domain = self.proc_module.get_param_value('domainid', config_params) def destroy_module(self): """ method to be executed when destroying the class :return: """ print('in destroy_module') def execute(self, request_params: Dict[str, FieldValue], auction_key: str, start: datetime, stop: datetime, bids: dict) -> list: """ Executes the auction procedure for an specific auction. :param request_params: request params included :param auction_key: auction key identifying the auction :param start: start datetime :param stop: stop datetime :param bids: bidding objects included :return: """ self.logger.debug("bas module: start execute num bids:{0}".format( str(len(bids)))) bandwidth_to_sell = self.proc_module.get_param_value( 'bandwidth', request_params) reserve_price = self.proc_module.get_param_value( 'reserveprice', request_params) subsidy = self.proc_module.get_param_value('subsidy', request_params) discriminatory_price = self.proc_module.get_param_value( 'maxvalue01', request_params) tot_demand = self.proc_module.calculate_requested_quantities(bids) # Order bids classifying them by whether they compete on the low and high auction. bids_low_rct, bids_high_rct = self.proc_module.separate_bids(bids, 0.5) # Calculate the number of quantities on both auctions. nl = self.proc_module.calculate_requested_quantities(bids_low_rct) nh = self.proc_module.calculate_requested_quantities(bids_high_rct) ordered_bids = self.proc_module.sort_bids_by_price( bids, discriminatory_price, subsidy) qty_available = bandwidth_to_sell sell_price = 0 self.logger.debug( "subsidy auction module- qty available: {0}".format(qty_available)) sorted_prices = sorted(ordered_bids.keys(), reverse=True) for price in sorted_prices: alloc_temp = ordered_bids[price] if price < reserve_price: for i in range(0, len(alloc_temp)): alloc_temp[i].quantity = 0 else: for i in range(0, len(alloc_temp)): if qty_available < alloc_temp[i].quantity: alloc_temp[i].quantity = qty_available if qty_available > 0: sell_price = price qty_available = 0 else: qty_available = qty_available - alloc_temp[i].quantity sell_price = price # There are more units available than requested if qty_available > 0: sell_price = reserve_price self.logger.debug( "subsidy auction module: after executing the auction for bids") allocations = {} # Creates allocations sorted_prices = sorted(ordered_bids.keys(), reverse=True) for price in sorted_prices: alloc_temp = ordered_bids[price] for i in range(0, len(alloc_temp)): key = self.proc_module.make_key( alloc_temp[i].auction_key, alloc_temp[i].bidding_object_key) if key in allocations: self.proc_module.increment_quantity_allocation( allocations[alloc_temp[i].bidding_object_key], alloc_temp[i].quantity) else: if alloc_temp[i].original_price < sell_price and alloc_temp[ i].quantity > 0: set_price = alloc_temp[i].original_price else: set_price = sell_price allocation = self.proc_module.create_allocation( self.domain, alloc_temp[i].session_id, alloc_temp[i].bidding_object_key, start, stop, alloc_temp[i].quantity, set_price) allocations[key] = allocation # Convert from the map to the final allocationDB result allocation_res = [] for allocation_key in allocations: allocation_res.append(allocations[allocation_key]) # Write a log with data of the auction self.logger.debug("starttime: {0} endtime:{1}".format( str(start), str(stop))) self.logger.debug( "demand: {0} - demand low: {1} demand high {2}".format( str(tot_demand), str(nl), str(nh))) self.logger.debug("qty_sell: {0}".format( str(bandwidth_to_sell - qty_available))) self.logger.debug("reservedPrice:{0} sell price:{1}".format( str(reserve_price), str(sell_price))) self.logger.debug("bas module: end execute") return allocation_res def execute_user(self, request_params: Dict[str, FieldValue], auctions: dict, start: datetime, stop: datetime) -> list: """ Executes the module for an agent :param request_params: request params included :param auctions: list of auction to create bids :param start: start datetime :param stop: stop datetime :return: list of bids created. """ print('in execute_user') return [] def reset(self): """ restart the module :return: """ print('in reset') def get_module_info(self, option: ModuleInformation) -> str: self.logger.debug("subsidy auction module: start getModuleInfo") if option == ModuleInformation.I_MODNAME: return "Subsidy Auction procedure" elif option == ModuleInformation.I_ID: return "bas" elif option == ModuleInformation.I_VERSION: return "0.1" elif option == ModuleInformation.I_CREATED: return "2015/12/30" elif option == ModuleInformation.I_MODIFIED: return "2015/12/30" elif option == ModuleInformation.I_BRIEF: return "Auction process that give to a target group a % additional bid value" elif option == ModuleInformation.I_VERBOSE: return "The auction process gives cares about capacity" elif option == ModuleInformation.I_HTMLDOCS: return "http://www.uniandes.edu.co/... " elif option == ModuleInformation.I_PARAMS: return "BANDWIDTH SUBSIDY MAXVALUE0 (discriminating Bid)" elif option == ModuleInformation.I_RESULTS: return "The set of assigments" elif option == ModuleInformation.I_AUTHOR: return "Andres Marentes" elif option == ModuleInformation.I_AFFILI: return "Universidad de los Andes, Colombia" elif option == ModuleInformation.I_EMAIL: return "*****@*****.**" elif option == ModuleInformation.I_HOMEPAGE: return "http://homepage" else: return ''
class TwoAuctionGeneralized(Module): def __init__(self, module_name: str, module_file: str, module_handle, config_group: str): super(TwoAuctionGeneralized, self).__init__(module_name, module_file, module_handle, config_group) self.config_params = {} self.logger = log().get_logger() self.bandwidth = 0 self.reserved_price = 0 self.domain = 0 self.proc_module = ProcModule() def init_module(self, config_params: Dict[str, FieldValue]): """ Initializes the module :param config_params: dictionary with the given configuration parameters """ self.logger.debug('in init_module') self.config_params = config_params self.domain = self.proc_module.get_param_value('domainid', config_params) def destroy_module(self): """ method to be executed when destroying the class :return: """ self.logger.debug('in destroy_module') @staticmethod def get_probability() -> float: """ Gets a uniform distribution sample for checking if a request should be promoted to the low auction :return: """ return random.uniform(0, 1) def create_request( self, bids_low: Dict[str, BiddingObject], bids_high: Dict[str, BiddingObject], q_star: float ) -> (DefaultDict[int, list], DefaultDict[float, list], int, int): """ Creates allocation requests for low and high auctions. It promotes some high auction bid into the low auction :param self: :param bids_low: bids competing in the low auction :param bids_high: bids competing in the high auction :param q_star: probability of being promoted. :return: allocations request in the low and high auctions. """ self.logger.debug( "create requests Nbr low bids {0} - Nbr high bids {1}".format( str(len(bids_low)), str(len(bids_high)))) nhtmp = 0 nltmp = 0 # creates the request for the L auction. index = 0 low_auction_allocs: DefaultDict[int, list] = defaultdict(list) for bidding_object_key in bids_low: bidding_object = bids_low[bidding_object_key] elements = bidding_object.elements inserted = False for element_name in elements: config_params = elements[element_name] price = ParseFormats.parse_float( config_params["unitprice"].value) quantity = ParseFormats.parse_float( config_params["quantity"].value) if quantity > 0: alloc = AllocProc(bidding_object.get_parent_key(), bidding_object.get_key(), element_name, bidding_object.get_session(), quantity, price) low_auction_allocs[index].append(alloc) nltmp = nltmp + quantity inserted = True # Only increase index if there was another node inserted. if inserted: index = index + 1 self.logger.debug("create requests after low budget bids {0}".format( str(len(low_auction_allocs)))) # go through all high budget bids and pass some of their units as low auction requests. high_auction_allocs: DefaultDict[float, list] = defaultdict(list) for bidding_object_key in bids_high: alloc_bids = [] bidding_object = bids_high[bidding_object_key] elements = bidding_object.elements inserted = False for element_name in elements: config_params = elements[element_name] price = ParseFormats.parse_float( config_params["unitprice"].value) quantity = ParseFormats.parse_float( config_params["quantity"].value) units_to_pass = 0 for k in range(0, floor(quantity)): if self.get_probability() <= q_star: # pass a unit. units_to_pass = units_to_pass + 1 # quantities in the H auction. alloc1 = AllocProc(bidding_object.get_parent_key(), bidding_object.get_key(), element_name, bidding_object.get_session(), quantity, price) high_auction_allocs[price].append(alloc1) nhtmp = nhtmp + quantity - units_to_pass if units_to_pass > 0: # quantities in the L auction. alloc2 = AllocProc(bidding_object.get_parent_key(), bidding_object.get_key(), element_name, bidding_object.get_session(), units_to_pass, price) alloc_bids.append(alloc2) inserted = True self.logger.debug("bid set: {0} units pass: {1}".format( bidding_object.get_key(), str(units_to_pass))) nltmp = nltmp + units_to_pass # Only increase index if there was another node inserted. if inserted: low_auction_allocs[index].extend(alloc_bids) index = index + 1 nl = nltmp nh = nhtmp self.logger.debug( "ending create requests low_auction request {0} nl: {1}-high auction request {2} nh: {3}" .format(str(len(low_auction_allocs)), str(nl), str(len(high_auction_allocs)), str(nh))) return low_auction_allocs, high_auction_allocs, nl, nh def execute_auction(self, start: datetime, stop: datetime, bids_to_fulfill: DefaultDict[float, list], qty_available: float, reserved_price: float) -> (dict, float): """ Executes a second price auction for high budget users. :param start: datetime when the allocation will start :param stop: datetime when the allocation will stop :param bids_to_fulfill: allocation requests to be allocated :param qty_available: quantity available to allocations :param reserved_price: minimum price for selling and to be used in the allocation. :return: """ sell_price = 0 allocations = {} sorted_prices = sorted(bids_to_fulfill.keys(), reverse=True) for price in sorted_prices: alloc_temp = bids_to_fulfill[price] if price < reserved_price: for i in range(0, len(alloc_temp)): alloc_temp[i].quantity = 0 else: for i in range(0, len(alloc_temp)): if qty_available < alloc_temp[i].quantity: alloc_temp[i].quantity = qty_available if qty_available > 0: sell_price = price qty_available = 0 else: qty_available = qty_available - alloc_temp[i].quantity sell_price = price # There are more units available than requested if qty_available > 0: sell_price = reserved_price # Creates allocations sorted_prices = sorted(bids_to_fulfill.keys(), reverse=True) for price in sorted_prices: alloc_temp: List[AllocProc] = bids_to_fulfill[price] for i in range(0, len(alloc_temp)): key = self.proc_module.make_key( alloc_temp[i].auction_key, alloc_temp[i].bidding_object_key) if key in allocations: self.proc_module.increment_quantity_allocation( allocations[alloc_temp[i].bidding_object_key], alloc_temp[i].quantity) else: allocation = self.proc_module.create_allocation( self.domain, alloc_temp[i].session_id, alloc_temp[i].bidding_object_key, start, stop, alloc_temp[i].quantity, sell_price) allocations[key] = allocation self.logger.debug( "two auction module: after create allocations - # nbr created: {0}" .format(len(allocations))) return allocations, sell_price def execute_auction_random_allocation(self, start: datetime, stop: datetime, bids_to_fulfill: DefaultDict[int, list], qty_available: float, reserved_price: float) -> dict: """ Creates allocations according with a random allocation. :param start: datetime when the allocation will start :param stop: datetime when the allocation will stop :param bids_to_fulfill: allocation requests to be allocated :param qty_available: quantity available to allocations :param reserved_price: minimum price for selling and to be used in the allocation. :return: dictionary with created allocations """ self.logger.debug("execute Action random allocation") allocations = {} # Create allocations with zero quantity for all bids. sorted_indexes: List[int] = sorted(bids_to_fulfill.keys(), reverse=True) for index in sorted_indexes: self.logger.debug("execute action random allocation 1") sorted_bids = bids_to_fulfill[index] for bid_index in range(len(sorted_bids) - 1, -1, -1): alloc_proc = sorted_bids[bid_index] key = self.proc_module.make_key(alloc_proc.auction_key, alloc_proc.bidding_object_key) if key not in allocations: allocation = self.proc_module.create_allocation( self.domain, alloc_proc.session_id, alloc_proc.bidding_object_key, start, stop, 0, reserved_price) allocations[key] = allocation # Remove the node if their price is less than the reserve price. if alloc_proc.original_price < reserved_price: del sorted_bids[bid_index] self.logger.debug("execute Action random allocation 2") # Remove the bid if all their price elements were less than the reserved price. if len(bids_to_fulfill[index]) == 0: del bids_to_fulfill[index] self.logger.debug("execute Action random allocation 3") self.logger.info("nbr allocation so far: {0}".format( str(len(allocations)))) self.logger.info("qty available: {0}".format(str(ceil(qty_available)))) # Allocates randomly the available quantities indexes = list(bids_to_fulfill.keys()) for j in range(0, ceil(qty_available)): prob = self.get_probability() length = len(indexes) main_index = floor(prob * length) if len(indexes) == 0: # All units have been assigned and there are no more bids. break else: index = indexes[main_index] # the unit is assigned to the first allocation proc for the bid. bids_to_fulfill[index][ 0].quantity = bids_to_fulfill[index][0].quantity - 1 key = self.proc_module.make_key( bids_to_fulfill[index][0].auction_key, bids_to_fulfill[index][0].bidding_object_key) # Create or update the allocation if key in allocations: self.proc_module.increment_quantity_allocation( allocations[key], 1) else: allocation = self.proc_module.create_allocation( self.domain, bids_to_fulfill[index][0].session_id, bids_to_fulfill[index][0].bidding_object_key, start, stop, 1, reserved_price) allocations[key] = allocation # Remove the node in case of no more units required. if bids_to_fulfill[index][0].quantity == 0: bids = bids_to_fulfill[index] del bids[0] if len(bids_to_fulfill[index]) == 0: del bids_to_fulfill[index] del indexes[main_index] self.logger.debug("execute Action random allocation") return allocations def apply_mechanism(self, start: datetime, stop: datetime, allocations: Dict[str, BiddingObject], reserved_price: float, q: float): """ Apply the two auction mechanism for a set of bidding objects. :param start: datetime when the allocation will start :param stop: datetime when the allocation will stop :param allocations: allocation request to allocate :param reserved_price: reserved price to be used for applying the mechanism. :param q: probability of promoting a user competing in the high budget auction. :return: """ self.logger.debug("starting ApplyMechanism Q: {0}".format(q)) allocations2 = {} for bidding_object_key in allocations: alloc = allocations[bidding_object_key] quantity = floor(self.proc_module.get_allocation_quantity(alloc)) units_to_pass = 0.0 for j in range(0, quantity): prob = self.get_probability() if prob <= q: # pass a unit. units_to_pass = units_to_pass + 1 self.logger.debug("qty to pass: {0}".format(str(units_to_pass))) if units_to_pass > 0: if units_to_pass < quantity: alloc2 = self.proc_module.create_allocation( self.domain, alloc.get_session(), alloc.get_parent_key(), start, stop, units_to_pass, reserved_price) units_to_add = units_to_pass * -1 self.proc_module.increment_quantity_allocation( alloc, units_to_add) allocations2[self.proc_module.make_key( alloc2.get_parent_key(), alloc2.get_key())] = alloc2 else: self.proc_module.change_allocation_price( alloc, reserved_price) # Inserts new allocations in allocation dictionary. for key in allocations2: alloc = allocations2[key] allocations[key] = alloc self.logger.debug("ending ApplyMechanism") def execute(self, request_params: Dict[str, FieldValue], auction_key: str, start: datetime, stop: datetime, bids: dict) -> list: """ Executes the auction procedure for an specific auction. :param request_params: request params included :param auction_key: auction key identifying the auction :param start: start datetime :param stop: stop datetime :param bids: bidding objects included :return: """ self.logger.info( "two auction generalized module: start execute {0}".format( len(bids))) bandwidth_to_sell_low = self.proc_module.get_param_value( 'bandwidth01', request_params) bandwidth_to_sell_high = self.proc_module.get_param_value( 'bandwidth02', request_params) self.logger.info( 'bandwidth_to_sell_low:{0} - bandwidth_to_sell_high:{1}'.format( str(bandwidth_to_sell_low), str(bandwidth_to_sell_high))) reserve_price_low: float = self.proc_module.get_param_value( 'reserveprice01', request_params) reserve_price_high: float = self.proc_module.get_param_value( 'reserveprice02', request_params) self.logger.info( 'reserve_price_low: {0} - reserve_price_high:{1}'.format( str(reserve_price_low), str(reserve_price_high))) bl = self.proc_module.get_param_value('maxvalue01', request_params) bh = self.proc_module.get_param_value('maxvalue02', request_params) tot_demand = self.proc_module.calculate_requested_quantities(bids) self.logger.info("totalReq: {0} total units: {1}".format( str(tot_demand), str(bandwidth_to_sell_low + bandwidth_to_sell_high))) if tot_demand > (bandwidth_to_sell_low + bandwidth_to_sell_high): self.logger.info("Splitting resources") bids_low, bids_high = self.proc_module.separate_bids(bids, bl) # Calculate the number of quantities requested on both auctions. nl = ceil( self.proc_module.calculate_requested_quantities(bids_low)) nh = ceil( self.proc_module.calculate_requested_quantities(bids_high)) if nh < bandwidth_to_sell_high: bandwidth_to_sell_low = bandwidth_to_sell_low + ( bandwidth_to_sell_high - nh) bandwidth_to_sell_high = nh if nl < bandwidth_to_sell_low: bandwidth_to_sell_high = bandwidth_to_sell_high + ( bandwidth_to_sell_low - nl) bandwidth_to_sell_low = nl self.logger.info( "Number of quantities requested low:{0} high:{1}".format( str(nl), str(nh))) q_star = 0 q = 0.2 self.logger.info("Starting the execution of the mechanism") if nl > 0 and nh > 0: # Find the probability of changing from the high budget to low budget auction. mechanism = TwoAuctionMechanismGeneralized() a = 0.01 b = 0.8 message = "nh:{0} nl:{1} bh:{2} bl:{3} bandwidth_to_sell_high:{4}".format( str(nh), str(nl), str(bh), str(bl), str(bandwidth_to_sell_high)) message = message + " bandwidth_to_sell_low:{0} reserve_price_high:{1} reserve_price_low:{2}".format( str(bandwidth_to_sell_low), str(reserve_price_high), str(reserve_price_low)) message = message + " q:{0} a:{1} b:{2}".format( str(q), str(a), str(b)) self.logger.info(message) res, a, b = mechanism.zero_in(nh, nl, bh, bl, bandwidth_to_sell_high, bandwidth_to_sell_low, reserve_price_high, reserve_price_low, q, a, b) q_star = a while (q_star >= 0.25) and (q <= 1.0): q = q + 0.03 a = 0.01 b = 0.8 message = "nh:{0} nl:{1} bh:{2} bl:{3} bandwidth_to_sell_high:{4}".format( str(nh), str(nl), str(bh), str(bl), str(bandwidth_to_sell_high)) message = message + " bandwidth_to_sell_low:{0} reserve_price_high:{1} reserve_price_low:{2}".format( str(bandwidth_to_sell_low), str(reserve_price_high), str(reserve_price_low)) message = message + " q:{0} a:{1} b:{2}".format( str(q), str(a), str(b)) self.logger.info(message) res, a, b = mechanism.zero_in(nh, nl, bh, bl, bandwidth_to_sell_high, bandwidth_to_sell_low, reserve_price_high, reserve_price_low, q, a, b) q_star = a self.logger.info("Q: {0} qStar: {1}".format( str(q), str(q_star))) self.logger.info( "Finished the execution of the mechanism q_start {0}".format( str(q_star))) self.logger.info("bids_low {0} - bids_high {1}".format( len(bids_low), len(bids_high))) # Create requests for both auctions, it passes the users from an auction to the other. low_auction_allocs, high_auction_allocs, nl, nh = self.create_request( bids_low, bids_high, q_star) self.logger.info( "low auctions_allocs {0} - high_auction_allocs {1}".format( len(low_auction_allocs), len(high_auction_allocs))) # Execute auctions. allocations_low = self.execute_auction_random_allocation( start, stop, low_auction_allocs, bandwidth_to_sell_low, reserve_price_low) allocations_high, reserve_price_high = self.execute_auction( start, stop, high_auction_allocs, bandwidth_to_sell_high, reserve_price_high) # code to debug. sell_prices_high = [] qty_allocates_high = [] for key in allocations_high: allocation = allocations_high[key] qty = self.proc_module.get_allocation_quantity(allocation) sell_price = self.proc_module.get_bid_price(allocation) sell_prices_high.append(sell_price) qty_allocates_high.append(qty) self.logger.info('sell prices high: {0}'.format( str(sell_prices_high))) self.logger.info('qty allocates high: {0}'.format( str(qty_allocates_high))) sell_prices_low = [] qty_allocates_low = [] for key in allocations_low: allocation = allocations_low[key] qty = self.proc_module.get_allocation_quantity(allocation) sell_price = self.proc_module.get_bid_price(allocation) sell_prices_low.append(sell_price) qty_allocates_low.append(qty) self.logger.info('sell prices low: {0}'.format( str(sell_prices_low))) self.logger.info('qty allocates low {0}:'.format( str(qty_allocates_low))) self.logger.info( "after executeAuction high budget users nbr allocations: {0}". format(len(allocations_high))) if q > 0: # change bids from the high budget to low budget auction. self.apply_mechanism(start, stop, allocations_high, reserve_price_low, q) # Convert from the map to the final returning vector allocation_res = [] for allocation_key in allocations_low: allocation = allocations_low[allocation_key] allocation_res.append(allocation) self.logger.info( "allocation low key: {0} - bidding object {1}".format( allocation_key, allocation.get_parent_key())) for allocation_key in allocations_high: allocation = allocations_high[allocation_key] allocation_res.append(allocation) self.logger.info( "allocation high key: {0} - bidding object {1}".format( allocation_key, allocation.get_parent_key())) else: self.logger.info("auctioning without splitting resources") # All bids get units and pay the reserved price of the L Auction bids_low = {} low_auction_allocs, high_auction_allocs, nl, nh = self.create_request( bids_low, bids, 0) allocations, reserve_price_low = self.execute_auction( start, stop, high_auction_allocs, bandwidth_to_sell_low + bandwidth_to_sell_high, reserve_price_low) # Convert from the map to the final allocationDB result allocation_res = [] for allocation_key in allocations: allocation = allocations[allocation_key] allocation_res.append(allocation) self.logger.info( "allocation key: {0} - bidding object {1}".format( allocation_key, allocation.get_parent_key())) self.logger.info("two auction generalized module: end execute") return allocation_res def execute_user(self, request_params: Dict[str, FieldValue], auctions: dict, start: datetime, stop: datetime) -> list: """ Executes the module for an agent :param request_params: request params included :param auctions: list of auction to create bids :param start: start datetime :param stop: stop datetime :return: list of bids created. """ return [] def reset(self): """ restart the module :return: """ print('in reset') def get_module_info(self, option: ModuleInformation) -> str: """ Gets module information for who is implementing the mechanism. :param option: option (type of information) to be reported. :return: string with the information """ self.logger.debug( "two auction generalized module: start getModuleInfo") if option == ModuleInformation.I_MODNAME: return "Two Auction Module" elif option == ModuleInformation.I_ID: return "TwoAuction" elif option == ModuleInformation.I_VERSION: return "0.1" elif option == ModuleInformation.I_CREATED: return "2015/12/01" elif option == ModuleInformation.I_MODIFIED: return "2015/12/01" elif option == ModuleInformation.I_BRIEF: return "Auction process for spliting in low and high budget users" elif option == ModuleInformation.I_VERBOSE: return "The auction calculates a probability q, so high budget users are priced as low budget users." elif option == ModuleInformation.I_HTMLDOCS: return "http://www.uniandes.edu.co/... " elif option == ModuleInformation.I_PARAMS: return "BANDWIDTH01(bandwidth low auction) BANDWIDTH02(bandwidth high auction) \ RESERVEDPRICE0 (reserved price low auction) RESERVEDPRICE1 (reserved price high auction) \ MAXVALUE0(discriminating price low auction) MAXVALUE1(discriminating price high auction)" elif option == ModuleInformation.I_RESULTS: return "The set of assigments" elif option == ModuleInformation.I_AUTHOR: return "Andres Marentes" elif option == ModuleInformation.I_AFFILI: return "Universidad de los Andes, Colombia" elif option == ModuleInformation.I_EMAIL: return "*****@*****.**" elif option == ModuleInformation.I_HOMEPAGE: return "http://homepage" else: return ''
class ProgressiveSecondPrice(Module): def __init__(self, module_name: str, module_file: str, module_handle, config_group: str): super(ProgressiveSecondPrice, self).__init__(module_name, module_file, module_handle, config_group) self.config_params = {} self.logger = log().get_logger() self.bandwidth = 0 self.reserved_price = 0 self.domain = 0 self.proc_module = ProcModule() def init_module(self, config_params: Dict[str, FieldValue]): """ Initializes the module :param config_params: dictionary with the given configuration parameters """ self.logger.debug('in init_module') self.config_params = config_params self.domain = self.proc_module.get_param_value('domainid', config_params) def destroy_module(self): """ method to be executed when destroying the class :return: """ self.logger.debug('in destroy_module') pass @staticmethod def calculate_allocation_quantities( tot_quantity: float, ordered_bids: DefaultDict[float, list], bid_to_exclude: str = None) -> Dict[str, AllocProc]: """ Calculates the allocation quantity to sell at each price bid. In the paper this corresponds to min(q_i, Q_i (p_i, s_{-i})) :param tot_quantity: available total quantity to sell. In the paper, it corresponds to Q :param ordered_bids: list of bids for which we want to calculate the maximum available quantity. :param bid_to_exclude: in case of giving this is a bid that should be excluded form the calculation. :return: return a dictionay with the id of the bid and its corresponding maximum available quantity. """ qty_acum = 0 allocations = {} sorted_prices = sorted(ordered_bids.keys(), reverse=True) for price in sorted_prices: alloc_temp = ordered_bids[price] acum_price = 0 for i in range(0, len(alloc_temp)): if alloc_temp[i].bidding_object_key != bid_to_exclude: acum_price += alloc_temp[i].quantity for i in range(0, len(alloc_temp)): if alloc_temp[i].bidding_object_key != bid_to_exclude: if tot_quantity - qty_acum - acum_price + alloc_temp[ i].quantity > 0: alloc_qty = min( alloc_temp[i].quantity, tot_quantity - qty_acum - acum_price + alloc_temp[i].quantity) else: alloc_qty = 0 alloc_proc = AllocProc(alloc_temp[i].auction_key, alloc_temp[i].bidding_object_key, alloc_temp[i].element_name, alloc_temp[i].session_id, alloc_qty, alloc_temp[i].original_price) allocations[alloc_temp[i].bidding_object_key] = alloc_proc qty_acum = qty_acum + acum_price return allocations def calculate_allocations( self, tot_quantity: float, ordered_bids: DefaultDict[float, list]) -> Dict[str, AllocProc]: """ Calculates the allocation cost to sell for each bid. In the paper this corresponds to c_i(s) :param tot_quantity: available total quantity to sell. In the paper, it corresponds to Q :param ordered_bids: list of bids for which we want to calculate the maximum available quantity. :return: """ allocations_all_bids = self.calculate_allocation_quantities( tot_quantity, ordered_bids) sorted_prices = sorted(ordered_bids.keys(), reverse=True) for price in sorted_prices: alloc_temp = ordered_bids[price] for i in range(0, len(alloc_temp)): allocations_partial_bids = self.calculate_allocation_quantities( tot_quantity, ordered_bids, alloc_temp[i].bidding_object_key) bid_cost = 0 for bid_key in allocations_partial_bids: price = allocations_partial_bids[bid_key].original_price alloc_qty = allocations_partial_bids[bid_key].quantity alloc_qty_included = allocations_all_bids[bid_key].quantity bid_cost = bid_cost + (price * (alloc_qty - alloc_qty_included)) allocations_all_bids[ alloc_temp[i].bidding_object_key].original_price = bid_cost return allocations_all_bids def create_allocations(self, start: datetime, stop: datetime, allocations: Dict[str, AllocProc]) -> list: """ Create allocations based the dictionary of alloca procs created. :param start: when the allocation will start :param stop: when the allocation will end :param allocations: dictionary with alloc procs created :return: list fo a allocations to return """ list_allocs = [] for bid_key in allocations: alloc_proc = allocations[bid_key] if alloc_proc.quantity == 0: allocation = self.proc_module.create_allocation( self.domain, alloc_proc.session_id, alloc_proc.bidding_object_key, start, stop, alloc_proc.quantity, 0) else: allocation = self.proc_module.create_allocation( self.domain, alloc_proc.session_id, alloc_proc.bidding_object_key, start, stop, alloc_proc.quantity, alloc_proc.original_price / alloc_proc.quantity) list_allocs.append(allocation) return list_allocs def execute(self, request_params: Dict[str, FieldValue], auction_key: str, start: datetime, stop: datetime, bids: dict) -> list: """ Executes the auction procedure for an specific auction. :param request_params: request params included :param auction_key: auction key identifying the auction :param start: start datetime :param stop: stop datetime :param bids: bidding objects included :return: """ self.logger.debug( "progressive second price auction: start execute num bids:{0}". format(str(len(bids)))) bandwidth_to_sell = self.proc_module.get_param_value( 'bandwidth', request_params) # sort bids from upper to lower values ordered_bids = self.proc_module.sort_bids_by_price(bids) # get allocations from the mechanism allocations = self.calculate_allocations(bandwidth_to_sell, ordered_bids) # create the final list of allocations and return it return self.create_allocations(start, stop, allocations) def execute_user(self, request_params: Dict[str, FieldValue], auctions: dict, start: datetime, stop: datetime) -> list: """ Executes the module for an agent :param request_params: request params included :param auctions: list of auction to create bids :param start: start datetime :param stop: stop datetime :return: list of bids created. """ print('in execute_user') return [] def reset(self): """ restart the module :return: """ print('in reset') def get_module_info(self, option: ModuleInformation) -> str: self.logger.debug("Progressive second price: start getModuleInfo") if option == ModuleInformation.I_MODNAME: return "Progressive Second price procedure" elif option == ModuleInformation.I_ID: return "psp" elif option == ModuleInformation.I_VERSION: return "0.1" elif option == ModuleInformation.I_CREATED: return "2019/05/09" elif option == ModuleInformation.I_MODIFIED: return "2019/05/09" elif option == ModuleInformation.I_BRIEF: return "Auction process that put the cost of the bid equals to the compensation principle" elif option == ModuleInformation.I_VERBOSE: return "The auction process cost bids according to the willingness to pay of other users for \ the units being allocated" elif option == ModuleInformation.I_HTMLDOCS: return "http://www.uniandes.edu.co/... " elif option == ModuleInformation.I_PARAMS: return "BANDWIDTH (how much capacity is being auctioned)" elif option == ModuleInformation.I_RESULTS: return "The set of assigments" elif option == ModuleInformation.I_AUTHOR: return "Andres Marentes" elif option == ModuleInformation.I_AFFILI: return "Advicetec Ltda, Colombia" elif option == ModuleInformation.I_EMAIL: return "*****@*****.**" elif option == ModuleInformation.I_HOMEPAGE: return "http://homepage" else: return ''
class ProgressiveSecondPriceUser(Module): def __init__(self, module_name: str, module_file: str, module_handle, config_group: str): super(ProgressiveSecondPriceUser, self).__init__(module_name, module_file, module_handle, config_group) self.config_param_list = {} self.proc_module = ProcModule() self.domain = 0 self.logger = log().get_logger() def init_module(self, config_params: Dict[str, FieldValue]): self.config_param_list = config_params self.domain = self.proc_module.get_param_value('domainid', config_params) def check_parameters(self, request_params): required_fields = set() required_fields.add( self.proc_module.field_def_manager.get_field("quantity")['key']) required_fields.add( self.proc_module.field_def_manager.get_field("maxvalue")['key']) for field in required_fields: if field not in request_params: raise ValueError( "basic module: ending check - it does not pass the check, \ field not included {0}".format(field['key'])) def create_bidding_object(self, auction_key: str, quantity: float, unit_budget: float, unit_price: float, start: datetime, stop: datetime) -> BiddingObject: """ Create bidding objects :param auction_key: :param quantity: :param unit_budget: :param unit_price: :param start: :param stop: :return: """ self.logger.debug("starting create bidding object") if unit_budget < unit_price: unit_price = unit_budget # build the elements of the bidding object elements = dict() config_elements = dict() record_id = "record_1" self.proc_module.insert_string_field("recordid", record_id, config_elements) self.proc_module.insert_float_field("quantity", quantity, config_elements) self.proc_module.insert_double_field("unitprice", unit_price, config_elements) elements[record_id] = config_elements # build the options (time intervals) options = dict() option_id = 'option_1' config_options = dict() self.proc_module.insert_datetime_field("start", start, config_options) self.proc_module.insert_datetime_field("stop", stop, config_options) options[option_id] = config_options bidding_object_id = self.proc_module.get_bidding_object_id() bidding_object_key = str(self.domain) + '.' + bidding_object_id bidding_object = BiddingObject(auction_key, bidding_object_key, AuctioningObjectType.BID, elements, options) self.logger.debug("ending create bidding object") return bidding_object def destroy_module(self): pass def execute(self, request_params: Dict[str, FieldValue], auction_key: str, start: datetime, stop: datetime, bids: dict) -> list: return [] def execute_user(self, request_params: Dict[str, FieldValue], auctions: dict, start: datetime, stop: datetime) -> list: """ :param request_params: :param auctions: :param start: :param stop: :return: """ self.logger.debug( "Progressive second price module: start execute with # {0} of auctions" .format(len(auctions))) list_return = [] self.check_parameters(request_params) if len(auctions) > 0: # Get the total money and budget and divide them by the number of auctions total_budget = self.proc_module.get_param_value( "totalbudget", request_params) max_unit_valuation = self.proc_module.get_param_value( "maxvalue", request_params) quantity = self.proc_module.get_param_value( "quantity", request_params) budget_by_auction = total_budget / len(auctions) unit_price_by_auction = max_unit_valuation / len(auctions) unit_price = unit_price_by_auction if budget_by_auction < unit_price_by_auction: unit_price = budget_by_auction self.logger.debug( "subsidy auction module - after setting up parameters") for auction_key in auctions: bidding_object = self.create_bidding_object( auction_key, quantity, unit_price, unit_price, start, stop) list_return.append(bidding_object) self.logger.debug("Progressive second price module: end execute") return list_return def reset(self): print('reset') def get_module_info(self, option: ModuleInformation) -> str: self.logger.debug( "Progressive second price module: start getModuleInfo") if option == ModuleInformation.I_MODNAME: return "Progressive second price procedure" elif option == ModuleInformation.I_ID: return "Progressive second price user" elif option == ModuleInformation.I_VERSION: return "0.1" elif option == ModuleInformation.I_CREATED: return "2019/05/09" elif option == ModuleInformation.I_MODIFIED: return "2019/05/09" elif option == ModuleInformation.I_BRIEF: return "Auction process that put the cost of the bid equals to the compensation principle" elif option == ModuleInformation.I_VERBOSE: return "The auction process cost bids according to the willingness to pay of other users for \ the units being allocated" elif option == ModuleInformation.I_HTMLDOCS: return "http://www.uniandes.edu.co/... " elif option == ModuleInformation.I_PARAMS: return "IPAP_FT_QUANTITY (requested quantity), IPAP_FT_MAXUNITVALUATION (own valuation), \ IPAP_FT_STARTSECONDS, IPAP_FT_ENDSECONDS" elif option == ModuleInformation.I_RESULTS: return "The user's bid" elif option == ModuleInformation.I_AUTHOR: return "Andres Marentes" elif option == ModuleInformation.I_AFFILI: return "Advicetec Ltda, Colombia" elif option == ModuleInformation.I_EMAIL: return "*****@*****.**" elif option == ModuleInformation.I_HOMEPAGE: return "http://homepage" else: return ''