diff --git a/.gitignore b/.gitignore index d6f307a..c792d83 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ dist/ downloads/ eggs/ .eggs/ -lib/ lib64/ parts/ sdist/ diff --git a/experiments/compare_course_allocation_algorithms.py b/experiments/compare_course_allocation_algorithms.py index 0319b51..024df5a 100644 --- a/experiments/compare_course_allocation_algorithms.py +++ b/experiments/compare_course_allocation_algorithms.py @@ -18,6 +18,7 @@ TIME_LIMIT = 100 algorithms_to_check = [ + crs.gale_shapley, crs.utilitarian_matching, crs.iterated_maximum_matching_unadjusted, crs.iterated_maximum_matching_adjusted, @@ -53,16 +54,16 @@ def course_allocation_with_random_instance_uniform( value_noise_ratio:float, algorithm:Callable, random_seed: int,): - agent_capacity_bounds = [6,6] - item_capacity_bounds = [40,40] + agent_capacity_bounds = (6,6) + item_capacity_bounds = (40,40) np.random.seed(random_seed) instance = Instance.random_uniform( num_of_agents=num_of_agents, num_of_items=num_of_items, normalized_sum_of_values=normalized_sum_of_values, - agent_capacity_bounds=agent_capacity_bounds, - item_capacity_bounds=item_capacity_bounds, - item_base_value_bounds=[1,max_value], - item_subjective_ratio_bounds=[1-value_noise_ratio, 1+value_noise_ratio] + agent_capacity_bounds=agent_capacity_bounds, + item_capacity_bounds=item_capacity_bounds, + item_base_value_bounds=(1,max_value), + item_subjective_ratio_bounds=(1-value_noise_ratio, 1+value_noise_ratio) ) return evaluate_algorithm_on_instance(algorithm, instance) @@ -127,6 +128,7 @@ def run_szws_experiment(): import json filename = "data/ariel_5783_input.json" +# filename = "experiments/data/ariel_5783_input.json" with open(filename, "r", encoding="utf-8") as file: ariel_5783_input = json.load(file) @@ -165,7 +167,7 @@ def run_ariel_experiment(): if __name__ == "__main__": import logging, experiments_csv experiments_csv.logger.setLevel(logging.INFO) - run_uniform_experiment() + # run_uniform_experiment() # run_szws_experiment() # run_ariel_experiment() diff --git a/experiments/plot_simulation_results.py b/experiments/plot_simulation_results.py index 69016c0..6a1d42b 100644 --- a/experiments/plot_simulation_results.py +++ b/experiments/plot_simulation_results.py @@ -1,4 +1,4 @@ -from experiments_csv import single_plot_results, multi_plot_results +from experiments_csv.plot_results import single_plot_results, multi_plot_results from matplotlib import pyplot as plt from pathlib import Path import sys diff --git a/experiments/results/course_allocation_szws.csv b/experiments/results/course_allocation_szws.csv index 20796b4..2ee6df8 100644 --- a/experiments/results/course_allocation_szws.csv +++ b/experiments/results/course_allocation_szws.csv @@ -611,7 +611,7 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_adjusted,2,87.23331541126743,77.03703703703704,5.275779376498804,0.4210944488964777,0,0.0,100,100,100,0.2146076000062748 100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_adjusted,3,87.16314624171262,77.47368421052632,4.347826086956516,0.2611163542740706,0,0.0,100,100,100,0.2161804999923333 100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_adjusted,4,87.66739407907521,73.84615384615385,5.599999999999994,0.2110422707023697,0,0.0,100,100,100,0.2121457000030204 -100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",serial_dictatorship,0,79.92581810373112,44.534412955465584,55.06072874493927,18.183652343792154,0,0.0,45,47,47,0.027460399956908 +100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",serial_dictatorship,0,79.92581810373112,44.534412955465584,55.06072874493927,18.18365234379215,0,0.0,45,47,47,0.027460399956908 100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",serial_dictatorship,1,80.64277408816763,48.49699398797595,49.09819639278557,17.344076401247534,0,0.0,47,49,50,0.0277321999892592 100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",serial_dictatorship,2,79.01526838881641,50.50301810865191,46.55963302752294,18.99785806429092,0,0.0,44,44,45,0.0268275000271387 100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",serial_dictatorship,3,78.90221255399143,46.98544698544699,53.01455301455301,19.03925124586916,0,0.0,44,46,48,0.0276876999996602 @@ -749,12 +749,12 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,0,90.64582776035242,73.46491228070175,19.293478260869577,1.4420407001051323,0,0.0,175,185,193,8.440132599964272 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,1,90.24369067059376,75.054704595186,12.206572769953056,1.3667400676399994,0,0.0,182,187,198,8.396355000033509 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,2,89.79748226078272,75.92592592592592,11.851851851851862,1.0331168925759402,0,0.0,183,188,197,8.12680830003228 -200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,3,90.04721638041038,75.16483516483517,19.137466307277634,1.4900341053752053,0,0.0,178,185,194,8.694806899991818 +200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,3,90.04721638041038,75.16483516483517,19.13746630727763,1.4900341053752053,0,0.0,178,185,194,8.694806899991818 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,4,90.19910079261358,74.64454976303317,17.77251184834124,1.763108560326778,0,0.0,182,185,196,8.081291999958921 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,0,90.72573988206744,75.9656652360515,19.293478260869577,1.3423960850872674,0,0.0,178,187,196,8.40496549999807 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,1,90.26741503877278,75.054704595186,12.206572769953056,1.1042986967766912,0,0.0,186,192,200,8.061324000009336 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,2,89.69651767945632,75.92592592592592,12.619047619047606,1.4726684296522752,0,0.0,183,188,198,8.391139699961059 -200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,3,90.1245346122803,75.16483516483517,19.137466307277634,1.2986605478008584,0,0.0,179,188,196,8.422776499995962 +200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,3,90.1245346122803,75.16483516483517,19.13746630727763,1.2986605478008584,0,0.0,179,188,196,8.422776499995962 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,4,90.28858711379073,75.69060773480662,16.022099447513824,1.510042593673469,0,0.0,180,185,196,8.111415999999736 200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,0,83.20345185590914,58.17307692307693,30.64935064935065,6.428372317874204,0,0.0,159,161,161,0.2817154000513255 200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,1,82.76437925391814,60.31331592689296,31.55080213903743,7.012085267643042,0,0.0,160,163,163,0.2724572999868542 @@ -1259,7 +1259,7 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",round_robin,0,81.35905406575732,60.23622047244095,14.024390243902443,3.273984147439857,0,0.0,300,300,300,0.1745009999722242 300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",round_robin,1,81.67317635835407,61.34969325153374,12.239583333333345,2.657560450673265,0,0.0,300,300,300,0.156711500021629 300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",round_robin,2,81.27020447022414,54.88454706927176,13.807531380753147,2.999016253584066,0,0.0,300,300,300,0.1544938999577425 -300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",round_robin,3,81.49755130397739,60.23166023166024,14.726840855106886,2.6883085827499054,0,0.0,300,300,300,0.1605463000014424 +300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",round_robin,3,81.49755130397739,60.23166023166024,14.726840855106886,2.688308582749906,0,0.0,300,300,300,0.1605463000014424 300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",round_robin,4,81.59937514999777,63.16872427983539,14.613778705636747,2.799636801825676,0,0.0,300,300,300,0.1634619000251405 300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",bidirectional_round_robin,0,81.44866571926562,60.526315789473685,13.483146067415731,2.7992817677178228,0,0.0,300,300,300,0.1725431000231765 300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",bidirectional_round_robin,1,81.48735041306327,62.903225806451616,15.324675324675312,2.949576467117935,0,0.0,300,300,300,0.1556535999989137 @@ -1320,7 +1320,7 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",utilitarian_matching,1,88.80604695843394,68.66096866096866,23.34293948126802,3.020692392053071,0,0.0,284,285,285,0.4751030000043101 300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",utilitarian_matching,2,88.44354735144022,64.43298969072166,26.030927835051543,3.2998834601480755,0,0.0,285,286,286,0.4610299000050872 300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",utilitarian_matching,3,88.60071496242416,62.05962059620597,28.57142857142857,3.177566119801358,0,0.0,280,284,284,0.4527616999694146 -300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",utilitarian_matching,4,89.19108147813999,71.82044887780549,24.01215805471124,2.7363607123804154,0,0.0,290,291,291,0.4558134999824688 +300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",utilitarian_matching,4,89.19108147813999,71.82044887780549,24.01215805471124,2.736360712380415,0,0.0,290,291,291,0.4558134999824688 300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,0,87.45616277995683,75.50607287449392,5.747126436781599,0.0354121278922374,0,0.0,300,300,300,0.8202729999902658 300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,1,88.08104253988792,74.29193899782135,2.6627218934911383,0.020688507910166,0,0.0,300,300,300,0.8117884999956004 300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,2,87.88223265040256,74.33808553971487,6.510416666666686,0.0463849659657937,0,0.0,300,300,300,0.8074428999680094 @@ -1415,7 +1415,7 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",serial_dictatorship,1,77.56961004192186,44.57831325301205,55.42168674698795,21.31401764623935,0,0.0,114,117,120,0.1540481999982148 300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",serial_dictatorship,2,76.86052387010628,36.234458259325045,63.76554174067496,21.91793710725471,0,0.0,114,117,121,0.1586207000073045 300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",serial_dictatorship,3,76.90751740618062,43.43629343629344,55.01930501930502,21.89193705677892,0,0.0,112,117,119,0.1616813999717123 -300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",serial_dictatorship,4,77.18302113108365,45.601436265709154,52.96229802513466,21.817956185439414,0,0.0,111,115,117,0.1619396000169217 +300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",serial_dictatorship,4,77.18302113108365,45.601436265709154,52.96229802513466,21.817956185439417,0,0.0,111,115,117,0.1619396000169217 300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",round_robin,0,83.29878319142645,60.43307086614173,14.357682619647363,3.037376608813323,0,0.0,300,300,300,0.1561790000414475 300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",round_robin,1,83.71370709936522,61.34969325153374,12.100456621004568,2.635782802965322,0,0.0,300,300,300,0.1619039000361226 300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",round_robin,2,83.354070981459,54.88454706927176,13.854351687388984,2.7591734844615186,0,0.0,300,300,300,0.164955899992492 @@ -1555,7 +1555,7 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,0,88.14809321508368,70.1657458563536,25.138121546961315,5.306000990493448,0,0.0,281,281,281,0.4348004999919794 300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,1,88.08821245989738,67.02702702702703,27.669902912621367,6.118149890402151,0,0.0,277,280,281,0.4211376999737695 300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,2,87.84597830742086,70.40816326530613,24.48979591836735,6.158583687542496,0,0.0,282,282,282,0.4292453000089153 -300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,3,87.97835977508856,66.66666666666666,28.645833333333314,5.115348650322014,0,0.0,284,287,287,0.4345547999837436 +300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,3,87.97835977508856,66.66666666666666,28.64583333333331,5.115348650322014,0,0.0,284,287,287,0.4345547999837436 300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,4,88.1938001637918,70.39999999999999,25.714285714285708,5.454859657719756,0,0.0,285,287,287,0.4555450999760069 300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,0,87.79489925136302,74.80314960629921,7.008086253369271,0.3873185588128168,0,0.0,300,300,300,0.841491799976211 300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,1,87.82368907274545,75.73529411764706,8.469945355191257,0.5776010094910686,0,0.0,300,300,300,0.8699599000392482 @@ -2170,12 +2170,12 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,0,90.64582776035242,73.46491228070175,19.293478260869577,1.4420407001051323,0,0.0,175,185,193,8.127196700021159 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,1,90.24369067059376,75.054704595186,12.206572769953056,1.3667400676399994,0,0.0,182,187,198,7.740226300025824 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,2,89.79748226078272,75.92592592592592,11.851851851851862,1.0331168925759402,0,0.0,183,188,197,7.922589100024197 -200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,3,90.04721638041038,75.16483516483517,19.137466307277634,1.4900341053752053,0,0.0,178,185,194,7.85639930004254 +200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,3,90.04721638041038,75.16483516483517,19.13746630727763,1.4900341053752053,0,0.0,178,185,194,7.85639930004254 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,4,90.19910079261358,74.64454976303317,17.77251184834124,1.763108560326778,0,0.0,182,185,196,7.861788699985482 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,0,90.72573988206744,75.9656652360515,19.293478260869577,1.3423960850872674,0,0.0,178,187,196,7.982699500047602 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,1,90.26741503877278,75.054704595186,12.206572769953056,1.1042986967766912,0,0.0,186,192,200,7.997166299959645 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,2,89.69651767945632,75.92592592592592,12.619047619047606,1.4726684296522752,0,0.0,183,188,198,8.033370300021488 -200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,3,90.1245346122803,75.16483516483517,19.137466307277634,1.2986605478008584,0,0.0,179,188,196,7.979367499996442 +200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,3,90.1245346122803,75.16483516483517,19.13746630727763,1.2986605478008584,0,0.0,179,188,196,7.979367499996442 200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,4,90.28858711379073,75.69060773480662,16.022099447513824,1.510042593673469,0,0.0,180,185,196,7.938216399983503 200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,0,83.20345185590914,58.17307692307693,30.64935064935065,6.428372317874204,0,0.0,159,161,161,0.2690136999590322 200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,1,82.76437925391814,60.31331592689296,31.55080213903743,7.012085267643042,0,0.0,160,163,163,0.267133500019554 @@ -2199,7 +2199,7 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",serial_dictatorship,4,75.49080112948269,42.85714285714285,55.77299412915851,22.738917677269704,0,0.0,66,67,68,0.080289100005757 200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",round_robin,0,81.62682300348021,63.73390557939914,14.024390243902443,2.474136882189849,0,0.0,200,200,200,0.0795854000025428 200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",round_robin,1,81.59822682702452,62.903225806451616,12.177985948477756,2.170413927707856,0,0.0,200,200,200,0.0777533999644219 -200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",round_robin,2,80.59034266308349,54.88454706927176,12.5,2.3435672279809934,0,0.0,200,200,200,0.0791170999873429 +200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",round_robin,2,80.59034266308349,54.88454706927176,12.5,2.343567227980994,0,0.0,200,200,200,0.0791170999873429 200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",round_robin,3,81.23036762475293,60.23166023166024,12.471655328798192,2.133904673590093,0,0.0,200,200,200,0.0783901999820955 200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",round_robin,4,81.6851109624728,61.839530332681015,11.645569620253156,2.323603285472848,0,0.0,200,200,200,0.0790565000497736 200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",bidirectional_round_robin,0,81.68856509430388,60.526315789473685,13.064133016627096,2.301991074117542,0,0.0,200,200,200,0.0792468999861739 @@ -2741,7 +2741,7 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",utilitarian_matching,1,88.80604695843394,68.66096866096866,23.34293948126802,3.020692392053071,0,0.0,284,285,285,0.4740567000117153 300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",utilitarian_matching,2,88.44354735144022,64.43298969072166,26.030927835051543,3.2998834601480755,0,0.0,285,286,286,0.4650993999675847 300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",utilitarian_matching,3,88.60071496242416,62.05962059620597,28.57142857142857,3.177566119801358,0,0.0,280,284,284,0.4464365999447182 -300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",utilitarian_matching,4,89.19108147813999,71.82044887780549,24.01215805471124,2.7363607123804154,0,0.0,290,291,291,0.4519039000151679 +300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",utilitarian_matching,4,89.19108147813999,71.82044887780549,24.01215805471124,2.736360712380415,0,0.0,290,291,291,0.4519039000151679 300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,0,87.45616277995683,75.50607287449392,5.747126436781599,0.0354121278922374,0,0.0,300,300,300,0.8181213999632746 300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,1,88.08104253988792,74.29193899782135,2.6627218934911383,0.020688507910166,0,0.0,300,300,300,0.8008617000305094 300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,2,87.88223265040256,74.33808553971487,6.510416666666686,0.0463849659657937,0,0.0,300,300,300,0.8147079999907874 @@ -2844,7 +2844,7 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",round_robin,4,83.68173562358432,64.27289048473968,14.072494669509595,2.427767331988216,0,0.0,300,300,300,0.1663105000043288 300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",bidirectional_round_robin,0,83.4024304230496,60.526315789473685,13.738738738738732,2.513971801550541,0,0.0,300,300,300,0.1606157000060193 300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",bidirectional_round_robin,1,83.5197545870574,62.903225806451616,15.324675324675312,2.55950449556267,0,0.0,300,300,300,0.1595395000185817 -300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",bidirectional_round_robin,2,83.07904408143345,62.95503211991434,15.848214285714292,2.6396068995489754,0,0.0,300,300,300,0.1611472999793477 +300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",bidirectional_round_robin,2,83.07904408143345,62.95503211991434,15.848214285714292,2.639606899548975,0,0.0,300,300,300,0.1611472999793477 300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",bidirectional_round_robin,3,83.34660807917858,60.23166023166024,13.84615384615384,2.748267028670773,0,0.0,300,300,300,0.1623632000409998 300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",bidirectional_round_robin,4,83.53688883346652,61.839530332681015,14.988290398126452,2.6210589031490854,0,0.0,300,300,300,0.1640336000127717 300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",almost_egalitarian_without_donation,0,84.52230807691095,70.31630170316302,20.044543429844097,3.161737361691262,0,0.0,280,284,284,13.138180200010538 @@ -2980,7 +2980,7 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,0,88.14809321508368,70.1657458563536,25.138121546961315,5.306000990493448,0,0.0,281,281,281,0.4108474000240676 300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,1,88.08821245989738,67.02702702702703,27.669902912621367,6.118149890402151,0,0.0,277,280,281,0.4076311999815516 300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,2,87.84597830742086,70.40816326530613,24.48979591836735,6.158583687542496,0,0.0,282,282,282,0.4098905000137165 -300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,3,87.97835977508856,66.66666666666666,28.645833333333314,5.115348650322014,0,0.0,284,287,287,0.4211993000353686 +300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,3,87.97835977508856,66.66666666666666,28.64583333333331,5.115348650322014,0,0.0,284,287,287,0.4211993000353686 300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",utilitarian_matching,4,88.1938001637918,70.39999999999999,25.714285714285708,5.454859657719756,0,0.0,285,287,287,0.4110549999750219 300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,0,87.79489925136302,74.80314960629921,7.008086253369271,0.3873185588128168,0,0.0,300,300,300,1.1339660999947228 300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,1,87.82368907274545,75.73529411764706,8.469945355191257,0.5776010094910686,0,0.0,300,300,300,0.8110597000340931 @@ -3098,6 +3098,194 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 300,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,3,94.4752559892894,83.48214285714286,9.050772626931575,0.9005964772161119,0,0.0,298,300,300,12.719845000014177 300,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",almost_egalitarian_with_donation,4,94.76965154539184,86.4693446088795,11.200000000000005,0.7632502270457473,0,0.0,300,300,300,12.896742700017056 100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",utilitarian_matching,0,91.01465052092666,75.58441558441558,19.61325966850829,1.6565634869489474,0,0.0,85,87,95,0.4999400000087917 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",utilitarian_matching,1,90.46266823624111,72.77777777777777,13.63636363636364,1.5098292614546187,0,0.0,83,84,91,0.5025423000333831 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",utilitarian_matching,2,90.6613935562088,74.71264367816092,15.34772182254197,1.1566266260879317,0,0.0,85,86,95,0.4105012000072747 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",utilitarian_matching,3,90.54056073413524,73.48066298342542,23.180592991913755,1.534518839391132,0,0.0,88,88,93,0.421102299937047 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",utilitarian_matching,4,90.90706955039724,77.92553191489363,17.72486772486772,1.2599697463498043,0,0.0,86,86,93,0.4198713999940082 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,0,90.6980094489252,73.91304347826086,4.926108374384242,0.2530781252975517,0,0.0,100,100,100,0.7979893999872729 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,1,90.05898169298018,75.75057736720554,7.653061224489789,0.2810958493639138,0,0.0,98,100,100,0.9945702999830246 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,2,90.31369025023268,76.63755458515283,4.092071611253203,0.2459238100682138,0,0.0,100,100,100,0.7193849000614136 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,3,90.17477726567944,76.06837606837607,6.43564356435644,0.2710227691975734,0,0.0,100,100,100,0.7424426999641582 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,0,90.72156673529481,73.2843137254902,20.994475138121558,1.7904914100499423,0,0.0,85,86,93,0.027799916999999397 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,1,89.98177319780805,58.69017632241813,24.181360201511332,2.6967552860879165,0,0.0,81,81,87,0.0279667090000002 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,2,90.43072191102038,68.84816753926701,13.694267515923556,1.422076398896337,0,0.0,85,87,95,0.0272316659999996 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,3,90.28253496588115,73.31536388140162,25.067385444743934,1.871637477119908,0,0.0,89,89,94,0.028051624999999802 +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,4,90.64597455513785,64.32432432432432,18.037135278514597,1.9324308491571938,0,0.0,84,84,91,0.028688791000000435 +100,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,0,82.66585182306596,54.589371980676326,35.42713567839195,7.338053536260713,0,0.0,78,78,78,0.028161790999999603 +100,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,1,81.8167136025603,45.622119815668206,29.03225806451612,6.863768207701404,0,0.0,76,77,77,0.028188375000000043 +100,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,2,81.52926886482163,55.932203389830505,32.83208020050126,6.409261764404241,0,0.0,77,78,78,0.0278299999999998 +100,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,3,81.8340061109915,56.26477541371159,28.841607565011813,5.433459309929131,0,0.0,82,83,84,0.027699709000000183 +100,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,4,82.50055691757665,54.739336492891,32.3076923076923,6.857248922619488,0,0.0,76,77,77,0.027735957999999172 +100,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,0,94.63358305482339,77.95698924731182,11.282051282051285,0.6007524513122828,0,0.0,95,96,100,0.027702542000000108 +100,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,1,95.01308533505582,78.33827893175074,9.792284866468847,0.37948913520218325,0,0.0,98,98,99,0.02775008399999912 +100,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,2,95.45471580521,81.08108108108108,11.1111111111111,0.5392621979487123,0,0.0,97,98,99,0.027803583000000742 +100,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,3,94.90544740317542,72.40437158469946,9.401709401709397,0.5862377370281538,0,0.0,94,96,98,0.028400541999999973 +100,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,4,94.64530605608427,72.51908396946564,16.284987277353693,0.4448399590616637,0,0.0,96,98,98,0.02800124999999909 +100,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,0,87.96365067788916,61.42131979695431,26.142131979695435,2.7836341117531225,0,0.0,95,95,96,0.027539084000000713 +100,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,1,88.23221560804623,67.01570680628272,20.420420420420427,2.682273074815894,0,0.0,93,93,93,0.02937383300000107 +100,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,2,88.68691458569191,61.684782608695656,24.456521739130437,2.916455394929703,0,0.0,94,94,94,0.027651291999999827 +100,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,3,87.9830220111561,62.43523316062176,21.761658031088075,2.4117607038223126,0,0.0,93,94,94,0.027979250000001343 +100,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,4,88.07460561933624,57.97872340425532,34.308510638297875,2.6420142196522103,0,0.0,92,94,94,0.028213125000000616 +100,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,0,92.75048697198305,75.58441558441558,19.61325966850829,1.5711734549903644,0,0.0,89,90,96,0.02742966599999974 +100,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,1,92.31769726871872,72.77777777777777,14.619883040935662,1.3394122571723241,0,0.0,90,90,95,0.027753999999999834 +100,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,2,92.30344442631893,74.71264367816092,13.694267515923556,1.1782621379315714,0,0.0,89,91,97,0.027020874999999833 +100,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,3,92.28900125557318,74.05405405405405,19.729729729729726,1.5556942403663205,0,0.0,92,92,97,0.027323334000000088 +100,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,4,92.55107410782068,66.84350132625994,17.72486772486772,1.4176076897646503,0,0.0,88,88,92,0.028229957999998945 +100,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,0,85.03016167673759,63.661202185792355,26.502732240437147,5.688215245250344,0,0.0,84,87,87,0.027442082999998618 +100,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,1,84.144502816491,60.313315926892955,24.8041775456919,5.710896800252035,0,0.0,81,82,82,0.027330708000000925 +100,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,2,83.88611609725702,55.932203389830505,32.83208020050126,4.897499293215965,0,0.0,85,86,86,0.027644624999998868 +100,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,3,83.98801162215221,64.45012787723785,23.561643835616437,5.054415397961204,0,0.0,88,89,89,0.027115624999998644 +100,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,4,84.72878112571179,57.24815724815725,27.179487179487168,5.561693848391156,0,0.0,86,86,86,0.027476291999999347 +100,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,0,96.46432164774225,81.02564102564102,10.256410256410263,0.3102410683317578,0,0.0,97,100,100,0.027201375000000638 +100,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,1,96.84779569038933,81.23324396782841,5.524861878453052,0.18684537763072556,0,0.0,100,100,100,0.027491334000000478 +100,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,2,97.26819995703731,81.08108108108108,7.386363636363626,0.22145191692588825,0,0.0,99,99,99,0.027682916999999918 +100,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,3,96.84077751645361,82.03592814371258,11.077844311377234,0.24840203766242852,0,0.0,96,98,100,0.027544040999998742 +100,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,4,96.54003201584514,82.70440251572327,8.620689655172413,0.22039301381586895,0,0.0,98,99,99,0.027338874999999874 +100,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,0,90.45541253664837,72.13541666666666,22.65625,2.158770420247992,0,0.0,99,100,100,0.027812458000001428 +100,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,1,90.8862013247948,69.12568306010928,15.217391304347814,1.7602233823546256,0,0.0,95,96,96,0.02766708300000076 +100,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,2,91.16242269657297,71.2166172106825,21.66172106824925,2.7931485168784156,0,0.0,96,97,97,0.027872166999999948 +100,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,3,90.5831763695686,69.73684210526315,19.43661971830987,2.2099960500940883,0,0.0,96,97,97,0.028773708000001008 +100,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,4,90.64250536842434,60.1063829787234,32.18085106382979,1.9459646012636496,0,0.0,94,95,95,0.027745375000000294 +100,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,0,95.40181792095802,78.63013698630137,13.69863013698631,0.740813739203665,0,0.0,94,96,98,0.026979083000000514 +100,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,1,95.06887289921613,73.61111111111111,16.66666666666667,0.9222588663010808,0,0.0,97,97,99,0.027076416999999964 +100,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,2,94.92569509598312,75.78347578347578,19.65811965811966,0.9358372293150219,0,0.0,93,93,97,0.02718245800000041 +100,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,3,94.86261460768662,81.84281842818429,13.178294573643399,1.0617920271269197,0,0.0,97,97,99,0.027014624999999626 +100,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,4,95.21202013155579,81.86968838526913,8.547008547008545,0.5845767978247514,0,0.0,95,96,98,0.02752066699999922 +100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,0,88.20574737002622,69.38775510204081,28.50122850122851,4.4293686580478635,0,0.0,90,90,90,0.027198084000000122 +100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,1,87.37359861472372,60.313315926892955,29.144385026737964,5.773970876087837,0,0.0,86,86,86,0.027194291000000703 +100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,2,87.17489152544341,64.84375,27.34375,3.1927549928430925,0,0.0,92,93,93,0.027526959000001128 +100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,3,87.2872661799857,66.3265306122449,23.52941176470587,4.6424319638103135,0,0.0,92,93,93,0.027611959000001463 +100,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,4,87.87552548451107,57.24815724815725,29.2191435768262,4.530247758117406,0,0.0,91,91,91,0.027925375000000585 +100,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,0,98.56431171510249,87.24373576309794,2.564102564102569,0.03310371220818993,0,0.0,100,100,100,0.02715454099999981 +100,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,1,98.8223934817559,85.38681948424069,9.742120343839545,0.16361958497691376,0,0.0,100,100,100,0.027165666000000144 +100,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,2,98.99533699353738,85.47008547008546,1.4970059880239432,0.034933265926380984,0,0.0,100,100,100,0.027267500000000666 +100,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,3,98.91647151774734,93.86189258312021,4.347826086956516,0.07713210702341129,0,0.0,100,100,100,0.02845275000000136 +100,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,4,98.41057857681619,87.69633507853402,8.620689655172413,0.1787320196016708,0,0.0,99,100,100,0.027232999999998952 +100,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,0,93.9493671210059,78.4090909090909,13.903743315508024,0.9342229513360849,0,0.0,100,100,100,0.027483458000000738 +100,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,1,94.31077797775983,72.48520710059172,17.15976331360946,1.0930796526391888,0,0.0,98,98,98,0.027860875000000007 +100,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,2,94.39315412957842,71.2166172106825,21.66172106824925,1.3755501858495252,0,0.0,99,99,99,0.027979832999999843 +100,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,3,93.97726281685145,80.0,12.911392405063296,1.1226759950618304,0,0.0,97,99,99,0.02750450000000093 +100,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,4,94.17750110270138,75.98784194528876,24.012158054711236,1.388537526313172,0,0.0,98,98,98,0.0273211670000002 +200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,0,90.8390263005807,63.75661375661375,27.513227513227513,2.746730615271309,0,0.0,165,168,181,0.08140633300000033 +200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,1,90.32750899337465,61.942257217847775,30.708661417322823,3.4869578816047238,0,0.0,163,165,178,0.08445579199999997 +200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,2,89.96325246921678,68.26666666666667,22.383720930232556,2.712791261730178,0,0.0,167,167,182,0.08070325000000089 +200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,3,90.39351887151764,70.22332506203473,23.495702005730664,2.766277099187564,0,0.0,173,175,186,0.0811603329999997 +200,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,4,90.52787163695672,65.67567567567568,23.342175066313004,2.822473191445715,0,0.0,170,170,183,0.08159112499999921 +200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,0,82.77626419832188,55.47445255474452,34.0632603406326,8.38014094097915,0,0.0,152,153,153,0.08354450000000035 +200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,1,82.34043032913237,57.180156657963444,36.06965174129355,8.910044637786207,0,0.0,154,156,156,0.08350641700000061 +200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,2,81.32836096187677,52.300242130750604,44.55205811138015,10.517173859923725,0,0.0,150,152,152,0.08121558299999876 +200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,3,82.17603542069283,56.26477541371159,32.336956521739125,6.78866182469445,0,0.0,166,166,167,0.08101583400000045 +200,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,4,82.66909327504814,57.24815724815725,39.27648578811369,7.8167392018349195,0,0.0,151,151,151,0.08100308400000067 +200,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,0,94.9303588123961,76.94704049844236,12.990196078431381,0.7191421294258634,0,0.0,194,195,198,0.08115237500000028 +200,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,1,95.20853122575662,75.0,15.294117647058826,0.7130014048256927,0,0.0,194,197,199,0.08150670800000093 +200,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,2,95.34742965184232,78.71148459383754,14.285714285714278,0.6152701497177295,0,0.0,195,195,196,0.08044508400000083 +200,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,3,94.95378332441847,69.45945945945947,19.729729729729726,1.0876623418671794,0,0.0,189,193,194,0.08068112499999991 +200,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,4,95.30451049212363,72.15568862275448,14.0625,0.734851271739029,0,0.0,194,195,196,0.08176691700000127 +200,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,0,88.07108769257566,59.375,26.142131979695435,4.001019856693276,0,0.0,192,192,192,0.08195608299999968 +200,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,1,88.32128088377978,67.35751295336787,19.786096256684502,3.2959414781144,0,0.0,188,188,188,0.08267829100000057 +200,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,2,88.5370710987103,61.684782608695656,26.956521739130423,3.454529463568198,0,0.0,189,189,189,0.08061012500000153 +200,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,3,87.95220685822332,63.69047619047619,28.27380952380952,3.975640290922594,0,0.0,186,188,189,0.08071537500000048 +200,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,4,89.03687792585659,64.91228070175438,24.012158054711236,2.740700496989423,0,0.0,190,191,191,0.08272908300000026 +200,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,0,92.76929087387373,64.81481481481481,26.455026455026456,1.7769815132385123,0,0.0,179,181,190,0.0836951250000002 +200,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,1,92.34448433273205,67.86632390745501,23.65038560411311,2.4690971829255606,0,0.0,175,178,190,0.08293841699999938 +200,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,2,91.97059801083203,74.71264367816092,22.383720930232556,2.236586469575546,0,0.0,176,178,190,0.08053762499999984 +200,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,3,92.32659972063844,73.48066298342542,19.729729729729726,1.9650903043707606,0,0.0,183,184,191,0.0799874169999999 +200,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,4,92.43631795183781,66.84350132625994,23.342175066313004,2.280586230743207,0,0.0,179,179,189,0.08333608300000073 +200,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,0,85.06305373245414,55.961070559610704,33.57664233576642,6.738744346776759,0,0.0,167,169,169,0.08127379099999921 +200,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,1,84.4313827893888,60.313315926892955,36.06965174129355,8.633280102979104,0,0.0,160,163,163,0.08112433299999999 +200,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,2,83.64763560342452,59.33503836317136,32.83208020050126,8.66104539109626,0,0.0,164,166,166,0.08010516699999926 +200,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,3,84.29692285939076,62.77173913043478,33.5195530726257,6.345514555625301,0,0.0,177,177,178,0.07985812499999945 +200,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,4,84.77517759685563,57.24815724815725,39.27648578811369,7.345778318816977,0,0.0,162,162,162,0.08135008299999846 +200,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,0,96.81577377398429,76.94704049844236,14.953271028037392,0.4333113028893472,0,0.0,199,199,200,0.08077962499999991 +200,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,1,96.8258650535444,79.94350282485875,12.13720316622691,0.4626044770568084,0,0.0,197,199,200,0.08094854199999979 +200,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,2,97.1150636249611,80.39702233250621,11.6279069767442,0.4371968153120116,0,0.0,197,197,198,0.08035395799999989 +200,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,3,96.87664055032961,79.94011976047905,17.664670658682624,0.47145038699342867,0,0.0,196,198,199,0.08107479099999892 +200,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,4,97.02072026844893,82.63473053892216,8.620689655172413,0.3335849275676764,0,0.0,198,199,199,0.08029858299999937 +200,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,0,90.65517397209514,69.67213114754098,21.823204419889507,3.0390619445391764,0,0.0,196,196,196,0.08131750000000082 +200,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,1,90.78234447507397,67.80104712041884,20.370370370370367,2.928417721511945,0,0.0,191,191,191,0.0808099999999996 +200,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,2,91.05842498882616,64.43298969072166,26.956521739130423,2.749743640661751,0,0.0,192,193,193,0.08096624999999946 +200,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,3,90.46864169197126,64.58333333333334,27.380952380952365,3.0037768944765064,0,0.0,192,194,194,0.08104970800000011 +200,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,4,91.33678968832199,71.62162162162163,24.012158054711236,2.0096026535454734,0,0.0,195,195,195,0.08277629200000014 +200,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,0,95.5129819835323,79.53216374269006,12.87128712871288,0.7663415223927488,0,0.0,191,195,198,0.08029179200000058 +200,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,1,95.15676419061687,73.61111111111111,16.717325227963514,1.0260536173131638,0,0.0,189,190,196,0.08025758299999985 +200,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,2,94.86458648100954,75.78347578347578,19.65811965811966,1.326608165208296,0,0.0,188,189,195,0.08057633299999978 +200,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,3,94.92459681658255,74.05405405405405,19.729729729729726,1.278829537799991,0,0.0,190,191,194,0.07996504099999946 +200,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,4,95.17605243042556,77.03488372093024,17.759562841530055,1.1575013707410355,0,0.0,187,187,195,0.0812066660000017 +200,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,0,88.32279597521723,60.73298429319372,33.50785340314136,5.3110565736806015,0,0.0,180,181,181,0.08053649999999912 +200,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,1,87.66128901492677,60.313315926892955,36.06965174129355,6.600389887382716,0,0.0,177,179,179,0.0817404169999989 +200,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,2,87.05234909570564,64.84375,28.79464285714286,6.571038320789221,0,0.0,183,183,183,0.08013062500000068 +200,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,3,87.55600492864927,62.77173913043478,33.5195530726257,5.668633978932357,0,0.0,189,189,189,0.0811440000000001 +200,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,4,87.94119121082973,57.36434108527132,39.27648578811369,6.422448133076156,0,0.0,181,181,182,0.0813166669999994 +200,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,0,98.82419344112306,89.87730061349694,5.384615384615387,0.0846270455828853,0,0.0,200,200,200,0.08161183400000027 +200,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,1,98.74667320413289,87.82608695652175,9.275362318840564,0.13830116348225865,0,0.0,200,200,200,0.08039154200000098 +200,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,2,99.08897378711941,92.02279202279202,3.225806451612897,0.03620652052792721,0,0.0,200,200,200,0.08038670799999892 +200,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,3,98.87727281181458,89.65517241379311,6.51558073654391,0.06718176483289064,0,0.0,200,200,200,0.08169795799999946 +200,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,4,98.89963275932615,90.70422535211267,8.620689655172413,0.11346038456970434,0,0.0,200,200,200,0.08089574999999982 +200,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,0,94.24862121125308,75.8530183727034,16.535433070866148,1.502960211714369,0,0.0,199,200,200,0.08092800000000011 +200,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,1,94.25620382106622,69.62750716332378,17.15976331360946,1.8466707115279137,0,0.0,196,196,196,0.08094304199999769 +200,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,2,94.4727848564491,74.71910112359551,17.69662921348315,1.4003942559256972,0,0.0,198,198,198,0.08234824999999901 +200,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,3,93.96593830468333,64.58333333333334,27.380952380952365,1.9685291517368144,0,0.0,195,196,196,0.08160258300000223 +200,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,4,94.61272964259673,73.47560975609755,21.34146341463415,1.6637261165952264,0,0.0,197,197,197,0.08122041700000082 +300,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,0,90.44383782677377,64.81481481481481,26.71957671957672,3.195590713183483,0,0.0,250,252,273,0.16102200000000266 +300,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,1,90.52410538393833,63.51706036745407,29.133858267716526,3.389494596954995,0,0.0,257,257,273,0.16072645900000282 +300,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,2,90.44606495834758,65.4696132596685,25.414364640883974,3.254018940217646,0,0.0,253,254,275,0.16075183299999907 +300,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,3,90.4483747318497,70.22332506203473,23.529411764705884,3.083340220547799,0,0.0,259,261,276,0.16204837500000124 +300,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",gale_shapley,4,90.41520510505673,65.67567567567568,23.342175066313004,3.407842189469743,0,0.0,251,252,275,0.1606474999999996 +300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,0,82.44852657912396,55.961070559610704,37.437185929648244,9.270176305027803,0,0.0,233,233,233,0.16256199999999765 +300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,1,82.47778997679353,57.291666666666664,31.64556962025317,9.324117119878089,0,0.0,236,239,240,0.20370179200000038 +300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,2,82.05728544656536,52.05811138014528,44.794188861985475,10.097739068681724,0,0.0,235,236,236,0.1614036669999983 +300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,3,82.37344755521146,54.54545454545454,33.492822966507184,7.374112738330614,0,0.0,248,248,249,0.16179870800000273 +300,25,5,1.1,6,3.85,"(50, 100)","(0, 50)",gale_shapley,4,82.66347617636784,55.582524271844655,39.27648578811369,8.996142179789377,0,0.0,231,231,231,0.16041033299999796 +300,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,0,94.91403796783541,75.49295774647888,18.181818181818187,0.9911430445491072,0,0.0,291,292,295,0.16378937500000035 +300,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,1,95.45167046189096,72.03389830508475,17.971014492753625,0.7976232869516525,0,0.0,294,295,296,0.16236766699999805 +300,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,2,95.26381529182099,68.18181818181817,21.590909090909093,0.9441127198228184,0,0.0,292,293,294,0.16246462499999836 +300,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,3,95.51230301617714,76.94524495677233,17.664670658682624,0.7942209768049835,0,0.0,288,295,297,0.1617934589999983 +300,25,5,1.1,9,2.6,"(50, 100)","(0, 50)",gale_shapley,4,95.25159726867464,72.15568862275448,19.46107784431139,0.8163094549597741,0,0.0,291,293,296,0.16354616600000327 +300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,0,87.72619970875195,57.34870317002881,37.17579250720462,4.4827615817243975,0,0.0,284,286,286,0.16468570900000046 +300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,1,88.52098204485767,62.33062330623306,29.268292682926834,3.8569741725294193,0,0.0,282,282,282,0.1629623339999995 +300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,2,88.09868715337988,61.684782608695656,29.041916167664667,4.4946682667998,0,0.0,281,281,281,0.163033875 +300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,3,88.34350893938175,62.05962059620597,28.57142857142857,4.38807430606958,0,0.0,279,281,282,0.1631934159999986 +300,25,5,1.1,9,3.85,"(50, 100)","(0, 50)",gale_shapley,4,88.95618487107225,60.099750623441395,29.639889196675895,3.338964430527342,0,0.0,287,287,287,0.1614157089999999 +300,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,0,92.43253074144991,64.81481481481481,26.71957671957672,2.340543437880036,0,0.0,270,271,284,0.16268541700000227 +300,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,1,92.48653436756564,71.23287671232876,22.1606648199446,2.3085307852201824,0,0.0,273,274,286,0.16184762500000005 +300,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,2,92.40698845250662,72.89156626506023,22.383720930232556,2.4000394204216953,0,0.0,266,268,283,0.16261733300000003 +300,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,3,92.29660347199452,72.06703910614524,20.949720670391073,2.2896360460165703,0,0.0,273,275,285,0.16068183399999825 +300,25,5,1.25,6,2.6,"(50, 100)","(0, 50)",gale_shapley,4,92.40835454873293,66.84350132625994,24.781341107871725,2.481944385390357,0,0.0,269,269,285,0.16019408400000046 +300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,0,84.59978709655405,55.961070559610704,33.57664233576642,8.069841263818864,0,0.0,248,249,249,0.16025312500000055 +300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,1,84.55360446823532,58.072916666666664,36.06965174129355,9.182313437725893,0,0.0,248,252,253,0.16428395799999862 +300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,2,84.2662475413897,61.111111111111114,33.41968911917098,8.4114131225523,0,0.0,253,254,254,0.16305291699999813 +300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,3,84.50118248786151,59.35960591133005,34.23913043478261,7.100772845647693,0,0.0,264,265,266,0.16378625000000113 +300,25,5,1.25,6,3.85,"(50, 100)","(0, 50)",gale_shapley,4,84.68685575243042,57.24815724815725,39.27648578811369,8.032190849727327,0,0.0,249,249,249,0.1612461670000016 +300,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,0,96.88917953082473,76.94704049844236,14.953271028037392,0.5426201695604249,0,0.0,294,296,297,0.16162941600000025 +300,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,1,97.2147876129128,83.89830508474576,7.317073170731703,0.33138667551725975,0,0.0,299,299,300,0.1760910000000031 +300,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,2,97.11853587692258,74.03846153846155,20.19230769230768,0.49966303600106243,0,0.0,296,297,298,0.16354033400000034 +300,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,3,97.28680970162445,79.94011976047905,17.664670658682624,0.4253110837983063,0,0.0,296,298,298,0.16299025 +300,25,5,1.25,9,2.6,"(50, 100)","(0, 50)",gale_shapley,4,96.98033040005713,72.15568862275448,19.46107784431139,0.47867882637949494,0,0.0,296,298,298,0.16049704099999929 +300,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,0,90.28714623205748,61.42131979695431,29.94923857868021,3.920422950276972,0,0.0,291,292,292,0.17779887500000058 +300,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,1,90.96172199812945,67.80104712041884,27.065527065527064,3.0369738609558823,0,0.0,285,285,285,0.16367654100000095 +300,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,2,90.65471648867259,66.26506024096386,28.020565552699225,3.6625025812539813,0,0.0,286,287,287,0.1620375420000002 +300,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,3,90.90471986294618,62.05962059620597,32.38341968911916,3.358793537579509,0,0.0,288,288,288,0.1624519169999985 +300,25,5,1.25,9,3.85,"(50, 100)","(0, 50)",gale_shapley,4,91.31824561154025,71.62162162162163,24.012158054711236,2.609185663605078,0,0.0,293,294,294,0.1616491670000002 +300,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,0,95.2139854186147,78.63013698630137,16.4179104477612,1.2961687618475615,0,0.0,287,290,296,0.16541291700000116 +300,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,1,95.10397228282979,79.93920972644378,16.717325227963514,1.4700018171678952,0,0.0,287,289,297,0.16145358300000012 +300,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,2,95.10870472627255,72.89156626506023,21.686746987951807,1.6175203537482188,0,0.0,280,282,289,0.16201112499999937 +300,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,3,94.93909835103311,74.85207100591717,16.949152542372886,1.5385485515626138,0,0.0,286,287,291,0.16116937500000006 +300,25,5,1.5,6,2.6,"(50, 100)","(0, 50)",gale_shapley,4,95.09499419468575,71.7201166180758,26.530612244897952,1.3906306154430097,0,0.0,282,282,293,0.16028204199999863 +300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,0,87.90069425150539,59.480519480519476,38.02083333333332,6.513893472097042,0,0.0,272,272,272,0.16119837500000145 +300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,1,87.84543358851109,60.313315926892955,36.06965174129355,7.0201492350802175,0,0.0,273,275,276,0.17168170900000135 +300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,2,87.55363683972142,62.43523316062176,33.67875647668393,7.349628496774373,0,0.0,273,273,273,0.20828220900000005 +300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,3,87.77004641726238,61.61879895561357,33.5195530726257,5.9728783159682814,0,0.0,284,285,285,0.22895349999999937 +300,25,5,1.5,6,3.85,"(50, 100)","(0, 50)",gale_shapley,4,87.85634005140113,57.24815724815725,39.31203931203931,7.255923918871748,0,0.0,275,276,276,0.17178516599999938 +300,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,0,98.92852384908214,90.38461538461539,6.997084548104951,0.08968962270290078,0,0.0,300,300,300,0.16837933300000074 +300,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,1,98.93790903952305,86.72086720867209,8.563535911602202,0.1668106007693046,0,0.0,300,300,300,0.21018583299999705 +300,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,2,99.0646902795822,92.02279202279202,4.3988269794721475,0.06475754798459121,0,0.0,300,300,300,0.16700037500000064 +300,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,3,99.05836562641296,93.06666666666666,3.6144578313252964,0.07248349819364279,0,0.0,300,300,300,0.16206649999999811 +300,25,5,1.5,9,2.6,"(50, 100)","(0, 50)",gale_shapley,4,98.89128860166431,87.25961538461539,7.042253521126767,0.15229296332505105,0,0.0,300,300,300,0.1950802920000001 +300,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,0,94.00395658087571,75.8530183727034,20.472440944881896,2.2091479186142124,0,0.0,298,299,299,0.18247233299999976 +300,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,1,94.45175145337782,72.48520710059172,26.851851851851848,1.9044658828285514,0,0.0,296,296,296,0.16143454199999852 +300,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,2,94.22928311594254,74.71910112359551,17.69662921348315,2.199458364420277,0,0.0,297,298,298,0.16202937499999948 +300,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,3,94.459835020266,64.58333333333334,30.95238095238095,2.072140162644666,0,0.0,295,296,296,0.16300058299999876 +300,25,5,1.5,9,3.85,"(50, 100)","(0, 50)",gale_shapley,4,94.6573449390455,73.71428571428571,21.42857142857143,1.7111197651192478,0,0.0,297,297,297,0.16252162500000011 100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",utilitarian_matching,1,90.46266823624113,72.77777777777777,13.63636363636364,1.5098292614546187,0,0.0,83,84,91,0.5025423000333831 100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",utilitarian_matching,2,90.66139355620881,74.71264367816092,15.34772182254197,1.1566266260879317,0,0.0,85,86,95,0.41050120000727475 100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",utilitarian_matching,3,90.54056073413525,73.48066298342542,23.180592991913755,1.534518839391132,0,0.0,88,88,93,0.42110229993704706 @@ -3105,4 +3293,4 @@ num_of_agents,num_of_items,agent_capacity,supply_ratio,num_of_popular_items,mean 100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,0,90.69800944892519,73.91304347826086,4.926108374384242,0.2530781252975517,0,0.0,100,100,100,0.7979893999872729 100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,1,90.05898169298018,75.75057736720554,7.6530612244897895,0.28109584936391385,0,0.0,98,100,100,0.9945702999830246 100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,2,90.31369025023268,76.63755458515283,4.092071611253203,0.24592381006821384,0,0.0,100,100,100,0.7193849000614136 -100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,3,90.17477726567944,76.06837606837607,6.43564356435644,0.27102276919757345,0,0.0,100,100,100,0.7424426999641582 \ No newline at end of file +100,25,5,1.1,6,2.6,"(50, 100)","(0, 50)",iterated_maximum_matching_unadjusted,3,90.17477726567944,76.06837606837607,6.43564356435644,0.27102276919757345,0,0.0,100,100,100,0.7424426999641582 diff --git a/experiments/results/course_allocation_szws_egalitarian_value.png b/experiments/results/course_allocation_szws_egalitarian_value.png new file mode 100644 index 0000000..e54ddf2 Binary files /dev/null and b/experiments/results/course_allocation_szws_egalitarian_value.png differ diff --git a/experiments/results/course_allocation_szws_max_deficit.png b/experiments/results/course_allocation_szws_max_deficit.png new file mode 100644 index 0000000..794545e Binary files /dev/null and b/experiments/results/course_allocation_szws_max_deficit.png differ diff --git a/experiments/results/course_allocation_szws_max_envy.png b/experiments/results/course_allocation_szws_max_envy.png new file mode 100644 index 0000000..9977dcf Binary files /dev/null and b/experiments/results/course_allocation_szws_max_envy.png differ diff --git a/experiments/results/course_allocation_szws_mean_deficit.png b/experiments/results/course_allocation_szws_mean_deficit.png new file mode 100644 index 0000000..2561bc8 Binary files /dev/null and b/experiments/results/course_allocation_szws_mean_deficit.png differ diff --git a/experiments/results/course_allocation_szws_mean_envy.png b/experiments/results/course_allocation_szws_mean_envy.png new file mode 100644 index 0000000..6420fb8 Binary files /dev/null and b/experiments/results/course_allocation_szws_mean_envy.png differ diff --git a/experiments/results/course_allocation_szws_num_with_top_1.png b/experiments/results/course_allocation_szws_num_with_top_1.png new file mode 100644 index 0000000..e81c975 Binary files /dev/null and b/experiments/results/course_allocation_szws_num_with_top_1.png differ diff --git a/experiments/results/course_allocation_szws_num_with_top_2.png b/experiments/results/course_allocation_szws_num_with_top_2.png new file mode 100644 index 0000000..73c0035 Binary files /dev/null and b/experiments/results/course_allocation_szws_num_with_top_2.png differ diff --git a/experiments/results/course_allocation_szws_num_with_top_3.png b/experiments/results/course_allocation_szws_num_with_top_3.png new file mode 100644 index 0000000..6c08855 Binary files /dev/null and b/experiments/results/course_allocation_szws_num_with_top_3.png differ diff --git a/experiments/results/course_allocation_szws_runtime.png b/experiments/results/course_allocation_szws_runtime.png new file mode 100644 index 0000000..5758fba Binary files /dev/null and b/experiments/results/course_allocation_szws_runtime.png differ diff --git a/experiments/results/course_allocation_szws_utilitarian_value.png b/experiments/results/course_allocation_szws_utilitarian_value.png new file mode 100644 index 0000000..1ef8abe Binary files /dev/null and b/experiments/results/course_allocation_szws_utilitarian_value.png differ diff --git a/experiments/results/course_allocation_uniform.csv b/experiments/results/course_allocation_uniform.csv index 9aa38bc..f1d6daa 100644 --- a/experiments/results/course_allocation_uniform.csv +++ b/experiments/results/course_allocation_uniform.csv @@ -219,7 +219,7 @@ num_of_agents,num_of_items,value_noise_ratio,algorithm,random_seed,utilitarian_v 200,25,0.0,serial_dictatorship,2,49.80459487053312,0.0,100.0,49.61030898868015,6,1.0,50,55,58,0.0610566000104881 200,25,0.0,serial_dictatorship,3,50.82567280607203,0.0,100.0,47.85266090045614,6,1.0,62,65,72,0.0627732999855652 200,25,0.0,serial_dictatorship,4,42.09615523908028,0.0,100.0,57.82713575227776,6,1.0,42,45,48,0.0623118000221438 -200,25,0.0,round_robin,0,55.39513387311314,40.78947368421053,22.139303482587074,6.471775918547442,1,1.0,146,184,200,0.0594282000092789 +200,25,0.0,round_robin,0,55.39513387311314,40.78947368421053,22.13930348258707,6.471775918547442,1,1.0,146,184,200,0.0594282000092789 200,25,0.0,round_robin,1,64.14445217482276,48.87780548628429,16.75392670157069,5.466047682529152,1,1.0,179,200,200,0.0657957999501377 200,25,0.0,round_robin,2,55.419251505453325,37.389380530973455,20.27649769585253,6.468798852967918,1,1.0,167,194,200,0.0718458999763242 200,25,0.0,round_robin,3,55.89998984651763,42.45283018867924,20.72072072072072,7.080802732839159,1,1.0,187,200,200,0.0724450999987311 @@ -422,7 +422,7 @@ num_of_agents,num_of_items,value_noise_ratio,algorithm,random_seed,utilitarian_v 300,25,0.0,round_robin,0,37.08461789017242,25.657894736842103,24.65437788018433,9.84131244722116,3,2.6666666666666665,156,222,274,0.1130971999955363 300,25,0.0,round_robin,1,43.05496940216578,30.423280423280424,20.43010752688172,7.734616878328352,3,2.6666666666666665,212,277,293,0.106700100004673 300,25,0.0,round_robin,2,37.05673020977912,24.16107382550336,23.07692307692308,8.065436124484494,3,2.6666666666666665,191,248,273,0.1072726999991573 -300,25,0.0,round_robin,3,37.27241794578104,25.476190476190474,20.14925373134328,8.91370823373532,3,2.6666666666666665,217,272,298,0.1071146000176668 +300,25,0.0,round_robin,3,37.27241794578104,25.47619047619047,20.14925373134328,8.91370823373532,3,2.6666666666666665,217,272,298,0.1071146000176668 300,25,0.0,round_robin,4,31.688928775480537,16.83366733466934,23.719165085389,8.243968694128311,3,2.6666666666666665,149,195,224,0.1071738000027835 300,25,0.0,bidirectional_round_robin,0,36.90936951633008,30.205949656750576,15.4228855721393,4.299837875049376,3,2.6666666666666665,156,222,274,0.1064907999825663 300,25,0.0,bidirectional_round_robin,1,42.77118596637503,31.56626506024096,12.938005390835578,3.2420014002393747,3,2.6666666666666665,212,277,293,0.1076494000153616 @@ -526,12 +526,12 @@ num_of_agents,num_of_items,value_noise_ratio,algorithm,random_seed,utilitarian_v 300,25,0.8,utilitarian_matching,4,41.28647169243629,0.0,86.80297397769516,31.330537628016657,6,2.6666666666666665,181,205,214,0.4148380000260658 300,25,0.8,iterated_maximum_matching_unadjusted,0,43.81537134205374,28.07017543859649,20.26022304832714,4.444621158950279,3,2.6666666666666665,213,286,297,0.5917126999702305 300,25,0.8,iterated_maximum_matching_unadjusted,1,49.40426460808358,37.47412008281574,15.306122448979586,2.2139330258947623,3,2.6666666666666665,270,297,300,0.5900283000082709 -300,25,0.8,iterated_maximum_matching_unadjusted,2,44.75781574373595,30.134357005758154,15.873015873015872,3.2812052776091467,3,2.6666666666666665,244,292,298,0.5868470999994315 +300,25,0.8,iterated_maximum_matching_unadjusted,2,44.75781574373595,30.13435700575815,15.873015873015872,3.2812052776091467,3,2.6666666666666665,244,292,298,0.5868470999994315 300,25,0.8,iterated_maximum_matching_unadjusted,3,43.37469843858028,30.9021113243762,15.355086372360848,3.960136147502308,3,2.6666666666666665,273,300,300,0.5893803000217304 300,25,0.8,iterated_maximum_matching_unadjusted,4,39.896490599797005,23.711340206185564,16.7910447761194,3.4178658537790656,3,2.6666666666666665,205,260,284,0.5838887999998406 300,25,0.8,iterated_maximum_matching_adjusted,0,43.81537134205374,28.07017543859649,20.26022304832714,4.444621158950279,3,2.6666666666666665,213,286,297,0.7939149999874644 300,25,0.8,iterated_maximum_matching_adjusted,1,49.40426460808358,37.47412008281574,15.306122448979586,2.2139330258947623,3,2.6666666666666665,270,297,300,0.6236257000127807 -300,25,0.8,iterated_maximum_matching_adjusted,2,44.75781574373595,30.134357005758154,15.873015873015872,3.2812052776091467,3,2.6666666666666665,244,292,298,0.5960176999797113 +300,25,0.8,iterated_maximum_matching_adjusted,2,44.75781574373595,30.13435700575815,15.873015873015872,3.2812052776091467,3,2.6666666666666665,244,292,298,0.5960176999797113 300,25,0.8,iterated_maximum_matching_adjusted,3,43.37469843858028,30.9021113243762,15.355086372360848,3.960136147502308,3,2.6666666666666665,273,300,300,0.7446940999943763 300,25,0.8,iterated_maximum_matching_adjusted,4,39.896490599797005,23.711340206185564,16.7910447761194,3.4178658537790656,3,2.6666666666666665,205,260,284,0.5823194999829866 300,25,0.8,serial_dictatorship,0,35.01047824213169,0.0,100.0,60.38303253559529,6,2.6666666666666665,73,83,87,0.1140207999851554 @@ -551,7 +551,7 @@ num_of_agents,num_of_items,value_noise_ratio,algorithm,random_seed,utilitarian_v 300,25,0.8,bidirectional_round_robin,4,36.76792036304611,21.79700499168053,25.84070796460177,4.784362006249035,3,2.6666666666666665,203,242,272,0.1091929000103846 300,25,0.8,almost_egalitarian_without_donation,0,44.10040372015013,17.62376237623762,40.99009900990099,10.307241614842924,5,2.6666666666666665,191,255,280,12.588894300046377 300,25,0.8,almost_egalitarian_without_donation,1,49.91197796160656,29.87551867219917,29.19389978213508,8.361883520390224,4,2.6666666666666665,239,274,292,12.691720100003296 -300,25,0.8,almost_egalitarian_without_donation,2,45.24530896448655,25.547445255474454,35.44857768052516,10.133646745352488,5,2.6666666666666665,206,247,267,12.592786799999883 +300,25,0.8,almost_egalitarian_without_donation,2,45.24530896448655,25.547445255474457,35.44857768052516,10.133646745352488,5,2.6666666666666665,206,247,267,12.592786799999883 300,25,0.8,almost_egalitarian_without_donation,3,43.618547335427714,22.71880819366853,31.471135940409688,9.90584477468822,4,2.6666666666666665,239,277,285,12.51178030000301 300,25,0.8,almost_egalitarian_without_donation,4,40.27882010308413,18.62745098039216,36.8421052631579,11.21753699523339,5,2.6666666666666665,183,230,258,12.336475399963092 300,25,0.8,almost_egalitarian_with_donation,0,44.11471321003086,17.62376237623762,40.99009900990099,10.175386447866812,5,2.6666666666666665,191,256,281,12.320924900006505 @@ -585,7 +585,7 @@ num_of_agents,num_of_items,value_noise_ratio,algorithm,random_seed,utilitarian_v 300,25,1.0,round_robin,3,41.73108191761379,25.63636363636364,25.39432176656151,7.305544960997491,3,2.6666666666666665,276,295,300,0.1086184000014327 300,25,1.0,round_robin,4,38.173411859010166,19.290123456790123,28.45394736842105,8.789931662740132,3,2.6666666666666665,206,250,280,0.1089725000201724 300,25,1.0,bidirectional_round_robin,0,41.460841780013055,28.515625,24.34944237918216,4.32574494014441,3,2.6666666666666665,237,274,297,0.1080712000257335 -300,25,1.0,bidirectional_round_robin,1,47.656758321069695,29.72972972972973,18.599999999999994,2.814159820490278,3,2.6666666666666665,276,299,300,0.1100359000265598 +300,25,1.0,bidirectional_round_robin,1,47.656758321069695,29.72972972972973,18.59999999999999,2.814159820490278,3,2.6666666666666665,276,299,300,0.1100359000265598 300,25,1.0,bidirectional_round_robin,2,42.78573720151452,28.622540250447223,19.18604651162791,3.757206887598629,3,2.6666666666666665,243,280,296,0.1143395999679341 300,25,1.0,bidirectional_round_robin,3,41.50882060817325,32.065217391304344,15.299684542586752,3.3487311283086703,3,2.6666666666666665,276,295,300,0.1116150000016205 300,25,1.0,bidirectional_round_robin,4,37.626936259247934,21.382636655948552,26.809210526315788,4.790153502905161,3,2.6666666666666665,206,250,280,0.1111859999946318 @@ -659,6 +659,81 @@ num_of_agents,num_of_items,value_noise_ratio,algorithm,random_seed,utilitarian_v 8,4,0.2,bidirectional_round_robin,2,100.0,100.0,0.0,0.0,2,2.0,8,8,8,0.0006288000149652 8,4,0.2,bidirectional_round_robin,3,100.0,100.0,0.0,0.0,2,2.0,8,8,8,0.0006845999741926 8,4,0.2,bidirectional_round_robin,4,100.0,100.0,0.0,0.0,2,2.0,8,8,8,0.0009022000012919 +100,25,0.0,gale_shapley,0,92.49677069899921,72.38805970149254,24.875621890547265,4.067563396065733,0,0.0,95,97,98,0.025848250000000017 +100,25,0.0,gale_shapley,1,96.08843582349384,85.51912568306011,13.315217391304358,2.1259056285883178,0,0.0,100,100,100,0.025150208000000007 +100,25,0.0,gale_shapley,2,88.21796183234568,68.06526806526807,27.505827505827497,9.283999069670328,0,0.0,98,99,99,0.024753875000000036 +100,25,0.0,gale_shapley,3,94.22070273294658,79.70297029702971,16.089108910891085,2.9403457512502857,0,0.0,100,100,100,0.025196667000000006 +100,25,0.0,gale_shapley,4,84.5503554699656,57.35294117647059,42.64705882352941,13.04130609679076,0,0.0,95,98,100,0.025031625000000002 +100,25,0.2,gale_shapley,0,94.32817954692482,74.07407407407408,22.46913580246914,2.1920051939043064,0,0.0,98,98,100,0.024973500000000093 +100,25,0.2,gale_shapley,1,97.15046570325181,88.25065274151436,11.749347258485642,0.9658975780566895,0,0.0,100,100,100,0.024828708000000033 +100,25,0.2,gale_shapley,2,90.53361667693449,71.55963302752293,22.477064220183493,6.336751836773719,0,0.0,98,99,100,0.025020417000000017 +100,25,0.2,gale_shapley,3,95.54647827889028,81.88235294117648,14.549653579676658,1.7455699579406463,0,0.0,100,100,100,0.02473225000000001 +100,25,0.2,gale_shapley,4,87.77316400883326,62.421711899791234,36.116910229645086,8.650734589677876,0,0.0,100,100,100,0.025520540999999897 +100,25,0.5,gale_shapley,0,95.93081945685714,75.87719298245614,20.43795620437956,1.2229625020850359,0,0.0,99,99,100,0.02418070800000005 +100,25,0.5,gale_shapley,1,98.1244089445243,89.749430523918,9.876543209876544,0.347017229081018,0,0.0,100,100,100,0.024068584000000115 +100,25,0.5,gale_shapley,2,92.78783397864807,67.49435665914221,27.765237020316036,3.6196651870400394,0,0.0,100,100,100,0.024186625000000017 +100,25,0.5,gale_shapley,3,96.6944153403077,80.25751072961373,13.090128755364816,0.9290921938933687,0,0.0,100,100,100,0.0240263329999999 +100,25,0.5,gale_shapley,4,90.91221176422594,69.23076923076923,27.45490981963927,5.0828410002357804,0,0.0,100,100,100,0.02552412500000001 +100,25,0.8,gale_shapley,0,96.8495730423398,76.7590618336887,18.22541966426857,0.7677898316846451,0,0.0,99,100,100,0.02393258300000012 +100,25,0.8,gale_shapley,1,98.65849839370749,90.71925754060325,8.120649651972158,0.1311774897758309,0,0.0,100,100,100,0.023136041999999968 +100,25,0.8,gale_shapley,2,94.46074345828363,78.28947368421053,15.13157894736841,1.7122182680258413,0,0.0,100,100,100,0.025657708 +100,25,0.8,gale_shapley,3,97.52083842325196,85.04672897196261,5.454545454545453,0.38822490570414914,0,0.0,100,100,100,0.023986958000000058 +100,25,0.8,gale_shapley,4,92.94669540174702,72.5925925925926,25.454545454545453,3.135201253069527,0,0.0,100,100,100,0.024703417000000005 +100,25,1.0,gale_shapley,0,97.42687741815625,77.35849056603774,15.130023640661946,0.5728148059101931,0,0.0,99,100,100,0.023882166999999788 +100,25,1.0,gale_shapley,1,98.86432154573045,91.25560538116592,6.9506726457399,0.08948619689384245,0,0.0,100,100,100,0.023535749999999966 +100,25,1.0,gale_shapley,2,95.1793351324711,74.89451476793249,18.776371308016877,1.3225934257189487,0,0.0,100,100,100,0.023185624999999987 +100,25,1.0,gale_shapley,3,97.80491413980747,84.375,11.5234375,0.3680213672159715,0,0.0,100,100,100,0.023217708000000004 +100,25,1.0,gale_shapley,4,93.95755787465463,74.68581687612208,24.420677361853834,1.9830789037876384,0,0.0,100,100,100,0.023875917000000024 +200,25,0.0,gale_shapley,0,58.263144842915096,0.0,77.15617715617715,22.380890809228298,6,1.0,131,162,182,0.08139683300000011 +200,25,0.0,gale_shapley,1,66.83386265719817,0.0,92.1259842519685,25.15464313186476,6,1.0,156,179,187,0.08326779200000001 +200,25,0.0,gale_shapley,2,58.263339983546274,7.322654462242563,84.89702517162472,30.076088682136046,5,1.0,147,165,170,0.08156079199999988 +200,25,0.0,gale_shapley,3,58.58552423359339,0.0,90.93137254901961,26.421131127031114,6,1.0,172,181,186,0.08414754199999996 +200,25,0.0,gale_shapley,4,50.79621534648443,0.0,83.02658486707567,29.214193410945114,6,1.0,130,147,158,0.0802070410000002 +200,25,0.2,gale_shapley,0,60.32544134093094,0.0,82.53588516746412,21.15048293084276,6,1.0,146,173,182,0.08294666699999986 +200,25,0.2,gale_shapley,1,68.70322976038881,13.984168865435356,81.79419525065963,21.479410434852543,5,1.0,168,182,188,0.08506158300000033 +200,25,0.2,gale_shapley,2,60.886834130242384,0.0,82.07964601769912,24.389618618397794,6,1.0,153,167,173,0.08341133299999992 +200,25,0.2,gale_shapley,3,60.364907578366484,0.0,88.09523809523809,23.4415151288397,6,1.0,174,183,187,0.08498437499999989 +200,25,0.2,gale_shapley,4,53.61607244812601,0.9380863039399625,85.91836734693877,26.76747321587795,5,1.0,138,156,168,0.08167829199999987 +200,25,0.5,gale_shapley,0,62.556495883775106,0.0,82.56880733944955,17.06871662879491,6,1.0,156,179,186,0.08394812500000004 +200,25,0.5,gale_shapley,1,70.6453418035562,0.0,86.60287081339713,17.87335873221818,6,1.0,172,182,187,0.08496637500000004 +200,25,0.5,gale_shapley,2,63.76601422084884,0.0,90.5982905982906,21.488770179762827,6,1.0,164,176,178,0.08546416700000004 +200,25,0.5,gale_shapley,3,62.35612545610845,0.0,88.31460674157303,21.21505426493055,6,1.0,183,188,190,0.0861720840000002 +200,25,0.5,gale_shapley,4,56.5787493697321,0.0,91.51515151515152,22.263095216458552,6,1.0,148,165,171,0.08290299999999995 +200,25,0.8,gale_shapley,0,64.12798983950012,0.0,82.23684210526315,16.574064258122267,6,1.0,159,180,184,0.0840298340000003 +200,25,0.8,gale_shapley,1,72.0964800057888,0.0,88.46153846153845,16.15930451627772,6,1.0,173,182,187,0.08537183299999995 +200,25,0.8,gale_shapley,2,65.77671441648296,0.0,84.59770114942529,17.483265210818583,6,1.0,169,177,183,0.08560037500000028 +200,25,0.8,gale_shapley,3,63.842070626304974,0.0,86.87089715536105,19.52463082464706,6,1.0,181,185,187,0.08609974999999981 +200,25,0.8,gale_shapley,4,58.65267698308432,0.0,91.699604743083,20.511374949198398,6,1.0,154,170,173,0.08647812499999974 +200,25,1.0,gale_shapley,0,64.88187121405679,0.0,84.0670859538784,17.15216937979489,6,1.0,168,181,183,0.08537408400000013 +200,25,1.0,gale_shapley,1,72.82519613555968,0.0,83.88520971302428,15.141348521620671,6,1.0,173,184,188,0.08496466599999986 +200,25,1.0,gale_shapley,2,66.81234314374346,0.0,88.51351351351352,16.408762807481622,6,1.0,169,177,182,0.08586745900000015 +200,25,1.0,gale_shapley,3,64.63950232069287,0.0,87.44769874476988,18.868211500076185,6,1.0,180,186,187,0.08457058300000009 +200,25,1.0,gale_shapley,4,59.73421257954176,0.0,93.00970873786407,19.657956740849656,6,1.0,156,170,175,0.08348512500000016 +300,25,0.0,gale_shapley,0,39.72344163298327,0.0,79.22705314009661,34.197159800715745,6,2.6666666666666665,144,189,223,0.138603625 +300,25,0.0,gale_shapley,1,45.543775459111956,0.0,90.02624671916011,42.04269472445284,6,2.6666666666666665,189,229,243,0.13900720799999977 +300,25,0.0,gale_shapley,2,39.80912955641544,0.0,76.39902676399026,33.4149739529616,6,2.6666666666666665,173,212,221,0.13742549999999998 +300,25,0.0,gale_shapley,3,39.731387618722245,0.0,89.63855421686748,39.91718048949528,6,2.6666666666666665,203,223,236,0.13966020900000053 +300,25,0.0,gale_shapley,4,34.764396423420436,0.0,80.46218487394957,37.61611545132006,6,2.6666666666666665,145,175,193,0.13761470899999928 +300,25,0.2,gale_shapley,0,41.389778378150474,0.0,81.48148148148148,31.950484491754846,6,2.6666666666666665,170,205,227,0.13965020799999994 +300,25,0.2,gale_shapley,1,47.09379142592505,0.0,95.77836411609498,36.64741776560305,6,2.6666666666666665,209,237,250,0.14694608300000045 +300,25,0.2,gale_shapley,2,41.891588947516354,0.0,77.96610169491525,30.874100142192802,6,2.6666666666666665,183,214,224,0.14144341699999963 +300,25,0.2,gale_shapley,3,41.15348688582147,0.0,90.58823529411764,37.27655901638151,6,2.6666666666666665,211,229,237,0.14165154199999996 +300,25,0.2,gale_shapley,4,37.0381744996238,0.0,85.18518518518519,34.15139721030079,6,2.6666666666666665,162,189,204,0.13809908300000018 +300,25,0.5,gale_shapley,0,43.22654357599736,0.0,85.09615384615384,30.885889248844386,6,2.6666666666666665,184,214,228,0.14128541600000055 +300,25,0.5,gale_shapley,1,48.859070542189805,0.0,95.23809523809523,32.157446960743876,6,2.6666666666666665,213,241,250,0.14362604200000018 +300,25,0.5,gale_shapley,2,44.25105286805108,0.0,87.12121212121212,30.884090217082665,6,2.6666666666666665,189,215,224,0.14158820799999994 +300,25,0.5,gale_shapley,3,42.717715672280015,0.0,91.87358916478556,35.36412618569946,6,2.6666666666666665,216,230,238,0.14175091600000034 +300,25,0.5,gale_shapley,4,39.503134412251576,0.0,86.64047151277013,33.34223714751684,6,2.6666666666666665,173,198,212,0.14005058399999992 +300,25,0.8,gale_shapley,0,44.51731136486354,0.0,85.09719222462203,31.05803198763208,6,2.6666666666666665,187,221,234,0.1407141249999997 +300,25,0.8,gale_shapley,1,50.10000375034142,0.0,99.76190476190476,31.140721296707174,6,2.6666666666666665,219,242,250,0.14348554200000052 +300,25,0.8,gale_shapley,2,45.905278787541555,0.0,85.36585365853658,28.97847084031857,6,2.6666666666666665,195,219,230,0.14482879100000012 +300,25,0.8,gale_shapley,3,43.95067487503277,0.0,83.54166666666667,31.431237947447663,6,2.6666666666666665,216,229,235,0.14272062499999993 +300,25,0.8,gale_shapley,4,41.28874196110141,0.0,86.80297397769516,31.40130883890528,6,2.6666666666666665,181,203,211,0.1400226249999994 +300,25,1.0,gale_shapley,0,45.176379669808234,0.0,85.38622129436325,30.988869494011972,6,2.6666666666666665,198,224,232,0.1449911660000005 +300,25,1.0,gale_shapley,1,50.814892109480866,0.0,100.0,29.703960098267107,6,2.6666666666666665,223,244,251,0.16631670900000017 +300,25,1.0,gale_shapley,2,46.7731115672324,0.0,89.83050847457628,28.93582603025562,6,2.6666666666666665,195,221,233,0.14500670900000046 +300,25,1.0,gale_shapley,3,44.604923938062086,0.0,82.93172690763052,30.73943914471146,6,2.6666666666666665,217,227,234,0.1656443750000003 +300,25,1.0,gale_shapley,4,42.24904960484787,0.0,85.24271844660194,30.522548966312126,6,2.6666666666666665,184,205,219,0.1414625420000002 5,6,0.2,ACEEI_without_EFTB,0,100.0,100.0,0.0,0.0,0,0.0,5,5,5,0.1032566999783739 5,6,0.2,ACEEI_without_EFTB,1,100.0,100.0,0.0,0.0,0,0.0,5,5,5,0.0074490999104455 5,6,0.2,ACEEI_without_EFTB,2,100.0,100.0,0.0,0.0,0,0.0,5,5,5,0.0081060000229626 diff --git a/fairpyx/algorithms/Gale_Shapley_pareto_dominant_market_mechanism.py b/fairpyx/algorithms/Gale_Shapley_pareto_dominant_market_mechanism.py new file mode 100644 index 0000000..10cac27 --- /dev/null +++ b/fairpyx/algorithms/Gale_Shapley_pareto_dominant_market_mechanism.py @@ -0,0 +1,244 @@ +""" +"Course bidding at business schools", by Tayfun Sönmez and M. Utku Ünver (2010) +https://doi.org/10.1111/j.1468-2354.2009.00572.x + +Allocate course seats using Gale-Shapley pareto-dominant market mechanism. + +Programmer: Zachi Ben Shitrit +Since: 2024-05 +""" + +from fairpyx import AllocationBuilder +import numpy as np +from typing import Dict, List, Union + +import logging +logger = logging.getLogger(__name__) + + +def gale_shapley(alloc: AllocationBuilder, course_order_per_student: Union[Dict[str, List[str]], None] = None, tie_braking_lottery: Union[None, Dict[str, float]] = None): + """ + Allocate the given items to the given agents using the Gale-Shapley protocol. + + Parameters: + alloc (AllocationBuilder): An allocation builder which tracks agent capacities, item capacities, and valuations. + course_order_per_student (Dict[str, List[str]]): A dictionary that matches each agent to their course rankings indicating preferences. + tie_braking_lottery (Dict[str, float]): A dictionary that matches each agent to their tie-breaking additive points (sampled from a uniform distribution [0,1]). + + Returns: + Dict[str, List[str]]: A dictionary representing the final allocation of courses to students. + + Naive Example: + >>> from fairpyx import Instance, AllocationBuilder + >>> from fairpyx.adaptors import divide + >>> s1 = {"c1": 40, "c2": 60} + >>> s2 = {"c1": 70, "c2": 30} + >>> s3 = {"c1": 70, "c2": 30} + >>> s4 = {"c1": 40, "c2": 60} + >>> s5 = {"c1": 50, "c2": 50} + >>> agent_capacities = {"Alice": 1, "Bob": 1, "Chana": 1, "Dana": 1, "Dor": 1} + >>> course_capacities = {"c1": 3, "c2": 2} + >>> valuations = {"Alice": s1, "Bob": s2, "Chana": s3, "Dana": s4, "Dor": s5} + >>> course_order_per_student = {"Alice": ["c2", "c1"], "Bob": ["c1", "c2"], "Chana": ["c1", "c2"], "Dana": ["c2", "c1"], "Dor": ["c1", "c2"]} + >>> tie_braking_lottery = {"Alice": 0.9, "Bob": 0.1, "Chana": 0.2, "Dana": 0.6, "Dor": 0.4} + >>> instance = Instance(agent_capacities=agent_capacities, item_capacities=course_capacities, valuations=valuations) + >>> divide(gale_shapley, instance=instance, course_order_per_student=course_order_per_student, tie_braking_lottery=tie_braking_lottery) + {'Alice': ['c2'], 'Bob': ['c1'], 'Chana': ['c1'], 'Dana': ['c2'], 'Dor': ['c1']} + + + Example where the students course order does not align with the bids: + >>> s1 = {"c1": 20, "c2": 15, "c3": 35, "c4": 10, "c5": 20} + >>> s2 = {"c1": 30, "c2": 15, "c3": 20, "c4": 20, "c5": 15} + >>> s3 = {"c1": 40, "c2": 10, "c3": 25, "c4": 10, "c5": 15} + >>> s4 = {"c1": 10, "c2": 10, "c3": 15, "c4": 30, "c5": 35} + >>> s5 = {"c1": 25, "c2": 20, "c3": 30, "c4": 10, "c5": 15} + >>> agent_capacities = {"Alice": 3, "Bob": 3, "Chana": 3, "Dana": 3, "Dor": 3} + >>> course_capacities = {"c1": 4, "c2": 4, "c3": 2, "c4": 3, "c5": 2} + >>> valuations = {"Alice": s1, "Bob": s2, "Chana": s3, "Dana": s4, "Dor": s5} + >>> course_order_per_student = {"Alice": ["c5", "c3", "c1", "c2", "c4"], "Bob": ["c1", "c4", "c5", "c2", "c3"], "Chana": ["c5", "c1", "c4", "c3", "c2"], "Dana": ["c3", "c4", "c1", "c5", "c2"], "Dor": ["c5", "c1", "c4", "c3", "c2"]} + >>> tie_braking_lottery = {"Alice": 0.6, "Bob": 0.4, "Chana": 0.3, "Dana": 0.8, "Dor": 0.2} + >>> instance = Instance(agent_capacities=agent_capacities, item_capacities=course_capacities, valuations=valuations) + >>> divide(gale_shapley, instance=instance, course_order_per_student=course_order_per_student, tie_braking_lottery=tie_braking_lottery) + {'Alice': ['c1', 'c3', 'c5'], 'Bob': ['c1', 'c2', 'c4'], 'Chana': ['c1', 'c2', 'c4'], 'Dana': ['c2', 'c4', 'c5'], 'Dor': ['c1', 'c2', 'c3']} + """ + + # Check if inputs are dictionaries + input_to_check_types = [alloc.remaining_agent_capacities, alloc.remaining_item_capacities] + for input_to_check in input_to_check_types: + if(type(input_to_check) != dict): + raise TypeError(f"In the input {input_to_check}, Expected a dict, but got {type(input_to_check).__name__}") + if tie_braking_lottery and type(tie_braking_lottery) != dict: + raise TypeError(f"In the input tie_braking_lottery, Expected a dict or None, but got {type(tie_braking_lottery).__name__}") + if not tie_braking_lottery: + tie_braking_lottery = {student : np.random.uniform(low=0, high=1) for student in alloc.remaining_agents()} + + if not course_order_per_student: + course_order_per_student = {student : generate_naive_course_order_for_student(student, alloc) for student in alloc.remaining_agents()} + logger.info(f"Created course_order_per_student: {course_order_per_student}") + + was_an_offer_declined: bool = True + course_to_on_hold_students: Dict[str, Dict[str, float]] = {course: {} for course in alloc.remaining_items()} + student_to_rejection_count: Dict[str, int] = {student: alloc.remaining_agent_capacities[student] for student in alloc.remaining_agents()} + + logger.info(f"We have {len(alloc.remaining_agents())} agents") + logger.info(f"The students allocation capacities are: {alloc.remaining_agent_capacities}") + logger.info(f"The courses capacities are: {alloc.remaining_item_capacities}") + logger.info(f"The tie-braking lottery results are: {tie_braking_lottery}") + for agent in alloc.remaining_agents(): + agent_bids = {course: alloc.effective_value(agent, course) for course in alloc.remaining_items()} + logger.info(f"Student '{agent}' bids are: {agent_bids}") + + step = 0 + while(was_an_offer_declined): + step += 1 + logger.info(f"\n *** Starting round #{step} ***") + was_an_offer_declined = False + logger.info("Each student who is rejected from k > 0 courses in the previous step proposes to his best remaining k courses based on his stated preferences") + for student in alloc.remaining_agents(): + student_capability: int = student_to_rejection_count[student] + for index in range(student_capability): + if(not course_order_per_student[student]): + logger.info(f"Student {student} already proposed to all his desired courses") + continue + wanted_course = course_order_per_student[student].pop(0) + if(wanted_course in course_to_on_hold_students): + if(student in course_to_on_hold_students[wanted_course]): + continue + try: + student_to_course_proposal = alloc.effective_value(student, wanted_course) + course_to_on_hold_students[wanted_course][student] = student_to_course_proposal + logger.info(f"Student '{student} proposes to course {wanted_course} with a bid of {student_to_course_proposal}") + except Exception as e: + return {} + + logger.info("Each course c considers the new proposals together with the proposals on hold and rejects all but the highest bidding Qc (the maximum capacity of students in course c) students") + student_to_rejection_count = {student: 0 for student in alloc.remaining_agents()} + for course_name in course_to_on_hold_students: + course_capacity = alloc.remaining_item_capacities[course_name] + if(type(course_capacity) == np.float64): + course_capacity = int(course_capacity) + course_to_offerings = course_to_on_hold_students[course_name] + logger.info(f"Course {course_name} considers the next offerings: {course_to_offerings}") + if len(course_to_offerings) == 0: + continue + elif len(course_to_offerings) <= course_capacity: + continue + logger.info("In case there is a tie, the tie-breaking lottery is used to determine who is rejected and who will be kept on hold.") + on_hold_students_sorted_and_tie_breaked = sort_and_tie_break(course_to_offerings, tie_braking_lottery) + course_to_on_hold_students[course_name].clear() + for key, value in on_hold_students_sorted_and_tie_breaked[:course_capacity]: + course_to_on_hold_students[course_name][key] = value + + rejected_students = on_hold_students_sorted_and_tie_breaked[course_capacity:] + for rejected_student, bid in rejected_students: + logger.info(f"Agent '{rejected_student}' was rejected from course {course_name}") + student_to_rejection_count[rejected_student] += 1 + was_an_offer_declined = True + + logger.info("The procedure terminates when no proposal is rejected, and at this stage course assignments are finalized.") + final_course_matchings = course_to_on_hold_students.items() + for course_name, matching in final_course_matchings: + for student, bid in matching.items(): + alloc.give(student, course_name, logger) + logger.info(f"The final course matchings are: {alloc.bundles}") + + +def sort_and_tie_break(input_dict: Dict[str, float], tie_braking_lottery: Dict[str, float]) -> List[tuple[str, float]]: + """ + Sorts a dictionary by its values in descending order and adds a number + to the values of keys with the same value to break ties. + + Parameters: + input_dict (Dict[str, float]): A dictionary with string keys and float values representing student bids. + tie_braking_lottery (Dict[str, float]): A dictionary with string keys and float values for tie-breaking. + + Returns: + List[tuple[str, float]]: A list of tuples containing student names and their modified bids, sorted in descending order. + + Examples: + >>> input_dict = {"Alice": 45, "Bob": 55, "Chana": 45, "Dana": 60} + >>> tie_braking_lottery = {"Alice": 0.3, "Bob": 0.2, "Chana": 0.4, "Dana": 0.1} + >>> sort_and_tie_break(input_dict, tie_braking_lottery) + [('Dana', 60), ('Bob', 55), ('Chana', 45), ('Alice', 45)] + """ + + + # Sort the dictionary by adjusted values in descending order + sorted_dict = (sorted(input_dict.items(), key=lambda item: item[1] + tie_braking_lottery[item[0]], reverse=True)) + + return sorted_dict + + +def generate_naive_course_order_for_student(student: str, alloc: AllocationBuilder) -> List[str]: + """ + Generate a naive course order for a given student based on the effective value the student assigns to each course. + + Parameters: + student (str): The student's name. + alloc (AllocationBuilder): An allocation builder which tracks agent capacities, item capacities, and valuations. + + Returns: + List[str]: A list of course names sorted by the effective value the student assigns to each course, in descending order. + + Example: + >>> from fairpyx import Instance, AllocationBuilder + >>> s1 = {"c1": 40, "c2": 60} + >>> s2 = {"c1": 70, "c2": 30} + >>> s3 = {"c1": 70, "c2": 30} + >>> s4 = {"c1": 40, "c2": 60} + >>> s5 = {"c1": 50, "c2": 50} + >>> agent_capacities = {"Alice": 1, "Bob": 1, "Chana": 1, "Dana": 1, "Dor": 1} + >>> course_capacities = {"c1": 3, "c2": 2} + >>> valuations = {"Alice": s1, "Bob": s2, "Chana": s3, "Dana": s4, "Dor": s5} + >>> course_order_per_student = {"Alice": ["c2", "c1"], "Bob": ["c1", "c2"], "Chana": ["c1", "c2"], "Dana": ["c2", "c1"], "Dor": ["c1", "c2"]} + >>> tie_braking_lottery = {"Alice": 0.9, "Bob": 0.1, "Chana": 0.2, "Dana": 0.6, "Dor": 0.4} + >>> instance = Instance(agent_capacities=agent_capacities, item_capacities=course_capacities, valuations=valuations) + >>> alloc = AllocationBuilder(instance) + >>> generate_naive_course_order_for_student("Alice", alloc) + ['c2', 'c1'] + >>> generate_naive_course_order_for_student("Bob", alloc) + ['c1', 'c2'] + >>> generate_naive_course_order_for_student('Chana', alloc) + ['c1', 'c2'] + >>> generate_naive_course_order_for_student('Dana', alloc) + ['c2', 'c1'] + >>> generate_naive_course_order_for_student('Dor', alloc) + ['c1', 'c2'] + """ + # Get all courses + courses: List[str] = alloc.remaining_items() + + # Calculate the effective value of each course for the given student + course_values: Dict[str, float] = {course: alloc.effective_value(student, course) for course in courses} + + # Sort the courses by their values in descending order + sorted_courses = sorted(course_values.items(), key=lambda item: item[1], reverse=True) + + # Extract the course names from the sorted list of tuples + sorted_course_names = [course for course, value in sorted_courses] + + return sorted_course_names + +if __name__ == "__main__": + import doctest + print(doctest.testmod()) + + logger.setLevel(logging.DEBUG) + logger.addHandler(logging.StreamHandler()) + + from fairpyx import Instance, divide + + s1 = {"c1": 20, "c2": 15, "c3": 35, "c4": 10, "c5": 20} + s2 = {"c1": 30, "c2": 15, "c3": 20, "c4": 20, "c5": 15} + s3 = {"c1": 40, "c2": 10, "c3": 25, "c4": 10, "c5": 15} + s4 = {"c1": 10, "c2": 10, "c3": 15, "c4": 30, "c5": 35} + s5 = {"c1": 25, "c2": 20, "c3": 30, "c4": 10, "c5": 15} + agent_capacities = {"Alice": 3, "Bob": 3, "Chana": 3, "Dana": 3, "Dor": 3} + course_capacities = {"c1": 4, "c2": 4, "c3": 2, "c4": 3, "c5": 2} + valuations = {"Alice": s1, "Bob": s2, "Chana": s3, "Dana": s4, "Dor": s5} + course_order_per_student = {"Alice": ["c5", "c3", "c1", "c2", "c4"], "Bob": ["c1", "c4", "c5", "c2", "c3"], "Chana": ["c5", "c1", "c4", "c3", "c2"], "Dana": ["c3", "c4", "c1", "c5", "c2"], "Dor": ["c5", "c1", "c4", "c3", "c2"]} + tie_braking_lottery = {"Alice": 0.6, "Bob": 0.4, "Chana": 0.3, "Dana": 0.8, "Dor": 0.2} + instance = Instance(agent_capacities=agent_capacities, item_capacities=course_capacities, valuations=valuations) + divide(gale_shapley, instance=instance, course_order_per_student=course_order_per_student, tie_braking_lottery=tie_braking_lottery) + {'Alice': ['c1', 'c3', 'c5'], 'Bob': ['c1', 'c2', 'c4'], 'Chana': ['c1', 'c2', 'c4'], 'Dana': ['c2', 'c4', 'c5'], 'Dor': ['c1', 'c2', 'c3']} + diff --git a/fairpyx/algorithms/__init__.py b/fairpyx/algorithms/__init__.py index 376790b..bcb73be 100644 --- a/fairpyx/algorithms/__init__.py +++ b/fairpyx/algorithms/__init__.py @@ -2,6 +2,7 @@ from fairpyx.algorithms.iterated_maximum_matching import iterated_maximum_matching, iterated_maximum_matching_adjusted, iterated_maximum_matching_unadjusted from fairpyx.algorithms.picking_sequence import round_robin, bidirectional_round_robin, serial_dictatorship from fairpyx.algorithms.utilitarian_matching import utilitarian_matching +from fairpyx.algorithms.Gale_Shapley_pareto_dominant_market_mechanism import gale_shapley from fairpyx.algorithms.ACEEI_algorithms.tabu_search import tabu_search from fairpyx.algorithms.ACEEI_algorithms.ACEEI import find_ACEEI_with_EFTB from fairpyx.algorithms.ACEEI_algorithms.find_profitable_manipulation import find_profitable_manipulation diff --git a/pyproject.toml b/pyproject.toml index 34ca122..5cf6443 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,4 +4,4 @@ build-backend = "setuptools.build_meta" [tool.pytest.ini_options] minversion = "6.0" -addopts = "--doctest-modules --ignore=examples/_pweave.py --ignore=experiments --ignore=fairpyx/zalternatives" +addopts = "--doctest-modules --ignore=examples/_pweave.py --ignore=experiments --ignore=fairpyx/zalternatives --ignore=website_gale_shapley" diff --git a/tests/test_gale_shapley.py b/tests/test_gale_shapley.py new file mode 100644 index 0000000..a06eb3c --- /dev/null +++ b/tests/test_gale_shapley.py @@ -0,0 +1,220 @@ +""" +Test Allocate course seats using Gale-Shapley pareto-dominant market mechanism. + +Programmer: Zachi Ben Shitrit +Since: 2024-05 +""" + +import pytest +import fairpyx + +def test_regular_case(): + + s1 = {"c1": 40, "c2": 60} + s2 = {"c1": 70, "c2": 30} + s3 = {"c1": 70, "c2": 30} + s4 = {"c1": 40, "c2": 60} + s5 = {"c1": 50, "c2": 50} + agent_capacities = {"Alice": 1, "Bob": 1, "Chana": 1, "Dana": 1, "Dor": 1} + course_capacities = {"c1": 3, "c2": 2} + valuations = {"Alice": s1, "Bob": s2, "Chana": s3, "Dana": s4, "Dor": s5} + course_order_per_student = {"Alice": ["c2", "c1"], "Bob": ["c1", "c2"], "Chana": ["c1", "c2"], "Dana": ["c2", "c1"], "Dor": ["c1", "c2"]} + tie_braking_lottery = {"Alice": 0.9, "Bob": 0.1, "Chana": 0.2, "Dana": 0.6, "Dor": 0.4} + instance = fairpyx.Instance(agent_capacities=agent_capacities, + item_capacities=course_capacities, + valuations=valuations) + allocation = fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=instance, + course_order_per_student=course_order_per_student, + tie_braking_lottery=tie_braking_lottery) + assert allocation == {'Alice': ['c2'], 'Bob': ['c1'], 'Chana': ['c1'], 'Dana': ['c2'], 'Dor': ['c1']}, "allocation's did not match" + +def test_order_does_not_align_with_bids(): + s1 = {"c1": 20, "c2": 15, "c3": 35, "c4": 10, "c5": 20} + s2 = {"c1": 30, "c2": 15, "c3": 20, "c4": 20, "c5": 15} + s3 = {"c1": 40, "c2": 10, "c3": 25, "c4": 10, "c5": 15} + s4 = {"c1": 10, "c2": 10, "c3": 15, "c4": 30, "c5": 35} + s5 = {"c1": 25, "c2": 20, "c3": 30, "c4": 10, "c5": 15} + agent_capacities = {"Alice": 3, "Bob": 3, "Chana": 3, "Dana": 3, "Dor": 3} + course_capacities = {"c1": 4, "c2": 4, "c3": 2, "c4": 3, "c5": 2} + valuations = {"Alice": s1, "Bob": s2, "Chana": s3, "Dana": s4, "Dor": s5} + course_order_per_student = {"Alice": ["c5", "c3", "c1", "c2", "c4"], "Bob": ["c1", "c4", "c5", "c2", "c3"], "Chana": ["c5", "c1", "c4", "c3", "c2"], "Dana": ["c3", "c4", "c1", "c5", "c2"], "Dor": ["c5", "c1", "c4", "c3", "c2"]} + tie_braking_lottery = {"Alice": 0.6, "Bob": 0.4, "Chana": 0.3, "Dana": 0.8, "Dor": 0.2} + instance = fairpyx.Instance(agent_capacities=agent_capacities, + item_capacities=course_capacities, + valuations=valuations) + allocation = fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=instance, + course_order_per_student=course_order_per_student, + tie_braking_lottery=tie_braking_lottery) + assert allocation == {'Alice': ['c1', 'c3', 'c5'], 'Bob': ['c1', 'c2', 'c4'], 'Chana': ['c1', 'c2', 'c4'], 'Dana': ['c2', 'c4', 'c5'], 'Dor': ['c1', 'c2', 'c3']}, "allocation's did not match" + +def test_one_agent(): + s1 = {"c1": 40, "c2": 60} + agent_capacities = {"Alice": 1} + course_capacities = {"c1": 1, "c2": 1} + valuations = {"Alice": s1} + course_order_per_student = {"Alice": ["c2", "c1"]} + tie_braking_lottery = {"Alice": 0.9} + instance = fairpyx.Instance(agent_capacities=agent_capacities, + item_capacities=course_capacities, + valuations=valuations) + allocation = fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=instance, + course_order_per_student=course_order_per_student, + tie_braking_lottery=tie_braking_lottery) + assert allocation == {'Alice': ['c2']}, "allocation's did not match" + +def test_empty_input(): + agent_capacities = {} + course_capacities = {} + valuations = {} + course_order_per_student = {} + tie_braking_lottery = {} + with pytest.raises(StopIteration): + instance = fairpyx.Instance(agent_capacities=agent_capacities, + item_capacities=course_capacities, + valuations=valuations) + allocation = fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=instance, + course_order_per_student=course_order_per_student, + tie_braking_lottery=tie_braking_lottery) + +def test_wrong_input_type_agent_capacities(): + agent_capacities = "not a dict" + course_capacities = {"c1": 3, "c2": 2} + valuations = {"Alice": {"c1": 40, "c2": 60}} + course_order_per_student = {"Alice": ["c2", "c1"]} + tie_braking_lottery = {"Alice": 0.9} + with pytest.raises(TypeError): + instance = fairpyx.Instance(agent_capacities=agent_capacities, + item_capacities=course_capacities, + valuations=valuations) + fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=instance, + course_order_per_student=course_order_per_student, + tie_braking_lottery=tie_braking_lottery) + +def test_wrong_input_type_course_capacities(): + agent_capacities = {"Alice": 1} + course_capacities = "not a dict" + valuations = {"Alice": {"c1": 40, "c2": 60}} + course_order_per_student = {"Alice": ["c2", "c1"]} + tie_braking_lottery = {"Alice": 0.9} + with pytest.raises(TypeError): + instance = fairpyx.Instance(agent_capacities=agent_capacities, + item_capacities=course_capacities, + valuations=valuations) + fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=instance, + course_order_per_student=course_order_per_student, + tie_braking_lottery=tie_braking_lottery) + +def test_wrong_input_type_valuations(): + agent_capacities = {"Alice": 1} + course_capacities = {"c1": 3, "c2": 2} + valuations = "not a dict" + course_order_per_student = {"Alice": ["c2", "c1"]} + tie_braking_lottery = {"Alice": 0.9} + with pytest.raises(TypeError): + instance = fairpyx.Instance(agent_capacities=agent_capacities, + item_capacities=course_capacities, + valuations=valuations) + fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=instance, + course_order_per_student=course_order_per_student, + tie_braking_lottery=tie_braking_lottery) + +def test_wrong_input_type_course_order_per_student(): + agent_capacities = {"Alice": 1} + course_capacities = {"c1": 3, "c2": 2} + valuations = {"Alice": {"c1": 40, "c2": 60}} + course_order_per_student = "not a dict" + tie_braking_lottery = {"Alice": 0.9} + with pytest.raises(TypeError): + instance = fairpyx.Instance(agent_capacities=agent_capacities, + item_capacities=course_capacities, + valuations=valuations) + fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=instance, + course_order_per_student=course_order_per_student, + tie_braking_lottery=tie_braking_lottery) + +def test_wrong_input_type_tie_braking_lottery(): + agent_capacities = {"Alice": 1} + course_capacities = {"c1": 3, "c2": 2} + valuations = {"Alice": {"c1": 40, "c2": 60}} + course_order_per_student = {"Alice": ["c2", "c1"]} + tie_braking_lottery = "not a dict" + with pytest.raises(TypeError): + instance = fairpyx.Instance(agent_capacities=agent_capacities, + item_capacities=course_capacities, + valuations=valuations) + fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=instance, + course_order_per_student=course_order_per_student, + tie_braking_lottery=tie_braking_lottery) + + +def test_large_input(): + num_students = 1000 + num_courses = 50 + agent_capacities = {f"Student_{i}": 1 for i in range(num_students)} + course_capacities = {f"Course_{i}": num_students // num_courses for i in range(num_courses)} + valuations = {f"Student_{i}": {f"Course_{j}": (i+j) % 100 for j in range(num_courses)} for i in range(num_students)} + course_order_per_student = {f"Student_{i}": [f"Course_{j}" for j in range(num_courses)] for i in range(num_students)} + tie_braking_lottery = {f"Student_{i}": i / num_students for i in range(num_students)} + instance = fairpyx.Instance(agent_capacities=agent_capacities, + item_capacities=course_capacities, + valuations=valuations) + allocation = fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=instance, + course_order_per_student=course_order_per_student, + tie_braking_lottery=tie_braking_lottery) + # Validate that the allocation is valid + assert len(allocation) == num_students, "length of allocation did not match the number of students" + assert all(len(courses) == 1 for courses in allocation.values()), "not every course got exactly 1 student" + fairpyx.validate_allocation(instance, allocation, title=f"gale_shapley") + +def test_large_number_of_students_and_courses(): + s1 = {"c1": 20, "c2": 15, "c3": 35, "c4": 10, "c5": 20, "c6": 30, "c7": 25, "c8": 30, "c9": 15, "c10": 20, "c11": 25, "c12": 10, "c13": 30, "c14": 20, "c15": 15, "c16": 35, "c17": 20, "c18": 10, "c19": 25, "c20": 30} # sum = 440 + s2 = {"c1": 30, "c2": 15, "c3": 20, "c4": 20, "c5": 15, "c6": 25, "c7": 10, "c8": 20, "c9": 30, "c10": 25, "c11": 20, "c12": 15, "c13": 10, "c14": 20, "c15": 30, "c16": 15, "c17": 25, "c18": 20, "c19": 10, "c20": 35} # sum = 440 + s3 = {"c1": 40, "c2": 10, "c3": 25, "c4": 10, "c5": 15, "c6": 20, "c7": 25, "c8": 30, "c9": 35, "c10": 20, "c11": 15, "c12": 10, "c13": 20, "c14": 25, "c15": 30, "c16": 15, "c17": 10, "c18": 20, "c19": 25, "c20": 30} # sum = 440 + s4 = {"c1": 10, "c2": 10, "c3": 15, "c4": 30, "c5": 35, "c6": 20, "c7": 15, "c8": 10, "c9": 25, "c10": 20, "c11": 30, "c12": 15, "c13": 10, "c14": 25, "c15": 20, "c16": 30, "c17": 35, "c18": 20, "c19": 15, "c20": 30} # sum = 440 + s5 = {"c1": 25, "c2": 20, "c3": 30, "c4": 10, "c5": 15, "c6": 35, "c7": 25, "c8": 20, "c9": 10, "c10": 30, "c11": 15, "c12": 20, "c13": 25, "c14": 10, "c15": 35, "c16": 20, "c17": 15, "c18": 10, "c19": 30, "c20": 25} # sum = 440 + agent_capacities = {"Alice": 15, "Bob": 20, "Chana": 18, "Dana": 17, "Dor": 16} + course_capacities = {"c1": 10, "c2": 10, "c3": 8, "c4": 7, "c5": 6, "c6": 5, "c7": 4, "c8": 3, "c9": 2, "c10": 1, "c11": 10, "c12": 9, "c13": 8, "c14": 7, "c15": 6, "c16": 5, "c17": 4, "c18": 3, "c19": 2, "c20": 1} + valuations = {"Alice": s1, "Bob": s2, "Chana": s3, "Dana": s4, "Dor": s5} + course_order_per_student = {"Alice": ["c5", "c3", "c1", "c2", "c4", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20"], "Bob": ["c1", "c4", "c5", "c2", "c3", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20"], "Chana": ["c5", "c1", "c4", "c3", "c2", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20"], "Dana": ["c3", "c4", "c1", "c5", "c2", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20"], "Dor": ["c5", "c1", "c4", "c3", "c2", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13", "c14", "c15", "c16", "c17", "c18", "c19", "c20"]} + tie_braking_lottery = {"Alice": 0.6, "Bob": 0.4, "Chana": 0.3, "Dana": 0.8, "Dor": 0.2} + instance = fairpyx.Instance(agent_capacities=agent_capacities, + item_capacities=course_capacities, + valuations=valuations) + allocation = fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=instance, + course_order_per_student=course_order_per_student, + tie_braking_lottery=tie_braking_lottery) + # Validate that the allocation is valid + fairpyx.validate_allocation(instance, allocation, title=f"gale_shapley") + + +def test_edge_case_tie(): + s1 = {"c1": 50, "c2": 50} + s2 = {"c1": 50, "c2": 50} + agent_capacities = {"Alice": 1, "Bob": 1} + course_capacities = {"c1": 1, "c2": 1} + valuations = {"Alice": s1, "Bob": s2} + course_order_per_student = {"Alice": ["c1", "c2"], "Bob": ["c1", "c2"]} + tie_braking_lottery = {"Alice": 0.5, "Bob": 0.5} + instance = fairpyx.Instance(agent_capacities=agent_capacities, + item_capacities=course_capacities, + valuations=valuations) + allocation = fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=instance, + course_order_per_student=course_order_per_student, + tie_braking_lottery=tie_braking_lottery) + assert set(allocation.keys()) == {"Alice", "Bob"}, "the keys in the allocation did not match 'Alice', 'Bob'" + assert set(allocation["Alice"] + allocation["Bob"]) == {"c1", "c2"}, "the total allocation of courses for Alice and Bob did not match 'c1', 'c2'" + +if __name__ == "__main__": + pytest.main(["-v",__file__]) \ No newline at end of file diff --git a/website_gale_shapley/back/Dockerfile b/website_gale_shapley/back/Dockerfile new file mode 100644 index 0000000..af32c81 --- /dev/null +++ b/website_gale_shapley/back/Dockerfile @@ -0,0 +1,28 @@ +FROM python:3.9.6-slim + +ENV SERVICE_FOLDER_NAME=back +WORKDIR /${SERVICE_FOLDER_NAME} + +ENV PYTHONDONTWRITEBYTECODE 1 +ENV PYTHONBUFFERED 1 + +RUN set -ex \ + && RUN_DEPS=" \ + libpq-dev \ + git \ + " \ + && seq 1 8 | xargs -I{} mkdir -p /usr/share/man/man{} \ + && apt-get update && apt-get install -y --no-install-recommends $RUN_DEPS \ + && rm -rf /var/lib/apt/lists/* + +COPY requirements.txt . + +RUN pip install --no-cache-dir -r requirements.txt + +COPY . /${SERVICE_FOLDER_NAME}/ + +EXPOSE 8000 + +RUN chmod +x /${SERVICE_FOLDER_NAME}/entrypoint.sh + +ENTRYPOINT /$SERVICE_FOLDER_NAME/entrypoint.sh diff --git a/website_gale_shapley/back/__init__.py b/website_gale_shapley/back/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/website_gale_shapley/back/entrypoint.sh b/website_gale_shapley/back/entrypoint.sh new file mode 100644 index 0000000..758598b --- /dev/null +++ b/website_gale_shapley/back/entrypoint.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +cd .. +uvicorn ${SERVICE_FOLDER_NAME}.main:app --host 0.0.0.0 diff --git a/website_gale_shapley/back/main.py b/website_gale_shapley/back/main.py new file mode 100644 index 0000000..f95e8dd --- /dev/null +++ b/website_gale_shapley/back/main.py @@ -0,0 +1,70 @@ +from contextlib import asynccontextmanager +from typing import Any, AsyncGenerator, Dict, List +from fastapi import FastAPI, status +import io +import logging + +import fairpyx +from .schema import Instance + +logger = logging.getLogger("uvicorn") + +# On startup, create database tables +@asynccontextmanager +async def lifespan(app: FastAPI) -> AsyncGenerator[Any, None]: + # before app startup + yield + # After app shutdown + + +app = FastAPI(lifespan=lifespan) + + +@app.post("/api/divide", status_code=status.HTTP_200_OK) +async def divide(instance: Instance) -> Dict[str, Any]: + fairpyx_instance = fairpyx.Instance(agent_capacities=instance.agentCapabilities, + item_capacities=instance.courseCapabilities, + valuations=instance.bids) + + # Create a StringIO object to capture logs + log_capture = io.StringIO() + # Create a handler that writes to the StringIO object + handler = logging.StreamHandler(log_capture) + # Set the format for the handler + handler.setFormatter(logging.Formatter('%(message)s')) + + # Add the handler to the fairpyx logger + fairpyx_logger = logging.getLogger('fairpyx') + fairpyx_logger.addHandler(handler) + + # Set the level to capture all logs + original_level = fairpyx_logger.level + fairpyx_logger.setLevel(logging.DEBUG) + + try: + allocation = fairpyx.divide(fairpyx.algorithms.gale_shapley, + instance=fairpyx_instance, + course_order_per_student=instance.courseOrderPerStudent, + tie_braking_lottery=instance.tieBrakingLottery) + finally: + # Reset the logger level and remove the handler + fairpyx_logger.setLevel(original_level) + fairpyx_logger.removeHandler(handler) + + # Get the captured logs + log_capture.seek(0) + captured_logs = log_capture.getvalue().splitlines() + + # Log the captured logs using the uvicorn logger + for log_line in captured_logs: + logger.info(f"fairpyx log: {log_line}") + + logger.info(f"input: {instance}") + logger.info(f"output: {allocation}") + + # Return both the allocation and the logs + return { + "allocation": allocation, + "logs": captured_logs + } + diff --git a/website_gale_shapley/back/requirements.txt b/website_gale_shapley/back/requirements.txt new file mode 100644 index 0000000..3d711a1 --- /dev/null +++ b/website_gale_shapley/back/requirements.txt @@ -0,0 +1,53 @@ +aiosmtplib==2.0.2 +annotated-types==0.6.0 +anyio==4.3.0 +blinker==1.8.2 +certifi==2024.2.2 +cfgv==3.4.0 +click==8.1.7 +distlib==0.3.8 +dnspython==2.6.1 +exceptiongroup==1.2.1 +fastapi==0.111.0 +fastapi-cli==0.0.3 +filelock==3.14.0 +h11==0.14.0 +httpcore==1.0.5 +httptools==0.6.1 +httpx==0.27.0 +identify==2.5.36 +idna==3.7 +iniconfig==2.0.0 +Jinja2==3.1.4 +markdown-it-py==3.0.0 +MarkupSafe==2.1.5 +mdurl==0.1.2 +nodeenv==1.8.0 +orjson==3.10.3 +packaging==24.0 +platformdirs==4.2.1 +pluggy==1.5.0 +pre-commit==3.7.0 +pydantic==2.7.1 +pydantic-settings==2.2.1 +pydantic_core==2.18.2 +Pygments==2.18.0 +pytest==8.3.2 +python-dotenv==1.0.1 +python-multipart==0.0.9 +PyYAML==6.0.1 +rich==13.7.1 +shellingham==1.5.4 +sniffio==1.3.1 +starlette==0.37.2 +tomli==2.0.1 +typer==0.12.3 +typing_extensions==4.11.0 +ujson==5.9.0 +uvicorn==0.29.0 +uvloop==0.19.0 +virtualenv==20.26.1 +watchfiles==0.21.0 +websockets==12.0 +aiohttp==3.9.5 +-e git+https://github.com/zachibs/fairpyx.git#egg=fairpyx \ No newline at end of file diff --git a/website_gale_shapley/back/schema.py b/website_gale_shapley/back/schema.py new file mode 100644 index 0000000..ea9c8bd --- /dev/null +++ b/website_gale_shapley/back/schema.py @@ -0,0 +1,34 @@ +from typing import Dict, List +from pydantic import BaseModel, field_validator +import json + +class Instance(BaseModel): + courseCapabilities: Dict[str, int] + agentCapabilities: Dict[str, int] + bids: Dict[str, Dict[str, int]] + courseOrderPerStudent: Dict[str, List[str]] + tieBrakingLottery: Dict[str, float] + + @field_validator("courseCapabilities", "agentCapabilities", mode="before") + @classmethod + def convert_str_to_dict_int(cls, value: str) -> Dict[str, int]: + if isinstance(value, str): + return json.loads(value) + + @field_validator( "tieBrakingLottery", mode="before") + @classmethod + def convert_str_to_dict_float(cls, value: str) -> Dict[str, float]: + if isinstance(value, str): + return json.loads(value) + + @field_validator("bids", mode="before") + @classmethod + def convert_str_to_dict_dict(cls, value: str) -> Dict[str, Dict[str, int]]: + if isinstance(value, str): + return json.loads(value) + + @field_validator("courseOrderPerStudent", mode="before") + @classmethod + def convert_str_to_dict_list(cls, value: str) -> Dict[str, List[str]]: + if isinstance(value, str): + return json.loads(value) diff --git a/website_gale_shapley/back/start.sh b/website_gale_shapley/back/start.sh new file mode 100644 index 0000000..8738fb1 --- /dev/null +++ b/website_gale_shapley/back/start.sh @@ -0,0 +1 @@ +docker run -d -p 50010:8000 --name back-container backend-image \ No newline at end of file diff --git a/website_gale_shapley/front/.dockerignore b/website_gale_shapley/front/.dockerignore new file mode 100644 index 0000000..2b5059d --- /dev/null +++ b/website_gale_shapley/front/.dockerignore @@ -0,0 +1,10 @@ +Dockerfile +.dockerignore +node_modules +npm-debug.log +README.md +.next +!.next/static +!.next/standalone +.git +.env \ No newline at end of file diff --git a/website_gale_shapley/front/.eslintrc.json b/website_gale_shapley/front/.eslintrc.json new file mode 100644 index 0000000..62a9318 --- /dev/null +++ b/website_gale_shapley/front/.eslintrc.json @@ -0,0 +1,6 @@ +{ + "extends": "next/core-web-vitals", + "rules": { + "react/no-unescaped-entities": 0 + } +} \ No newline at end of file diff --git a/website_gale_shapley/front/.gitignore b/website_gale_shapley/front/.gitignore new file mode 100644 index 0000000..fd3dbb5 --- /dev/null +++ b/website_gale_shapley/front/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/website_gale_shapley/front/Dockerfile b/website_gale_shapley/front/Dockerfile new file mode 100644 index 0000000..d4cbf72 --- /dev/null +++ b/website_gale_shapley/front/Dockerfile @@ -0,0 +1,58 @@ +FROM node:22-alpine3.19 AS base + +# Install dependencies only when needed +FROM base AS deps +# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. +RUN apk add --no-cache libc6-compat +WORKDIR /app + +# Install dependencies based on the preferred package manager +COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./ +# RUN apk add --no-cache python3 make g++ bash +RUN npm ci + + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Next.js collects completely anonymous telemetry data about general usage. +# Learn more here: https://nextjs.org/telemetry +# Uncomment the following line in case you want to disable telemetry during the build. +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN npm run build + +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app + +ENV NODE_ENV production +# Uncomment the following line in case you want to disable telemetry during runtime. +# ENV NEXT_TELEMETRY_DISABLED 1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public + +# Set the correct permission for prerender cache +RUN mkdir .next +RUN chown nextjs:nodejs .next + +# Automatically leverage output traces to reduce image size +# https://nextjs.org/docs/advanced-features/output-file-tracing +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 50011 + +ENV PORT 50011 + +# server.js is created by next build from the standalone output +# https://nextjs.org/docs/pages/api-reference/next-config-js/output +CMD HOSTNAME="0.0.0.0" node server.js diff --git a/website_gale_shapley/front/README.md b/website_gale_shapley/front/README.md new file mode 100644 index 0000000..c403366 --- /dev/null +++ b/website_gale_shapley/front/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/website_gale_shapley/front/app/globals.css b/website_gale_shapley/front/app/globals.css new file mode 100644 index 0000000..99a7b0c --- /dev/null +++ b/website_gale_shapley/front/app/globals.css @@ -0,0 +1,69 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 222.2 84% 4.9%; + --radius: 0.5rem; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + } + + .dark { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + --ring: 212.7 26.8% 83.9%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} \ No newline at end of file diff --git a/website_gale_shapley/front/app/layout.tsx b/website_gale_shapley/front/app/layout.tsx new file mode 100644 index 0000000..2d08670 --- /dev/null +++ b/website_gale_shapley/front/app/layout.tsx @@ -0,0 +1,22 @@ +import type { Metadata } from "next"; +import { Inter } from "next/font/google"; +import "./globals.css"; + +const inter = Inter({ subsets: ["latin"] }); + +export const metadata: Metadata = { + title: "Create Next App", + description: "Generated by create next app", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + {children} + + ); +} diff --git a/website_gale_shapley/front/app/page.tsx b/website_gale_shapley/front/app/page.tsx new file mode 100644 index 0000000..42ca894 --- /dev/null +++ b/website_gale_shapley/front/app/page.tsx @@ -0,0 +1,32 @@ +import AllocationForm from "@/components/AllocationForm"; +import Link from "next/link"; + +export default async function Home() { + return ( +
+

+ Course allocation: Gale-Shapley protocol +

+ + This algorithm is based on the following paper: +
+ "Course bidding at business schools", by Tayfun Sönmez and M. Utku Ünver (2010) +
+ Programmed by: Zachi Ben Shitrit +
+
+ This form allows you to allocate courses to students based on the Gale-Shapley algorithm. + Please provide the following data: + + After filling out the form, the Gale-Shapley algorithm will process the data to allocate courses to students based on their preferences and the provided constraints. +
+ +
+ ); +} diff --git a/website_gale_shapley/front/components.json b/website_gale_shapley/front/components.json new file mode 100644 index 0000000..15f2b02 --- /dev/null +++ b/website_gale_shapley/front/components.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "app/globals.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils" + } +} \ No newline at end of file diff --git a/website_gale_shapley/front/components/AllocationForm.tsx b/website_gale_shapley/front/components/AllocationForm.tsx new file mode 100644 index 0000000..ea49f45 --- /dev/null +++ b/website_gale_shapley/front/components/AllocationForm.tsx @@ -0,0 +1,147 @@ +"use client"; +import clsx from "clsx"; +import { Textarea } from "./ui/textarea"; +import { useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "./ui/form"; +import { z } from "zod"; +import { Button } from "./ui/button"; +import { CoursePreferences, formSchema } from "@/lib/formSchemas"; +import { submitForm } from "@/lib/actions"; +import { AllocationResult } from "@/lib/formSchemas"; +import { AllocationResultDialog } from "./AllocationResultDialog"; +import { useState } from "react"; + +export default function AllocationForm({ className }: { className?: string }) { + const [result, setResult] = useState(); + const [open, setOpen] = useState(false); + + // Define your form. + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + courseCapabilities: "", + agentCapabilities: "", + bids: "", + courseOrderPerStudent: "", + tieBrakingLottery: "", + }, + }); + + // Define a submit handler. + async function onSubmit(values: z.infer) { + try { + const temp = await submitForm(values); + console.log(temp); + setResult(temp); + setOpen(true); + } catch (error) { + console.error("Error submitting form:", error); + } + } + + // Set example values for the form fields + function handleDefaultValuesExample() { + form.setValue("courseCapabilities", '{"Course1": 4, "Course2": 4, "Course3": 2, "Course4": 3, "Course5": 2}'); + form.setValue("agentCapabilities", '{"Alice": 3, "Bob": 3, "Chana": 3, "Dana": 3, "Dor": 3}'); + form.setValue("bids", '{"Alice": {"Course1": 20, "Course2": 15, "Course3": 35, "Course4": 10, "Course5": 20}, "Bob": {"Course1": 30, "Course2": 15, "Course3": 20, "Course4": 20, "Course5": 15}, "Chana": {"Course1": 40, "Course2": 10, "Course3": 25, "Course4": 10, "Course5": 15}, "Dana": {"Course1": 10, "Course2": 10, "Course3": 15, "Course4": 30, "Course5": 35}, "Dor": {"Course1": 25, "Course2": 20, "Course3": 30, "Course4": 10, "Course5": 15}}'); + form.setValue("courseOrderPerStudent", '{"Alice": ["Course5", "Course3", "Course1", "Course2", "Course4"], "Bob": ["Course1", "Course4", "Course5", "Course2", "Course3"], "Chana": ["Course5", "Course1", "Course4", "Course3", "Course2"], "Dana": ["Course3", "Course4", "Course1", "Course5", "Course2"], "Dor": ["Course5", "Course1", "Course4", "Course3", "Course2"]}'); + form.setValue("tieBrakingLottery", '{"Alice": 0.6, "Bob": 0.4, "Chana": 0.3, "Dana": 0.8, "Dor": 0.2}'); + } + + // Clear all form fields + function handleClearForm() { + form.setValue("courseCapabilities", ""); + form.setValue("agentCapabilities", ""); + form.setValue("bids", ""); + form.setValue("courseOrderPerStudent", ""); + form.setValue("tieBrakingLottery", ""); + } + + return ( +
+
+ + +
+ +
+ + ( + + Courses and Capacities + +