forked from ariel-research/fairpyx
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
egalitarian & utilitarian comparison is ready
- Loading branch information
1 parent
e3bcd2e
commit ec0a539
Showing
1 changed file
with
135 additions
and
0 deletions.
There are no files selected for viewing
135 changes: 135 additions & 0 deletions
135
experiments/compare_heterogeneous_matroid_constraints_algorithms.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
import experiments_csv | ||
import logging | ||
|
||
from fairpyx import rounded_allocation | ||
from fairpyx.algorithms.heterogeneous_matroid_constraints_algorithms import * | ||
from fairpyx.utils.test_utils import stringify | ||
from tests.test_heterogeneous_matroid_constraints_algorithms import * | ||
from fairpyx.algorithms.fractional_egalitarian import * | ||
|
||
def compare_heterogeneous_matroid_constraints_algorithms_egalitarian_utilitarian(): #egalitarian: prioritizes the poor | ||
""" | ||
we have 5 algorithms , for the sake of common support we give an input range respected by all algorithms | ||
meaning : single category , binary valuations , equal valuations , equal capacities | ||
we make number of items/number of agents variable | ||
""" | ||
expr=experiments_csv.Experiment('results/', 'egalitarian_utilitarian_comparison_heterogeneous_constraints_algorithms.csv') | ||
#expr.clear_previous_results() | ||
input_ranges_1 = { | ||
'equal_capacities': [True], | ||
'equal_valuations': [True], | ||
'binary_valuations': [True], | ||
'num_of_items':range(10,20), | ||
'category_count': [2], | ||
'item_capacity_bounds': range(1, 1 + 1), | ||
'random_seed_num': [0], | ||
'num_of_agents': range(10,20), | ||
'algorithm': [per_category_round_robin, capped_round_robin, | ||
per_category_capped_round_robin, two_categories_capped_round_robin, iterated_priority_matching] | ||
} | ||
input_ranges_2 = { | ||
'equal_capacities': [True], | ||
'equal_valuations': [True,False], | ||
'binary_valuations': [False], | ||
'num_of_items': range(10,20), | ||
'category_count': [2], | ||
'item_capacity_bounds': range(1, 1 + 1), | ||
'random_seed_num': [0], | ||
'num_of_agents': range(10,20), | ||
'algorithm': [per_category_round_robin, capped_round_robin | ||
, two_categories_capped_round_robin] | ||
} # equal capacities for the sake of the compatibility of input with the implemented egalitarian and utilitarian algorithms | ||
# we also need to consider giving each agent a capacity which is >= number of items | ||
input_ranges_3 = { | ||
'equal_capacities': [True], | ||
'equal_valuations': [True], | ||
'binary_valuations': [False], | ||
'num_of_items': range(10,20), | ||
'category_count': [2], | ||
'item_capacity_bounds': range(1, 1 + 1), | ||
'random_seed_num': [0], | ||
'num_of_agents': range(10,20), | ||
'algorithm': [ | ||
per_category_capped_round_robin] | ||
} | ||
# input_ranges_4 = { | ||
# 'equal_capacities': [True], | ||
# 'equal_valuations': [False,True], | ||
# 'binary_valuations': [False], | ||
# 'num_of_items': range(10,20), | ||
# 'category_count': [2], | ||
# 'item_capacity_bounds': range(1, 1 + 1), | ||
# 'random_seed_num': [0], | ||
# 'num_of_agents': range(10,20), | ||
# 'algorithm': [capped_round_robin, | ||
# two_categories_capped_round_robin] | ||
# } | ||
expr.run_with_time_limit(run_experiment,input_ranges_1,5) | ||
expr.run_with_time_limit(run_experiment, input_ranges_2, 5) | ||
expr.run_with_time_limit(run_experiment, input_ranges_3, 5) | ||
#expr.run_with_time_limit(run_experiment, input_ranges_4, 5) | ||
def run_experiment(equal_capacities:bool,equal_valuations:bool,binary_valuations:bool,category_count:int,item_capacity_bounds:int,random_seed_num:int,num_of_agents:int,algorithm:callable,num_of_items:int): | ||
# Mapping of algorithms to their specific argument sets | ||
algo_args = { | ||
per_category_round_robin: {'alloc', 'agent_category_capacities', 'item_categories', 'initial_agent_order'}, | ||
capped_round_robin: {'alloc', 'item_categories', 'agent_category_capacities', | ||
'initial_agent_order', 'target_category'}, | ||
two_categories_capped_round_robin: {'alloc', 'item_categories', 'agent_category_capacities', 'initial_agent_order','target_category_pair'}, | ||
per_category_capped_round_robin: {'alloc', 'item_categories', 'agent_category_capacities', 'initial_agent_order'}, | ||
iterated_priority_matching: {'alloc', 'item_categories', 'agent_category_capacities'}, | ||
} | ||
|
||
instance, agent_category_capacities, categories, initial_agent_order = random_instance( | ||
equal_capacities=equal_capacities, | ||
equal_valuations=equal_valuations, | ||
binary_valuations=binary_valuations, | ||
category_count=category_count, | ||
item_capacity_bounds=(1, item_capacity_bounds), random_seed_num=random_seed_num, num_of_agents=num_of_agents,num_of_items=num_of_items,agent_capacity_bounds=(num_of_items,num_of_items+1)) | ||
alloc = AllocationBuilder(instance) | ||
kwargs = {'alloc': alloc, 'agent_category_capacities': agent_category_capacities, 'item_categories': categories, | ||
'initial_agent_order': initial_agent_order, 'target_category_pair': ('c1', 'c2'), 'target_category': 'c1'} | ||
|
||
# Extract the set of required arguments for the chosen algorithm | ||
required_args = algo_args.get(algorithm, set()) | ||
|
||
# Filter kwargs to include only those required by the chosen algorithm | ||
filtered_kwargs = {k: v for k, v in kwargs.items() if k in required_args} | ||
valuation_matrix = [[instance.agent_item_value(agent, item) for item in instance.items] for agent in | ||
instance.agents]# simply forming valuations as in matrix so we can run fractional egalitarian algorithm | ||
not_rounded_egal=fractional_egalitarian_allocation(Instance(valuation_matrix),normalize_utilities=False) | ||
epsilon = 1 # replaced because a number (0,1) isnt a good apprach since it gives a very large number when being divided by | ||
min_egalitarian_algorithm_value=min(not_rounded_egal) | ||
min_egalitarian_algorithm_value_denominator=min_egalitarian_algorithm_value if min_egalitarian_algorithm_value!=0 else min_egalitarian_algorithm_value+epsilon | ||
experiments_csv.logger.info(f'valuation_matrix -> {valuation_matrix} \n and egalitarian allocation ->{not_rounded_egal} \n min value of it is -> {min_egalitarian_algorithm_value}') | ||
rounded_egal=rounded_allocation(not_rounded_egal,1)# integer | ||
algorithm(**filtered_kwargs) | ||
# bundle_values={agent:sum(instance.agent_item_value(agent,item) for item in bundle) for agent,bundle in alloc.bundles.items()}# sums the values of each agent bundle | ||
# min_bundle_value=min(bundle_values.values()) | ||
min_algorithm_bundle_value=min(alloc.agent_bundle_value(agent,bundle) for agent,bundle in alloc.bundles.items()) | ||
# utilitarian algorithm | ||
alloc_utilitarian=AllocationBuilder(instance) | ||
utilitarian_matching(alloc_utilitarian) | ||
utilitarian_bundle_sum=sum(alloc_utilitarian.agent_bundle_value(agent,bundle)for agent,bundle in alloc_utilitarian.bundles.items()) | ||
utilitarian_bundle_sum_denominator=utilitarian_bundle_sum if utilitarian_bundle_sum>0 else utilitarian_bundle_sum+epsilon # epsilon=1 to prevent big numbers | ||
current_algorithm_bundle_sum=sum(alloc.agent_bundle_value(agent,bundle)for agent,bundle in alloc.bundles.items()) | ||
#experiments_csv.logger.info(f'utilitarian algorithm bundle sum is ->{utilitarian_bundle_sum} \n current algorithm {algorithm.__name__} bundle sum is ->{current_algorithm_bundle_sum}') | ||
|
||
|
||
|
||
|
||
return {'egalitarian_algorithm_min_value':min_egalitarian_algorithm_value,'current_algorithm_min_value':min_algorithm_bundle_value,'ratio_egalitarian':min_algorithm_bundle_value/min_egalitarian_algorithm_value_denominator,'utilitarian_algorithm_sum':utilitarian_bundle_sum,'current_algorithm_sum':current_algorithm_bundle_sum,'ratio_utilitarian':current_algorithm_bundle_sum/utilitarian_bundle_sum_denominator} | ||
|
||
if __name__ == '__main__': | ||
# not_rounded_egal = fractional_egalitarian_allocation(Instance(valuation_matrix), normalize_utilities=False) | ||
# epsilon = 1 # replaced because a number (0,1) isnt a good apprach since it gives a very large number when being divided by | ||
# min_egalitarian_algorithm_value = min(not_rounded_egal) | ||
# min_egalitarian_algorithm_value_denominator = min_egalitarian_algorithm_value if min_egalitarian_algorithm_value != 0 else min_egalitarian_algorithm_value + epsilon | ||
# | ||
|
||
|
||
|
||
experiments_csv.logger.setLevel(logging.INFO) | ||
#compare_heterogeneous_matroid_constraints_algorithms_egalitarian_utilitarian() | ||
#experiments_csv.single_plot_results('results/egalitarian_utilitarian_comparison_heterogeneous_constraints_algorithms.csv',filter={},x_field='num_of_agents',y_field='ratio_egalitarian',z_field='algorithm',save_to_file='results/egalitarian_comparison_heterogeneous_constraints_algorithms.png') | ||
experiments_csv.single_plot_results('results/egalitarian_utilitarian_comparison_heterogeneous_constraints_algorithms.csv',filter={},x_field='num_of_agents',y_field='ratio_utilitarian',z_field='algorithm',save_to_file='results/utilitarian_comparison_heterogeneous_constraints_algorithms.png') | ||
|