Example #1
0
def experiment(results_csv_file: str, recipe: list, value_ranges: list,
               nums_of_agents: list, num_of_iterations: int,
               agent_counts: list, agent_values: list,
               recipe_tree_agent_counts: list, num_recipes: int):
    """
    Run an experiment similar to McAfee (1992) experiment on the given auction.
    :param results_csv_file: the experiment result file.
    :param auction_functions: list of functions for executing the auction under consideration.
    :param auction_names: titles of the experiment, for printouts.
    :param recipe: can be any vector of ones, e.g. (1,1,1), for our trade-reduction mechanism, or any vector of positive integers for our ascending-auction mechanism.
    :param nums_of_agents: list of n(s) for number of possible trades to make the calculations.
    :param stocks_prices: list of prices for each stock and each agent.
    :param stock_names: list of stocks names which prices are belongs, for naming only.
    """
    TABLE_COLUMNS = [
        "iterations", "recipe", "numofagents", "optimalcount", "optimalkmin",
        "optimalkmax", "gftformula", "auctioncount", "auctionkmin",
        "auctionkmax", "countratio", "optimalgft", "auctiongft", "gftratio"
    ]
    print('recipe:', recipe, 'size:', num_recipes)
    GFT_ROUND = 1 - 1
    K_ROUND = 2 - 1
    RATIO_ROUND = 3 - 1
    results_table = TeeTable(TABLE_COLUMNS, results_csv_file)
    recipe_str = str(recipe).replace(',', '-')
    is_binary = len(set(recipe_tree_agent_counts)) == 1

    for i in range(len(nums_of_agents)):
        now = datetime.now()
        sum_optimal_count = sum_auction_count = sum_optimal_kmin = sum_optimal_kmax = 0  # count the number of deals done in the optimal vs. the actual auction.
        sum_optimal_gft = sum_auction_total_gft = sum_auction_kmin = sum_auction_kmax = 0
        for iteration in range(num_of_iterations):
            #if iteration % 10000 == 0:
            #    print('iteration:', iteration)
            agents = []
            for category in range(len(recipe_tree_agent_counts)):
                sign = 0 if category == 0 else 1
                agents.append(
                    AgentCategory.uniformly_random(
                        "agent",
                        int(nums_of_agents[i] * agent_counts[category]),
                        value_ranges[sign][0] * agent_values[category],
                        value_ranges[sign][1] * agent_values[category]))
                #agents.append(AgentCategory.uniformly_random("agent", nums_of_agents[i], value_ranges[sign][0], value_ranges[sign][1]))
            market = Market(agents)
            #print(market)
            #print(agents)
            recipe_tree = RecipeTree(market.categories, recipe,
                                     recipe_tree_agent_counts)
            optimal_trade, optimal_count, optimal_gft, kmin, kmax, categories_optimal_counters = recipe_tree.optimal_trade_with_counters(
            )
            #print('counters:' + str(categories_counters))
            #print('optimal trade:', optimal_trade, optimal_count, optimal_gft)
            auction_trade = budget_balanced_ascending_auction(
                market, recipe, recipe_tree_agent_counts)
            auction_count = auction_trade.num_of_deals()
            auction_kmin = auction_trade.min_num_of_deals()
            auction_kmax = auction_trade.max_num_of_deals()
            path_counters = auction_trade.path_counters
            gft = auction_trade.gain_from_trade()
            #print('Compare:', categories_optimal_counters, path_counters)
            for counter in categories_optimal_counters.keys():
                if categories_optimal_counters[
                        counter] > path_counters[counter] + 1 and False:
                    print(market)
                    print('Compare:', categories_optimal_counters,
                          path_counters)
                    print('Warning counters', str(counter),
                          'are not in same size!',
                          categories_optimal_counters[counter], '!=',
                          path_counters[counter])
            #for i in range(len(path_counters)):
            #    print('Compare:', categories_optimal_counters, path_counters)
            #if optimal_count > 0 and gft < optimal_gft * (kmin - 1)/(kmin + 2):
            #the auction count is less more than 1 than the optimal count.
            #    print('Warning GFT!!!', 'optimal_count:', optimal_count, 'auction_count:', auction_count,
            #          'num_of_possible_ps:', nums_of_agents[i], 'optimal_gft:', optimal_gft, 'gft:', gft, 'lower bound:', optimal_gft * (1 - 1/optimal_count))
            #    if nums_of_agents[i] < 20:
            #        print(market.categories)

            sum_optimal_count += optimal_count
            sum_auction_count += auction_count

            sum_optimal_kmin += kmin
            sum_optimal_kmax += kmax

            sum_auction_kmin += auction_kmin
            sum_auction_kmax += auction_kmax

            sum_optimal_gft += optimal_gft
            sum_auction_total_gft += gft

            #if auction_count < optimal_count - 2:
            #the auction count is less more than 1 than the optimal count.
            #print('Warning!!!', 'optimal_count:', optimal_count, 'auction_count:', auction_count, 'num_of_possible_ps:', nums_of_agents[i])
            #if nums_of_agents[i] < 10:
            #    print(market.categories)

        # print("Num of times {} attains the maximum GFT: {} / {} = {:.2f}%".format(title, count_optimal_gft, num_of_iterations, count_optimal_gft * 100 / num_of_iterations))
        # print("GFT of {}: {:.2f} / {:.2f} = {:.2f}%".format(title, sum_auction_gft, sum_optimal_gft, 0 if sum_optimal_gft==0 else sum_auction_gft * 100 / sum_optimal_gft))
        kmin_mean = sum_optimal_kmin / num_of_iterations
        if is_binary:
            gft_formula = int_round(
                (kmin_mean - 1) / kmin_mean * 100 if kmin_mean - 1 > 0 else 0,
                RATIO_ROUND)
        else:
            gft_formula = int_round(
                (kmin_mean - num_recipes) / (kmin_mean + num_recipes) *
                100 if kmin_mean - num_recipes > 0 else 0, RATIO_ROUND)

        results_table.add(
            OrderedDict([
                ("iterations", num_of_iterations),
                ("recipe", recipe_str),
                ("numofagents", nums_of_agents[i]),
                ("optimalcount",
                 int_round(sum_optimal_count / num_of_iterations, K_ROUND)),
                ("optimalkmin", int_round(kmin_mean, K_ROUND)),
                ("optimalkmax",
                 int_round(sum_optimal_kmax / num_of_iterations, K_ROUND)),
                ("gftformula", gft_formula),
                ("auctioncount",
                 int_round(sum_auction_count / num_of_iterations, K_ROUND)),
                ("auctionkmin",
                 int_round(sum_auction_kmin / num_of_iterations, K_ROUND)),
                ("auctionkmax",
                 int_round(sum_auction_kmax / num_of_iterations, K_ROUND)),
                ("countratio",
                 int_round(
                     0 if sum_optimal_count == 0 else
                     (sum_auction_count / sum_optimal_count) * 100,
                     RATIO_ROUND)),
                ("optimalgft",
                 int_round(sum_optimal_gft / num_of_iterations, GFT_ROUND)),
                ("auctiongft",
                 int_round(sum_auction_total_gft / num_of_iterations,
                           GFT_ROUND)),
                ("gftratio", '0.00' if sum_optimal_gft == 0 else int_round(
                    sum_auction_total_gft / sum_optimal_gft *
                    100, RATIO_ROUND)),
            ]))
        print('took', (datetime.now() - now).seconds)
    results_table.done()
Example #2
0
def experiment(results_csv_file: str, recipe: list, value_ranges: list,
               nums_of_agents: list, num_of_iterations: int,
               agent_counts: list, agent_values: list,
               agent_counts_integer: list):
    """
    Run an experiment similar to McAfee (1992) experiment on the given auction.
    :param results_csv_file: the experiment result file.
    :param auction_functions: list of functions for executing the auction under consideration.
    :param auction_names: titles of the experiment, for printouts.
    :param recipe: can be any vector of ones, e.g. (1,1,1), for our trade-reduction mechanism, or any vector of positive integers for our ascending-auction mechanism.
    :param nums_of_agents: list of n(s) for number of possible trades to make the calculations.
    :param stocks_prices: list of prices for each stock and each agent.
    :param stock_names: list of stocks names which prices are belongs, for naming only.
    """
    TABLE_COLUMNS = [
        "iterations", "recipe", "numofagents", "optimalcount", "optimalkmin",
        "optimalkmax", "gftformula", "auctioncount", "auctionkmin",
        "auctionkmax", "countratio", "optimalgft", "auctiongft", "gftratio"
    ]
    GFT_ROUND = 1
    K_ROUND = 2
    RATIO_ROUND = 3
    print('recipe:', recipe)
    results_table = TeeTable(TABLE_COLUMNS, results_csv_file)
    results_table_integer = TeeTable(TABLE_COLUMNS,
                                     results_csv_file[0:-4] + '_integer.csv')
    recipe_str = str(recipe).replace(',', '-')
    category_size_list = get_agents_analyze(recipe)
    for i in range(len(nums_of_agents)):
        sum_optimal_count = sum_auction_count = sum_optimal_kmin = sum_optimal_kmax = 0  # count the number of deals done in the optimal vs. the actual auction.
        sum_optimal_gft = sum_auction_total_gft = sum_auction_kmin = sum_auction_kmax = 0
        sum_optimal_count_integer = sum_auction_count_integer = sum_optimal_kmin_integer = sum_optimal_kmax_integer = 0  # count the number of deals done in the optimal vs. the actual auction.
        sum_optimal_gft_integer = sum_auction_total_gft_integer = sum_auction_kmin_integer = sum_auction_kmax_integer = 0

        for iteration in range(num_of_iterations):
            if iteration % 10000 == 0:
                print('iteration:', iteration)
            agents = []
            agents_integer = []
            for category in range(len(category_size_list)):
                sign = 0 if category == 0 else 1
                agent_category = AgentCategory.uniformly_random(
                    "agent", int(nums_of_agents[i] * agent_counts[category]),
                    value_ranges[sign][0] * agent_values[category],
                    value_ranges[sign][1] * agent_values[category])
                agents.append(agent_category)
                agents_integer.append(
                    AgentCategory(
                        agent_category.name,
                        agent_category.values + agent_category.values))
                #agents.append(AgentCategory.uniformly_random("agent", nums_of_agents[i], value_ranges[sign][0], value_ranges[sign][1]))
            market = Market(agents)
            market_integer = Market(agents_integer)

            #print(agents)
            recipe_tree = RecipeTree(market.categories, recipe)
            recipe_tree_integer = RecipeTree(market_integer.categories, recipe,
                                             agent_counts_integer)
            optimal_trade, optimal_count, optimal_gft, kmin, kmax = recipe_tree.optimal_trade_with_counters(
            )
            optimal_trade_integer, optimal_count_integer, optimal_gft_integer, kmin_integer, kmax_integer = recipe_tree_integer.optimal_trade_with_counters(
            )
            #print('optimal trade:', optimal_trade, optimal_count, optimal_gft)
            auction_trade = budget_balanced_ascending_auction(market, recipe)
            auction_trade_integer = budget_balanced_ascending_auction(
                market_integer, recipe, agent_counts_integer)
            auction_count = auction_trade.num_of_deals()
            auction_count_integer = auction_trade_integer.num_of_deals()
            auction_kmin = auction_trade.min_num_of_deals()
            auction_kmin_integer = auction_trade_integer.min_num_of_deals()
            auction_kmax = auction_trade.max_num_of_deals()
            auction_kmax_integer = auction_trade_integer.max_num_of_deals()
            gft = auction_trade.gain_from_trade()
            gft_integer = auction_trade_integer.gain_from_trade()
            #if optimal_count > 0 and gft < optimal_gft * (1 - 1/optimal_count):
            #the auction count is less more than 1 than the optimal count.
            #    print('Warning GFT!!!', 'optimal_count:', optimal_count, 'auction_count:', auction_count,
            #          'num_of_possible_ps:', nums_of_agents[i], 'optimal_gft:', optimal_gft, 'gft:', gft)
            #    if nums_of_agents[i] < 20:
            #        print(market.categories)

            sum_optimal_count += optimal_count
            sum_optimal_count_integer += optimal_count_integer
            sum_auction_count += auction_count
            sum_auction_count_integer += auction_count_integer

            sum_optimal_kmin += kmin
            sum_optimal_kmin_integer += kmin_integer
            sum_optimal_kmax += kmax
            sum_optimal_kmax_integer += kmax_integer

            sum_auction_kmin += auction_kmin
            sum_auction_kmin_integer += auction_kmin_integer
            sum_auction_kmax += auction_kmax
            sum_auction_kmax_integer += auction_kmax_integer

            sum_optimal_gft += optimal_gft
            sum_optimal_gft_integer += optimal_gft_integer
            sum_auction_total_gft += gft
            sum_auction_total_gft_integer += gft_integer

            if auction_count < optimal_count - 2:
                #the auction count is less more than 1 than the optimal count.
                print('Warning!!!', 'optimal_count:', optimal_count,
                      'auction_count:', auction_count, 'num_of_possible_ps:',
                      nums_of_agents[i])
                if nums_of_agents[i] < 10:
                    print(market.categories)

        # print("Num of times {} attains the maximum GFT: {} / {} = {:.2f}%".format(title, count_optimal_gft, num_of_iterations, count_optimal_gft * 100 / num_of_iterations))
        # print("GFT of {}: {:.2f} / {:.2f} = {:.2f}%".format(title, sum_auction_gft, sum_optimal_gft, 0 if sum_optimal_gft==0 else sum_auction_gft * 100 / sum_optimal_gft))
        kmin_mean = sum_optimal_kmin / num_of_iterations
        kmin_mean_integer = sum_optimal_kmin_integer / num_of_iterations

        results_table.add(
            OrderedDict([
                ("iterations", num_of_iterations),
                ("recipe", recipe_str),
                ("numofagents", nums_of_agents[i]),
                ("optimalcount",
                 int_round(sum_optimal_count / num_of_iterations, K_ROUND)),
                ("optimalkmin", int_round(kmin_mean, K_ROUND)),
                ("optimalkmax",
                 int_round(sum_optimal_kmax / num_of_iterations, K_ROUND)),
                ("gftformula",
                 int_round((1 - 1 / kmin_mean) * 100 if kmin_mean > 1 else 0,
                           RATIO_ROUND)),
                ("auctioncount",
                 int_round(sum_auction_count / num_of_iterations, K_ROUND)),
                ("auctionkmin",
                 int_round(sum_auction_kmin / num_of_iterations, K_ROUND)),
                ("auctionkmax",
                 int_round(sum_auction_kmax / num_of_iterations, K_ROUND)),
                ("countratio",
                 int_round(
                     0 if sum_optimal_count == 0 else
                     (sum_auction_count / sum_optimal_count) * 100,
                     RATIO_ROUND)),
                ("optimalgft",
                 int_round(sum_optimal_gft / num_of_iterations, GFT_ROUND)),
                ("auctiongft",
                 int_round(sum_auction_total_gft / num_of_iterations,
                           GFT_ROUND)),
                ("gftratio", '0.00' if sum_optimal_gft == 0 else int_round(
                    sum_auction_total_gft / sum_optimal_gft *
                    100, RATIO_ROUND)),
            ]))
        results_table_integer.add(
            OrderedDict([
                ("iterations", num_of_iterations),
                ("recipe", recipe_str),
                ("numofagents", nums_of_agents[i]),
                ("optimalcount",
                 int_round(sum_optimal_count_integer / num_of_iterations,
                           K_ROUND)),
                ("optimalkmin", int_round(kmin_mean_integer, K_ROUND)),
                ("optimalkmax",
                 int_round(sum_optimal_kmax_integer / num_of_iterations,
                           K_ROUND)),
                ("gftformula",
                 int_round((1 - 1 / kmin_mean_integer) *
                           100 if kmin_mean_integer > 1 else 0, RATIO_ROUND)),
                ("auctioncount",
                 int_round(sum_auction_count_integer / num_of_iterations,
                           K_ROUND)),
                ("auctionkmin",
                 int_round(sum_auction_kmin_integer / num_of_iterations,
                           K_ROUND)),
                ("auctionkmax",
                 int_round(sum_auction_kmax_integer / num_of_iterations,
                           K_ROUND)),
                ("countratio",
                 int_round(
                     0 if sum_optimal_count_integer == 0 else
                     (sum_auction_count_integer / sum_optimal_count_integer) *
                     100, RATIO_ROUND)),
                ("optimalgft",
                 int_round(sum_optimal_gft_integer / num_of_iterations,
                           GFT_ROUND)),
                ("auctiongft",
                 int_round(sum_auction_total_gft_integer / num_of_iterations,
                           GFT_ROUND)),
                ("gftratio",
                 '0.00' if sum_optimal_gft_integer == 0 else int_round(
                     sum_auction_total_gft_integer / sum_optimal_gft_integer *
                     100, RATIO_ROUND)),
            ]))
    results_table.done()
def experiment(results_csv_file: str,
               auction_functions: list,
               auction_names: str,
               recipe: tuple,
               nums_of_agents=None,
               stocks_prices: list = None,
               stock_names: list = None,
               num_of_iterations=1000,
               run_with_stock_prices=True,
               report_diff=False):
    """
    Run an experiment similar to McAfee (1992) experiment on the given auction.
    :param results_csv_file: the experiment result file.
    :param auction_functions: list of functions for executing the auction under consideration.
    :param auction_names: titles of the experiment, for printouts.
    :param recipe: can be any vector of ones, e.g. (1,1,1), for our trade-reduction mechanism, or any vector of positive integers for our ascending-auction mechanism.
    :param stocks_prices: list of prices for each stock and each agent.
    :param stock_names: list of stocks names which prices are belongs, for naming only.
    """
    TABLE_COLUMNS = [
        "iterations", "stockname", "recipe", "numpossibletrades",
        "optimalcount", "gftratioformula", "optimalcountwithgftzero",
        "optimalgft", "optimalgftwithgftzero"
    ]
    AUCTION_COLUMNS = [
        "count", "countratio", "totalgft", "totalgftratio",
        "withoutgftzerocountratio", "withoutgftzerototalgft",
        "withoutgftzerototalgftratio", "marketgft", "marketgftratio"
    ]

    if path.exists(results_csv_file):
        print('The file', results_csv_file, 'already exists, skipping')
        return
    else:
        print('Running for the file', results_csv_file)
    if stocks_prices is None:
        (stocks_prices, stock_names) = getStocksPricesShuffled()
    column_names = TABLE_COLUMNS
    column_names += [
        auction_name + column for auction_name in auction_names
        for column in AUCTION_COLUMNS
    ]
    results_table = TeeTable(column_names, results_csv_file)
    recipe_str = ":".join(map(str, recipe))
    recipe_sum = sum(recipe)
    recipe_sum_for_buyer = (recipe_sum - recipe[0]) / recipe[0]
    if nums_of_agents is None:
        nums_of_agents = [10000000]
    #print(nums_of_agents)
    total_results = {}
    for num_of_agents_per_category in nums_of_agents:
        total_results[str(num_of_agents_per_category)] = []
    #print(total_results)
    for i in range(len(stocks_prices)):
        stock_prices = stocks_prices[i]
        for num_of_possible_ps in nums_of_agents:
            for iteration in range(num_of_iterations):
                categories = []
                if run_with_stock_prices:
                    while len(stock_prices) < num_of_possible_ps * recipe_sum:
                        stock_prices = stock_prices + stock_prices
                    random.shuffle(stock_prices)
                    index = 0
                    for category in recipe:
                        next_index = index + num_of_possible_ps * category
                        price_sign = recipe_sum_for_buyer if index == 0 else -1
                        #price_value_multiple = -1 * buyer_agent_count if index > 0 else recipe_sum - buyer_agent_count
                        categories.append(
                            AgentCategory("agent", [
                                int(price * price_sign)
                                for price in stock_prices[index:next_index]
                            ]))
                        index = next_index
                else:  #prices from random.
                    for index in range(len(recipe)):
                        #for category in recipe:
                        min_value = -100000 if index > 0 else recipe_sum_for_buyer
                        max_value = -1 if index > 0 else 100000 * recipe_sum_for_buyer
                        categories.append(
                            AgentCategory.uniformly_random(
                                "agent", num_of_possible_ps * recipe[index],
                                min_value, max_value))
                market = Market(categories)
                (optimal_trade,
                 _) = market.optimal_trade(ps_recipe=list(recipe),
                                           max_iterations=10000000,
                                           include_zero_gft_ps=False)
                optimal_count = optimal_trade.num_of_deals()
                optimal_gft = optimal_trade.gain_from_trade()
                (optimal_trade_with_gft_zero,
                 _) = market.optimal_trade(ps_recipe=list(recipe),
                                           max_iterations=10000000)
                optimal_count_with_gft_zero = optimal_trade_with_gft_zero.num_of_deals(
                )
                optimal_gft_with_gft_zero = optimal_trade_with_gft_zero.gain_from_trade(
                )

                results = [
                    ("iterations", num_of_iterations),
                    ("stockname", stock_names[i]), ("recipe", recipe_str),
                    ("numpossibletrades", int(num_of_possible_ps)),
                    ("optimalcount", optimal_count),
                    ("gftratioformula", (optimal_count - 1) * 100 /
                     (optimal_count if min(recipe) == max(recipe)
                      and recipe[0] == 1 else optimal_count + 1)
                     if optimal_count > 1 else 0),
                    ("optimalcountwithgftzero", optimal_count_with_gft_zero),
                    ("optimalgft", optimal_gft),
                    ("optimalgftwithgftzero", optimal_gft_with_gft_zero)
                ]
                for auction_index in range(len(auction_functions)):
                    auction_trade = auction_functions[auction_index](market,
                                                                     recipe)
                    count = auction_trade.num_of_deals()
                    total_gft = auction_trade.gain_from_trade(
                        including_auctioneer=True)
                    market_gft = auction_trade.gain_from_trade(
                        including_auctioneer=False)
                    auction_name = auction_names[auction_index]
                    results.append(
                        (auction_name + "count", auction_trade.num_of_deals()))

                    results.append(
                        (auction_name + "countratio",
                         0 if optimal_count == 0 else
                         (count / optimal_count_with_gft_zero) * 100))
                    results.append((auction_name + "totalgft", total_gft))
                    results.append((auction_name + "totalgftratio",
                                    0 if optimal_gft == 0 else total_gft /
                                    optimal_gft_with_gft_zero * 100))
                    results.append((auction_name + "marketgft", market_gft))
                    results.append((auction_name + "marketgftratio",
                                    0 if optimal_gft == 0 else market_gft /
                                    optimal_gft_with_gft_zero * 100))
                    results.append((auction_name + "withoutgftzerocountratio",
                                    0 if optimal_count == 0 else
                                    (count / optimal_count) * 100))
                    results.append(
                        (auction_name + "withoutgftzerototalgft", total_gft))
                    results.append(
                        (auction_name + "withoutgftzerototalgftratio",
                         0 if optimal_gft == 0 else total_gft / optimal_gft *
                         100))
                #We check which auction did better and print the market and their results.
                if report_diff:
                    gft_to_compare = -1
                    k_to_compare = -1
                    gft_found = False
                    k_found = False
                    for (label, value) in results:
                        if 'SBB' in label:
                            if gft_found is False and label.endswith(
                                    'totalgft'):
                                if gft_to_compare < 0:
                                    gft_to_compare = value
                                elif gft_to_compare != value:
                                    with open('diff_in_sbbs_gft.txt',
                                              'a') as f:
                                        f.write(
                                            'There is diff in gft between two auctions: '
                                            + str(gft_to_compare) + ' ' +
                                            str(value) + '\n')
                                        f.write(str(results) + '\n')
                                        if num_of_possible_ps < 10:
                                            f.write(str(market) + '\n')
                                    gft_found = True
                            elif k_found is False and label.endswith('count'):
                                if k_to_compare < 0:
                                    k_to_compare = value
                                elif k_to_compare != value:
                                    with open('diff_in_sbbs_k.txt', 'a') as f:
                                        f.write(
                                            'There is diff in gft between two auctions: '
                                            + str(k_to_compare) + ' ' +
                                            str(value) + '\n')
                                        f.write(str(results) + '\n')
                                        if num_of_possible_ps < 10:
                                            f.write(str(market) + '\n')
                                    k_found = True
                compare_sbbs = True
                if compare_sbbs:
                    gft_to_compare = -1
                    k_to_compare = -1
                    gft_found = False
                    k_found = False
                    for (label, value) in results:
                        if 'SBB' in label:
                            if gft_found is False and label.endswith(
                                    'totalgft'):
                                if gft_to_compare < 0:
                                    gft_to_compare = value
                                elif gft_to_compare > value:
                                    with open('diff_in_sbbs_gft.txt',
                                              'a') as f:
                                        f.write(
                                            'There is diff in gft between two auctions: '
                                            + str(gft_to_compare) + ' ' +
                                            str(value) + '\n')
                                        f.write(str(results) + '\n')
                                        if num_of_possible_ps < 10:
                                            f.write(str(market) + '\n')
                                    gft_found = True
                            elif k_found is False and label.endswith('count'):
                                if k_to_compare < 0:
                                    k_to_compare = value
                                elif k_to_compare > value:
                                    with open('diff_in_sbbs_k.txt', 'a') as f:
                                        f.write(
                                            'There is diff in gft between two auctions: '
                                            + str(k_to_compare) + ' ' +
                                            str(value) + '\n')
                                        f.write(str(results) + '\n')
                                        if num_of_possible_ps < 10:
                                            f.write(str(market) + '\n')
                                    k_found = True
                #results_table.add(OrderedDict(results))
                #print(results)
                if len(total_results[str(num_of_possible_ps)]) == 0:
                    total_results[str(
                        num_of_possible_ps)] = results[0:len(results)]
                else:
                    sum_result = total_results[str(num_of_possible_ps)]
                    for index in range(len(results)):
                        if index > 3:
                            sum_result[index] = (results[index][0],
                                                 sum_result[index][1] +
                                                 results[index][1])
            #print(total_results)
        print(stock_names[i], end=',')
        #break
    print()
    division_number = num_of_iterations * len(stocks_prices)
    #division_number = num_of_iterations
    for num_of_possible_ps in nums_of_agents:
        results = total_results[str(num_of_possible_ps)]
        for index in range(len(results)):
            if 'gftratio' in results[index][0]:
                results[index] = (results[index][0],
                                  padding_zeroes(
                                      results[index][1] / division_number, 3))
            elif index > 3:
                results[index] = (results[index][0],
                                  padding_zeroes(
                                      results[index][1] / division_number, 2))
            elif index == 1:
                results[index] = (results[index][0], 'Average')
        #print(results)
        results_table.add(OrderedDict(results))
    results_table.done()
Example #4
0
def experiment(results_csv_file: str, auction_function: Callable,
               auction_name: str, recipe: tuple, value_ranges: list,
               nums_of_agents: list, num_of_iterations: int):
    """
    Run an experiment similar to McAfee (1992) experiment on the given auction.

    :param auction_function: the function for executing the auction under consideration.
    :param auction_name: title of the experiment, for printouts.
    :param nums_of_agents: a list of the numbers of agents with which to run the experiment.
    :param value_ranges: for each category, a pair (min_value,max_value). The value for each agent in this category is selected uniformly at random between min_value and max_value.
    :param num_of_iterations: how many times to repeat the experiment for each num of agents.
    """
    results_table = TeeTable(TABLE_COLUMNS, results_csv_file)
    recipe_str = ":".join(map(str, recipe))
    num_of_categories = len(recipe)
    for num_of_agents_per_category in nums_of_agents:
        sum_optimal_count = sum_auction_count = 0  # count the number of deals done in the optimal vs. the actual auction.
        sum_optimal_gft = sum_auction_total_gft = sum_auction_market_gft = 0
        for _ in range(num_of_iterations):
            market = Market([
                AgentCategory.uniformly_random(
                    "agent", num_of_agents_per_category * recipe[category],
                    value_ranges[category][0], value_ranges[category][1])
                for category in range(num_of_categories)
            ])
            (optimal_trade, _) = market.optimal_trade(recipe)
            auction_trade = auction_function(market, recipe)

            sum_optimal_count += optimal_trade.num_of_deals()
            sum_auction_count += auction_trade.num_of_deals()

            sum_optimal_gft += optimal_trade.gain_from_trade()
            sum_auction_total_gft += auction_trade.gain_from_trade(
                including_auctioneer=True)
            sum_auction_market_gft += auction_trade.gain_from_trade(
                including_auctioneer=False)

        # print("Num of times {} attains the maximum GFT: {} / {} = {:.2f}%".format(title, count_optimal_gft, num_of_iterations, count_optimal_gft * 100 / num_of_iterations))
        # print("GFT of {}: {:.2f} / {:.2f} = {:.2f}%".format(title, sum_auction_gft, sum_optimal_gft, 0 if sum_optimal_gft==0 else sum_auction_gft * 100 / sum_optimal_gft))
        results_table.add(
            OrderedDict((
                ("iterations", num_of_iterations),
                ("auction_name", auction_name),
                ("recipe", recipe_str),
                ("num_of_agents", num_of_agents_per_category),
                ("mean_optimal_count",
                 round(sum_optimal_count / num_of_iterations, 2)),
                ("mean_auction_count",
                 round(sum_auction_count / num_of_iterations, 2)),
                ("count_ratio", 0 if sum_optimal_count == 0 else int(
                    (sum_auction_count / sum_optimal_count) * 10000) / 100),
                ("mean_optimal_gft",
                 round(sum_optimal_gft / num_of_iterations, 2)),
                ("mean_auction_total_gft",
                 round(sum_auction_total_gft / num_of_iterations, 2)),
                ("total_gft_ratio", 0 if sum_optimal_gft == 0 else round(
                    sum_auction_total_gft / sum_optimal_gft * 100, 2)),
                ("mean_auction_market_gft",
                 round(sum_auction_market_gft / num_of_iterations, 2)),
                ("market_gft_ratio", 0 if sum_optimal_gft == 0 else round(
                    sum_auction_market_gft / sum_optimal_gft * 100, 2)),
            )))
    results_table.done()
Example #5
0
def experiment(results_csv_file: str, recipes: tuple, value_ranges: list,
               nums_of_agents: list, num_of_iterations: int):
    """
    Run an experiment similar to McAfee (1992) experiment on the given auction.

    :param recipes: list of recipes.
    :param nums_of_agents: a list of the numbers of agents with which to run the experiment.
    :param value_ranges: for each category, a pair (min_value,max_value). The value for each agent in this category is selected uniformly at random between min_value and max_value.
    :param num_of_iterations: how many times to repeat the experiment for each num of agents.
    """
    results_table = TeeTable(TABLE_COLUMNS, results_csv_file)
    for recipe in recipes:
        recipe_str = ":".join(map(str, recipe))
        num_of_categories = len(recipe)
        external_wins_gft = tie_gft = ascending_wins_gft = 0
        external_wins_k = tie_k = ascending_wins_k = 0
        for num_of_agents_per_category in nums_of_agents:
            external_sum_auction_count = ascending_sum_auction_count = 0  # count the number of deals done the ascending auction.
            external_sum_auction_gft = ascending_sum_auction_gft = 0
            agents_recipe_values = [sum(recipe) - recipe[0]] + [
                recipe[0] for _ in range(1, len(recipe))
            ]
            for _ in range(num_of_iterations):
                market = Market([
                    AgentCategory.uniformly_random(
                        "agent", num_of_agents_per_category * recipe[category],
                        value_ranges[category][0] *
                        agents_recipe_values[category],
                        value_ranges[category][1] *
                        agents_recipe_values[category])
                    for category in range(num_of_categories)
                ])
                (optimal_trade, _) = market.optimal_trade(recipe)
                external_auction_trade = budget_balanced_trade_reduction(
                    market, recipe)
                ascending_auction_trade = budget_balanced_ascending_auction(
                    market, recipe)

                external_sum_auction_count += external_auction_trade.num_of_deals(
                )
                ascending_sum_auction_count += ascending_auction_trade.num_of_deals(
                )

                external_sum_auction_gft += external_auction_trade.gain_from_trade(
                )
                ascending_sum_auction_gft += ascending_auction_trade.gain_from_trade(
                )

            if external_sum_auction_count > ascending_sum_auction_count:
                external_wins_k += 1
            elif external_sum_auction_count == ascending_sum_auction_count:
                tie_k += 1
            else:
                ascending_wins_k += 1

            if external_sum_auction_gft > ascending_sum_auction_gft:
                external_wins_gft += 1
            elif external_sum_auction_gft == ascending_sum_auction_gft:
                tie_gft += 1
            else:
                ascending_wins_gft += 1
        num_agents = len(nums_of_agents)

        results_table.add(
            OrderedDict((
                ("recipe", recipe),
                ("external_wins_gft",
                 int(external_wins_gft * 100 / num_agents)),
                ("tie_gft", int(tie_gft * 100 / num_agents)),
                ("ascending_wins_gft",
                 int(ascending_wins_gft * 100 / num_agents)),
                ("external_wins_k", int(external_wins_k * 100 / num_agents)),
                ("tie_k", int(tie_k * 100 / num_agents)),
                ("ascending_wins_k", int(ascending_wins_k * 100 / num_agents)),
                ("external_wins", external_wins_gft),
                ("tie", tie_gft),
                ("ascending_wins", ascending_wins_gft),
            )))
    results_table.done()