diff --git a/.gitignore b/.gitignore index 72553c2..2b4eba9 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,6 @@ investment_results_Facility_1_2019-06-03.csv investment_results_Facility_KoeBogen_2019-06-03.csv !/Cache/pv_loads.pkl -!/Cache/pv_loads.pkl \ No newline at end of file +!/Cache/pv_loads.pkl +data/input/ACN_Caltech_Charging_Data/.Rapp.history +data/input/Parking_Data/Bucerius Passage Hamburg 2020.xlsx diff --git a/Learning_Pricing.py b/Learning_Pricing.py new file mode 100644 index 0000000..9018bcd --- /dev/null +++ b/Learning_Pricing.py @@ -0,0 +1,188 @@ +from resources.configuration.configuration import Configuration +from Utilities.RL_Agents.agents.actor_critic_agents.SAC import ( + SAC, +) +from resources.configuration.SAC_configuration import ( + config, + pricing_config, +) +from Utilities.RL_environments.rl_pricing_env import PricingEnv +from Utilities.sim_input_processing import sample_week +from resources.logging.log import lg +import pandas as pd +import numpy as np + +from run_simulation import run_single_simulation + +SIM_SEASON = Configuration.instance().SIM_SEASON +SUMMER_START = Configuration.instance().SUMMER_START +SUMMER_END = Configuration.instance().SUMMER_END +POST_FIX = Configuration.instance().POST_FIX + +Configuration.instance().dynamic_pricing = True + +evaluate_after_training = Configuration.instance().evaluation_after_training +number_of_chargers = 200 +PV_CAPA = Configuration.instance().PV +STORAGE_CAPA = 0 +max_cap = 50 +max_grid_usage = 2000 +TRANSFORMER_NUM = Configuration.instance().grid + +# config.number_chargers = number_of_chargers +# config.maximum_power = max_cap +# config.maximum_grid_usage = max_grid_usage +# config.environment = ChargingHubInvestmentEnv(config=config) +# config.learnt_network = evaluate_after_training +# agent = SAC(config) +agent = None + +# storage_config.number_chargers = 80 +# storage_config.maximum_power = 50 +# storage_config.maximum_grid_usage = 200 +# storage_config.environment = StorageEnv(config=storage_config) +# storage_config.learnt_network = False +# storage_agent = SAC(storage_config) + +def run_experiments(): + pricing_config.number_chargers = number_of_chargers + pricing_config.maximum_power = max_cap + pricing_config.maximum_grid_usage = max_grid_usage + pricing_config.number_power_options = len(Configuration.instance().energy_prices) + 0 + pricing_config.environment = PricingEnv(config=pricing_config, DQN=False) + pricing_config.learnt_network = evaluate_after_training + pricing_config.evaluation_after_training = evaluate_after_training + + pricing_agent = SAC(pricing_config) + training_results = pd.DataFrame([]) + episode = 1 + NUMBER_EPISODES = 300 + if Configuration.instance().pricing_mode == "perfect_info": + NUMBER_EPISODES = 1 + output = [] + while episode <= NUMBER_EPISODES: + START = sample_week( + sim_seasons=SIM_SEASON, + summer_start=SUMMER_START, + summer_end=SUMMER_END, + seed=42, + ) + print(START) + # week = random.sample(TRAIN_WEEKS, 1) + # week = START + results = None + off_monitoring = True + evaluation_episodes = 10 + time_to_learn = pricing_agent.hyperparameters["min_steps_before_learning"] + if evaluate_after_training: + off_monitoring = False + evaluation_episodes = 1 + results = [f"{POST_FIX}", f"state{9}", f"week{1}"] + time_to_learn = 0 + # chargers = {'fast_one': 5, 'fast_two': 40, 'fast_four': 5, 'slow_one': 5, 'slow_two': 10, 'slow_four': 0} + chargers = { + "fast_one": number_of_chargers, + "fast_two": 0, + "fast_four": 0, + "slow_one": 0, + "slow_two": 0, + "slow_four": 0, + } + lg.error(f"episode: {episode}", extra={"clazz": "", "oid": ""}) + if ( + episode % evaluation_episodes == 0 + and pricing_agent.global_step_number >= time_to_learn + ): + if agent: + agent.do_evaluation_iterations = True + pricing_agent.do_evaluation_iterations = True + ### activate when we have separate battery agent + # storage_agent.do_evaluation_iterations = True + df = run_single_simulation( + charging_agent=agent, + storage_agent=None, + pricing_agent=pricing_agent, + num_charger=chargers, + turn_off_monitoring=False, + turn_on_results=results, + turn_on_plotting=True, + transformer_num=TRANSFORMER_NUM, + storage_capa=STORAGE_CAPA, + pv_capa=PV_CAPA, + year=9, + start_day=START, + ) + pricing_agent.update_lr(new_objective=df["profit"], episode=episode) + print( + pricing_agent.alpha, + pricing_agent.learning_rate_actor, + max(pricing_agent.objective_function), + pricing_agent.hyperparameters["Critic"]["tau"], + pricing_agent.hyperparameters["batch_size"], + pricing_agent.action_size, + ) + else: + if agent: + agent.do_evaluation_iterations = False + pricing_agent.do_evaluation_iterations = False + ### activate when we have separate battery agent + # storage_agent.do_evaluation_iterations = False + df = run_single_simulation( + charging_agent=agent, + storage_agent=None, + pricing_agent=pricing_agent, + num_charger=chargers, + turn_off_monitoring=False, + turn_on_results=results, + turn_on_plotting=True, + transformer_num=TRANSFORMER_NUM, + storage_capa=STORAGE_CAPA, + pv_capa=PV_CAPA, + year=9, + start_day=START, + ) + + episode += 1 + pricing_agent.episode_number += 1 + if not Configuration.instance().evaluation_after_training: + training_results = pd.concat([training_results, df]) + training_results.to_csv(Configuration.instance().OUTPUT_DATA_PATH+ + f"training_results_{pricing_agent.config.name}.csv" + ) + output.append(df["profit"].values[0]) + # print(output) + return output[9:-1:10][-10:] + + +def find_best_parameters(): + try: + training_results = pd.read_csv(f'training_results_{config.path}.csv') + except: + training_results = pd.DataFrame(columns=['learning_rate', 'batch_size', 'tau', 'result']) + training_dict = {} + best_results = -10000000000 + best_parameters = {'learning_rate': 0, 'batch_size': 0, 'tau': 0} + for lr in [5e-5, 1e-4, 5e-4, 1e-3]: + for bs in [64, 256, 512]: + for tau in [0.05, 0.1]: + pricing_config.hyperparameters['batch_size'] = bs + pricing_config.hyperparameters['Actor']['learning_rate'] = lr + pricing_config.hyperparameters['Critic']['learning_rate'] = lr + pricing_config.hyperparameters['Actor']['tau'] = tau + pricing_config.hyperparameters['Critic']['tau'] = tau + pricing_config.hyperparameters['min_steps_before_learning'] = max(bs, 256) + mean_reward = run_experiments() + # print('Mean reward: ', mean_reward) + hyperparameters = {'learning_rate': lr, 'batch_size': bs, 'tau': tau} + if np.array(mean_reward).mean() > best_results: + best_results = np.array(mean_reward).mean() + best_parameters = hyperparameters + results_dict = {'result': mean_reward} + training_results = pd.concat( + [pd.DataFrame([[lr, bs, tau, mean_reward]], columns=training_results.columns), + training_results], ignore_index=True) + print(f'{hyperparameters}, {results_dict}, best: {best_results}, best_parameters: {best_parameters}') + training_results.to_csv(f'{Configuration.instance().OUTPUT_DATA_PATH}training_results_{pricing_config.name}_tuning.csv', index=False) + +find_best_parameters() +# run_experiments() \ No newline at end of file diff --git a/Planning/Scaled_Avg_Hourly_Load.csv b/Planning/Scaled_Avg_Hourly_Load.csv deleted file mode 100644 index 2bc1f9f..0000000 --- a/Planning/Scaled_Avg_Hourly_Load.csv +++ /dev/null @@ -1,2017 +0,0 @@ -,month,hour,kW,kWScaled,SiteID -0,1,0,248.27956989247312,621.1876640419947,Facility_1 -1,1,1,231.72043010752688,579.757217847769,Facility_1 -2,1,2,225.05376344086022,563.0774278215223,Facility_1 -3,1,3,224.56989247311827,561.8667979002624,Facility_1 -4,1,4,267.1505376344086,668.4022309711286,Facility_1 -5,1,5,281.02150537634407,703.1069553805773,Facility_1 -6,1,6,367.63440860215053,919.8097112860892,Facility_1 -7,1,7,397.741935483871,995.1377952755905,Facility_1 -8,1,8,427.9032258064516,1070.6003937007874,Facility_1 -9,1,9,431.55913978494624,1079.747375328084,Facility_1 -10,1,10,437.31182795698925,1094.1404199475066,Facility_1 -11,1,11,436.18279569892474,1091.3156167979002,Facility_1 -12,1,12,436.7204301075269,1092.6607611548557,Facility_1 -13,1,13,440.59139784946234,1102.3458005249342,Facility_1 -14,1,14,440.16129032258067,1101.2696850393702,Facility_1 -15,1,15,438.6559139784946,1097.5032808398948,Facility_1 -16,1,16,438.8709677419355,1098.041338582677,Facility_1 -17,1,17,440.16129032258067,1101.2696850393702,Facility_1 -18,1,18,438.2258064516129,1096.4271653543308,Facility_1 -19,1,19,438.1720430107527,1096.2926509186352,Facility_1 -20,1,20,426.8279569892473,1067.9101049868766,Facility_1 -21,1,21,410.64516129032256,1027.4212598425197,Facility_1 -22,1,22,348.44086021505376,871.7880577427821,Facility_1 -23,1,23,314.89247311827955,787.8510498687664,Facility_1 -24,2,0,238.33333333333334,596.3024934383202,Facility_1 -25,2,1,219.3452380952381,548.7948772028496,Facility_1 -26,2,2,214.9404761904762,537.7743016497938,Facility_1 -27,2,3,211.9047619047619,530.179040119985,Facility_1 -28,2,4,258.57142857142856,646.937570303712,Facility_1 -29,2,5,276.7857142857143,692.5091394825647,Facility_1 -30,2,6,366.01190476190476,915.7502577802775,Facility_1 -31,2,7,391.48809523809524,979.490883952006,Facility_1 -32,2,8,422.26190476190476,1056.4859861267341,Facility_1 -33,2,9,433.92857142857144,1085.675618672666,Facility_1 -34,2,10,430.6547619047619,1077.4846503562055,Facility_1 -35,2,11,430.35714285714283,1076.740016872891,Facility_1 -36,2,12,430.6547619047619,1077.4846503562055,Facility_1 -37,2,13,431.07142857142856,1078.527137232846,Facility_1 -38,2,14,429.82142857142856,1075.3996766029245,Facility_1 -39,2,15,426.3690476190476,1066.7619281964753,Facility_1 -40,2,16,422.26190476190476,1056.4859861267341,Facility_1 -41,2,17,426.60714285714283,1067.3576349831271,Facility_1 -42,2,18,427.67857142857144,1070.0383155230597,Facility_1 -43,2,19,424.5238095238095,1062.145200599925,Facility_1 -44,2,20,414.04761904761904,1035.9341019872516,Facility_1 -45,2,21,400.6547619047619,1002.4255952380953,Facility_1 -46,2,22,342.9761904761905,858.1156261717285,Facility_1 -47,2,23,301.7857142857143,755.0583520809898,Facility_1 -48,3,0,223.1720430107527,558.3694225721786,Facility_1 -49,3,1,203.44086021505376,509.002624671916,Facility_1 -50,3,2,196.88888888888889,492.6097987751531,Facility_1 -51,3,3,196.88172043010752,492.59186351706035,Facility_1 -52,3,4,240.48387096774192,601.6830708661417,Facility_1 -53,3,5,257.4731182795699,644.1896325459318,Facility_1 -54,3,6,350.6989247311828,877.4376640419947,Facility_1 -55,3,7,378.2258064516129,946.3090551181103,Facility_1 -56,3,8,410.752688172043,1027.6902887139108,Facility_1 -57,3,9,416.8817204301075,1043.024934383202,Facility_1 -58,3,10,412.5268817204301,1032.1292650918635,Facility_1 -59,3,11,411.3440860215054,1029.1699475065618,Facility_1 -60,3,12,412.36559139784947,1031.7257217847769,Facility_1 -61,3,13,413.1182795698925,1033.6089238845145,Facility_1 -62,3,14,414.247311827957,1036.4337270341207,Facility_1 -63,3,15,412.258064516129,1031.4566929133857,Facility_1 -64,3,16,410.80645161290323,1027.8248031496064,Facility_1 -65,3,17,411.61290322580646,1029.8425196850394,Facility_1 -66,3,18,410.64516129032256,1027.4212598425197,Facility_1 -67,3,19,409.13978494623655,1023.6548556430446,Facility_1 -68,3,20,397.63440860215053,994.8687664041995,Facility_1 -69,3,21,382.2043010752688,956.26312335958,Facility_1 -70,3,22,320.6989247311828,802.3786089238845,Facility_1 -71,3,23,292.1505376344086,730.9514435695537,Facility_1 -72,4,0,215.72222222222223,539.7302055993001,Facility_1 -73,4,1,196.72222222222223,492.192804024497,Facility_1 -74,4,2,190.38888888888889,476.34700349956256,Facility_1 -75,4,3,187.66666666666666,469.53608923884514,Facility_1 -76,4,4,228.0,570.4488188976378,Facility_1 -77,4,5,241.94444444444446,605.3373797025372,Facility_1 -78,4,6,326.8888888888889,817.8657042869642,Facility_1 -79,4,7,354.27777777777777,886.3918416447943,Facility_1 -80,4,8,386.55555555555554,967.1498250218723,Facility_1 -81,4,9,393.22222222222223,983.829615048119,Facility_1 -82,4,10,395.1666666666667,988.6945538057744,Facility_1 -83,4,11,402.3333333333333,1006.6253280839894,Facility_1 -84,4,12,407.6111111111111,1019.8301618547681,Facility_1 -85,4,13,414.0,1035.8149606299212,Facility_1 -86,4,14,415.6666666666667,1039.984908136483,Facility_1 -87,4,15,413.1111111111111,1033.5909886264217,Facility_1 -88,4,16,415.55555555555554,1039.7069116360456,Facility_1 -89,4,17,418.72222222222223,1047.6298118985128,Facility_1 -90,4,18,411.55555555555554,1029.6990376202975,Facility_1 -91,4,19,409.8333333333333,1025.390091863517,Facility_1 -92,4,20,393.72222222222223,985.0805993000876,Facility_1 -93,4,21,375.22222222222223,938.7941819772528,Facility_1 -94,4,22,315.6111111111111,789.6490594925633,Facility_1 -95,4,23,284.55555555555554,711.9490376202974,Facility_1 -96,5,0,232.25806451612902,581.1023622047244,Facility_1 -97,5,1,204.03225806451613,510.48228346456693,Facility_1 -98,5,2,199.247311827957,498.51049868766404,Facility_1 -99,5,3,194.19354838709677,485.86614173228344,Facility_1 -100,5,4,235.86021505376345,590.1148293963255,Facility_1 -101,5,5,245.21505376344086,613.5203412073491,Facility_1 -102,5,6,329.4623655913978,824.3044619422571,Facility_1 -103,5,7,364.73118279569894,912.5459317585302,Facility_1 -104,5,8,397.5806451612903,994.7342519685039,Facility_1 -105,5,9,414.5698924731183,1037.2408136482939,Facility_1 -106,5,10,426.55913978494624,1067.237532808399,Facility_1 -107,5,11,436.1290322580645,1091.1811023622047,Facility_1 -108,5,12,443.1720430107527,1108.8024934383202,Facility_1 -109,5,13,450.10752688172045,1126.1548556430446,Facility_1 -110,5,14,453.3333333333333,1134.2257217847769,Facility_1 -111,5,15,453.9247311827957,1135.7053805774278,Facility_1 -112,5,16,455.59139784946234,1139.8753280839894,Facility_1 -113,5,17,455.80645161290323,1140.4133858267717,Facility_1 -114,5,18,455.86021505376345,1140.5479002624672,Facility_1 -115,5,19,451.23655913978496,1128.979658792651,Facility_1 -116,5,20,436.8279569892473,1092.9297900262468,Facility_1 -117,5,21,417.5268817204301,1044.6391076115485,Facility_1 -118,5,22,342.0967741935484,855.9153543307087,Facility_1 -119,5,23,308.38709677419354,771.5748031496063,Facility_1 -120,6,0,267.72222222222223,669.8325678040245,Facility_1 -121,6,1,229.11111111111111,573.2287839020123,Facility_1 -122,6,2,217.38888888888889,543.9001531058617,Facility_1 -123,6,3,217.88888888888889,545.1511373578303,Facility_1 -124,6,4,263.3333333333333,658.8517060367453,Facility_1 -125,6,5,284.8888888888889,712.7830271216098,Facility_1 -126,6,6,387.0,968.261811023622,Facility_1 -127,6,7,442.55555555555554,1107.2600612423446,Facility_1 -128,6,8,478.5,1197.1919291338584,Facility_1 -129,6,9,494.8888888888889,1238.1964129483815,Facility_1 -130,6,10,505.6666666666667,1265.1620734908138,Facility_1 -131,6,11,517.2777777777778,1294.2127077865268,Facility_1 -132,6,12,528.6666666666666,1322.7073490813648,Facility_1 -133,6,13,534.0,1336.0511811023623,Facility_1 -134,6,14,542.1111111111111,1356.3449256342956,Facility_1 -135,6,15,543.3888888888889,1359.5418853893264,Facility_1 -136,6,16,545.7777777777778,1365.5188101487315,Facility_1 -137,6,17,552.4444444444445,1382.198600174978,Facility_1 -138,6,18,550.7222222222222,1377.8896544181976,Facility_1 -139,6,19,547.5555555555555,1369.9667541557305,Facility_1 -140,6,20,530.3888888888889,1327.0162948381453,Facility_1 -141,6,21,502.94444444444446,1258.3511592300963,Facility_1 -142,6,22,397.05555555555554,993.4204943132108,Facility_1 -143,6,23,358.27777777777777,896.3997156605424,Facility_1 -144,7,0,271.6666666666667,679.7014435695538,Facility_1 -145,7,1,235.91397849462365,590.2493438320209,Facility_1 -146,7,2,220.21505376344086,550.9711286089239,Facility_1 -147,7,3,216.0215053763441,540.4790026246719,Facility_1 -148,7,4,265.26881720430106,663.6942257217847,Facility_1 -149,7,5,291.2903225806452,728.7992125984252,Facility_1 -150,7,6,401.98924731182797,1005.764435695538,Facility_1 -151,7,7,468.6559139784946,1172.5623359580052,Facility_1 -152,7,8,498.9247311827957,1248.293963254593,Facility_1 -153,7,9,518.2795698924731,1296.7191601049867,Facility_1 -154,7,10,523.7096774193549,1310.3051181102362,Facility_1 -155,7,11,531.9354838709677,1330.8858267716535,Facility_1 -156,7,12,539.3548387096774,1349.448818897638,Facility_1 -157,7,13,550.0537634408602,1376.2171916010498,Facility_1 -158,7,14,552.0967741935484,1381.3287401574803,Facility_1 -159,7,15,555.9677419354839,1391.013779527559,Facility_1 -160,7,16,557.2043010752689,1394.1076115485566,Facility_1 -161,7,17,560.5913978494624,1402.5820209973754,Facility_1 -162,7,18,556.989247311828,1393.5695538057744,Facility_1 -163,7,19,552.4731182795699,1382.2703412073492,Facility_1 -164,7,20,535.752688172043,1340.4363517060367,Facility_1 -165,7,21,505.752688172043,1265.3772965879266,Facility_1 -166,7,22,408.01075268817203,1020.8300524934383,Facility_1 -167,7,23,370.80645161290323,927.746062992126,Facility_1 -168,8,0,261.4516129032258,654.1437007874015,Facility_1 -169,8,1,230.69892473118279,577.2014435695538,Facility_1 -170,8,2,213.49462365591398,534.1568241469816,Facility_1 -171,8,3,208.33333333333334,521.24343832021,Facility_1 -172,8,4,253.70967741935485,634.7736220472441,Facility_1 -173,8,5,278.3333333333333,696.3812335958005,Facility_1 -174,8,6,381.55913978494624,954.6489501312336,Facility_1 -175,8,7,447.63440860215053,1119.9671916010498,Facility_1 -176,8,8,481.3440860215054,1204.3077427821522,Facility_1 -177,8,9,495.3225806451613,1239.2814960629921,Facility_1 -178,8,10,504.3010752688172,1261.745406824147,Facility_1 -179,8,11,518.0645161290323,1296.181102362205,Facility_1 -180,8,12,532.0967741935484,1331.2893700787401,Facility_1 -181,8,13,541.989247311828,1356.0400262467192,Facility_1 -182,8,14,548.763440860215,1372.988845144357,Facility_1 -183,8,15,551.8817204301075,1380.790682414698,Facility_1 -184,8,16,546.6129032258065,1367.6082677165355,Facility_1 -185,8,17,548.1720430107526,1371.509186351706,Facility_1 -186,8,18,542.3655913978495,1356.981627296588,Facility_1 -187,8,19,534.7849462365591,1338.015091863517,Facility_1 -188,8,20,513.8172043010753,1285.5544619422574,Facility_1 -189,8,21,487.741935483871,1220.3149606299212,Facility_1 -190,8,22,390.86021505376345,977.9199475065617,Facility_1 -191,8,23,352.9032258064516,882.9527559055117,Facility_1 -192,9,0,237.88888888888889,595.1905074365704,Facility_1 -193,9,1,221.44444444444446,554.0470253718286,Facility_1 -194,9,2,202.27777777777777,506.0926290463692,Facility_1 -195,9,3,202.72222222222223,507.204615048119,Facility_1 -196,9,4,243.44444444444446,609.0903324584427,Facility_1 -197,9,5,253.05555555555554,633.1370297462817,Facility_1 -198,9,6,358.94444444444446,898.0676946631671,Facility_1 -199,9,7,389.05555555555554,973.4047462817148,Facility_1 -200,9,8,408.55555555555554,1022.1931321084865,Facility_1 -201,9,9,414.94444444444446,1038.1779308836396,Facility_1 -202,9,10,424.6111111111111,1062.3636264216973,Facility_1 -203,9,11,440.72222222222223,1102.6731189851268,Facility_1 -204,9,12,451.5,1129.638779527559,Facility_1 -205,9,13,456.72222222222223,1142.704615048119,Facility_1 -206,9,14,455.94444444444446,1140.758639545057,Facility_1 -207,9,15,458.6666666666667,1147.5695538057744,Facility_1 -208,9,16,460.6111111111111,1152.4344925634296,Facility_1 -209,9,17,456.44444444444446,1142.0096237970254,Facility_1 -210,9,18,452.8888888888889,1133.113735783027,Facility_1 -211,9,19,444.6111111111111,1112.4029965004374,Facility_1 -212,9,20,426.8888888888889,1068.062554680665,Facility_1 -213,9,21,405.3333333333333,1014.1312335958005,Facility_1 -214,9,22,335.22222222222223,838.7154418197725,Facility_1 -215,9,23,304.8888888888889,762.82239720035,Facility_1 -216,10,0,234.6031746031746,586.9697537807774,Facility_1 -217,10,1,210.6451612903226,527.0275590551181,Facility_1 -218,10,2,196.61290322580646,491.9192913385827,Facility_1 -219,10,3,195.7258064516129,489.6998031496063,Facility_1 -220,10,4,242.58064516129033,606.9291338582677,Facility_1 -221,10,5,250.16129032258064,625.8956692913385,Facility_1 -222,10,6,356.85483870967744,892.8395669291339,Facility_1 -223,10,7,384.51612903225805,962.0472440944882,Facility_1 -224,10,8,405.64516129032256,1014.9114173228346,Facility_1 -225,10,9,401.2903225806452,1004.0157480314961,Facility_1 -226,10,10,409.51612903225805,1024.5964566929133,Facility_1 -227,10,11,414.6774193548387,1037.509842519685,Facility_1 -228,10,12,420.4032258064516,1051.8356299212599,Facility_1 -229,10,13,423.6290322580645,1059.9064960629921,Facility_1 -230,10,14,423.06451612903226,1058.494094488189,Facility_1 -231,10,15,422.741935483871,1057.6870078740158,Facility_1 -232,10,16,423.2258064516129,1058.8976377952756,Facility_1 -233,10,17,425.16129032258067,1063.740157480315,Facility_1 -234,10,18,420.241935483871,1051.4320866141732,Facility_1 -235,10,19,413.46774193548384,1034.4832677165355,Facility_1 -236,10,20,400.64516129032256,1002.4015748031495,Facility_1 -237,10,21,383.5483870967742,959.6259842519686,Facility_1 -238,10,22,321.69354838709677,804.867125984252,Facility_1 -239,10,23,296.0483870967742,740.7037401574803,Facility_1 -240,11,0,224.33333333333334,561.2749343832021,Facility_1 -241,11,1,204.41666666666666,511.44406167979,Facility_1 -242,11,2,198.41666666666666,496.432250656168,Facility_1 -243,11,3,199.66666666666666,499.5597112860892,Facility_1 -244,11,4,241.83333333333334,605.0593832020998,Facility_1 -245,11,5,254.75,637.3764763779527,Facility_1 -246,11,6,359.0833333333333,898.4151902887139,Facility_1 -247,11,7,379.4166666666667,949.2885498687665,Facility_1 -248,11,8,390.8333333333333,977.8526902887139,Facility_1 -249,11,9,386.1666666666667,966.1768372703413,Facility_1 -250,11,10,387.5,969.5127952755905,Facility_1 -251,11,11,389.9166666666667,975.559219160105,Facility_1 -252,11,12,393.0,983.2736220472441,Facility_1 -253,11,13,396.9166666666667,993.072998687664,Facility_1 -254,11,14,404.8333333333333,1012.880249343832,Facility_1 -255,11,15,401.5,1004.5403543307086,Facility_1 -256,11,16,396.0,990.7795275590552,Facility_1 -257,11,17,396.75,992.6560039370079,Facility_1 -258,11,18,398.4166666666667,996.8259514435696,Facility_1 -259,11,19,398.1666666666667,996.2004593175853,Facility_1 -260,11,20,384.5,962.0068897637796,Facility_1 -261,11,21,371.0,928.2303149606299,Facility_1 -262,11,22,311.5833333333333,779.571686351706,Facility_1 -263,11,23,287.9166666666667,720.3584317585303,Facility_1 -264,12,0,252.09677419354838,630.738188976378,Facility_1 -265,12,1,233.8709677419355,585.1377952755905,Facility_1 -266,12,2,230.40322580645162,576.4616141732283,Facility_1 -267,12,3,226.69354838709677,567.1801181102362,Facility_1 -268,12,4,270.7258064516129,677.3474409448819,Facility_1 -269,12,5,283.7096774193548,709.8326771653543,Facility_1 -270,12,6,387.741935483871,970.1181102362204,Facility_1 -271,12,7,416.53225806451616,1042.1505905511813,Facility_1 -272,12,8,421.7741935483871,1055.265748031496,Facility_1 -273,12,9,422.66129032258067,1057.4852362204724,Facility_1 -274,12,10,422.741935483871,1057.6870078740158,Facility_1 -275,12,11,427.8225806451613,1070.398622047244,Facility_1 -276,12,12,427.98387096774195,1070.8021653543308,Facility_1 -277,12,13,432.33870967741933,1081.6978346456692,Facility_1 -278,12,14,432.5806451612903,1082.3031496062993,Facility_1 -279,12,15,427.741935483871,1070.1968503937007,Facility_1 -280,12,16,434.11290322580646,1086.1368110236222,Facility_1 -281,12,17,431.3709677419355,1079.2765748031495,Facility_1 -282,12,18,427.9032258064516,1070.6003937007874,Facility_1 -283,12,19,427.33870967741933,1069.1879921259842,Facility_1 -284,12,20,417.741935483871,1045.1771653543308,Facility_1 -285,12,21,405.4032258064516,1014.3061023622047,Facility_1 -286,12,22,345.48387096774195,864.3897637795276,Facility_1 -287,12,23,314.2741935483871,786.3041338582676,Facility_1 -0,1,0,248.27956989247312,134.89204978409958,Facility_2 -1,1,1,231.72043010752688,125.89535179070359,Facility_2 -2,1,2,225.05376344086022,122.27330454660911,Facility_2 -3,1,3,224.56989247311827,122.01041402082805,Facility_2 -4,1,4,267.1505376344086,145.14478028956057,Facility_2 -5,1,5,281.02150537634407,152.68097536195071,Facility_2 -6,1,6,367.63440860215053,199.73837947675895,Facility_2 -7,1,7,397.741935483871,216.0960121920244,Facility_2 -8,1,8,427.9032258064516,232.48285496570992,Facility_2 -9,1,9,431.55913978494624,234.4691389382779,Facility_2 -10,1,10,437.31182795698925,237.59461518923038,Facility_2 -11,1,11,436.18279569892474,236.98120396240793,Facility_2 -12,1,12,436.7204301075269,237.27330454660913,Facility_2 -13,1,13,440.59139784946234,239.3764287528575,Facility_2 -14,1,14,440.16129032258067,239.1427482854966,Facility_2 -15,1,15,438.6559139784946,238.3248666497333,Facility_2 -16,1,16,438.8709677419355,238.4417068834138,Facility_2 -17,1,17,440.16129032258067,239.1427482854966,Facility_2 -18,1,18,438.2258064516129,238.09118618237238,Facility_2 -19,1,19,438.1720430107527,238.06197612395226,Facility_2 -20,1,20,426.8279569892473,231.8986537973076,Facility_2 -21,1,21,410.64516129032256,223.10642621285243,Facility_2 -22,1,22,348.44086021505376,189.31038862077725,Facility_2 -23,1,23,314.89247311827955,171.08331216662432,Facility_2 -24,2,0,238.33333333333334,129.48818897637796,Facility_2 -25,2,1,219.3452380952381,119.17182227221599,Facility_2 -26,2,2,214.9404761904762,116.7786839145107,Facility_2 -27,2,3,211.9047619047619,115.12935883014623,Facility_2 -28,2,4,258.57142857142856,140.48368953880765,Facility_2 -29,2,5,276.7857142857143,150.37964004499437,Facility_2 -30,2,6,366.01190476190476,198.85686164229472,Facility_2 -31,2,7,391.48809523809524,212.69825646794152,Facility_2 -32,2,8,422.26190476190476,229.41788526434198,Facility_2 -33,2,9,433.92857142857144,235.75646794150734,Facility_2 -34,2,10,430.6547619047619,233.97778402699666,Facility_2 -35,2,11,430.35714285714283,233.81608548931385,Facility_2 -36,2,12,430.6547619047619,233.97778402699666,Facility_2 -37,2,13,431.07142857142856,234.20416197975254,Facility_2 -38,2,14,429.82142857142856,233.5250281214848,Facility_2 -39,2,15,426.3690476190476,231.64932508436445,Facility_2 -40,2,16,422.26190476190476,229.41788526434198,Facility_2 -41,2,17,426.60714285714283,231.77868391451068,Facility_2 -42,2,18,427.67857142857144,232.36079865016876,Facility_2 -43,2,19,424.5238095238095,230.64679415073118,Facility_2 -44,2,20,414.04761904761904,224.95500562429697,Facility_2 -45,2,21,400.6547619047619,217.67857142857144,Facility_2 -46,2,22,342.9761904761905,186.3413948256468,Facility_2 -47,2,23,301.7857142857143,163.96231721034871,Facility_2 -48,3,0,223.1720430107527,121.25095250190502,Facility_2 -49,3,1,203.44086021505376,110.53086106172213,Facility_2 -50,3,2,196.88888888888889,106.97112860892389,Facility_2 -51,3,3,196.88172043010752,106.96723393446787,Facility_2 -52,3,4,240.48387096774192,130.65659131318262,Facility_2 -53,3,5,257.4731182795699,139.88696977393957,Facility_2 -54,3,6,350.6989247311828,190.53721107442215,Facility_2 -55,3,7,378.2258064516129,205.49276098552198,Facility_2 -56,3,8,410.752688172043,223.16484632969266,Facility_2 -57,3,9,416.8817204301075,226.494792989586,Facility_2 -58,3,10,412.5268817204301,224.12877825755652,Facility_2 -59,3,11,411.3440860215054,223.48615697231398,Facility_2 -60,3,12,412.36559139784947,224.0411480822962,Facility_2 -61,3,13,413.1182795698925,224.45008890017783,Facility_2 -62,3,14,414.247311827957,225.06350012700028,Facility_2 -63,3,15,412.258064516129,223.98272796545595,Facility_2 -64,3,16,410.80645161290323,223.19405638811278,Facility_2 -65,3,17,411.61290322580646,223.63220726441455,Facility_2 -66,3,18,410.64516129032256,223.10642621285243,Facility_2 -67,3,19,409.13978494623655,222.28854457708917,Facility_2 -68,3,20,397.63440860215053,216.03759207518416,Facility_2 -69,3,21,382.2043010752688,207.65430530861062,Facility_2 -70,3,22,320.6989247311828,174.23799847599696,Facility_2 -71,3,23,292.1505376344086,158.7274574549149,Facility_2 -72,4,0,215.72222222222223,117.20341207349082,Facility_2 -73,4,1,196.72222222222223,106.88057742782154,Facility_2 -74,4,2,190.38888888888889,103.43963254593176,Facility_2 -75,4,3,187.66666666666666,101.96062992125984,Facility_2 -76,4,4,228.0,123.87401574803151,Facility_2 -77,4,5,241.94444444444446,131.4501312335958,Facility_2 -78,4,6,326.8888888888889,177.60104986876644,Facility_2 -79,4,7,354.27777777777777,192.48162729658793,Facility_2 -80,4,8,386.55555555555554,210.01837270341207,Facility_2 -81,4,9,393.22222222222223,213.6404199475066,Facility_2 -82,4,10,395.1666666666667,214.6968503937008,Facility_2 -83,4,11,402.3333333333333,218.59055118110237,Facility_2 -84,4,12,407.6111111111111,221.45800524934384,Facility_2 -85,4,13,414.0,224.92913385826773,Facility_2 -86,4,14,415.6666666666667,225.83464566929138,Facility_2 -87,4,15,413.1111111111111,224.4461942257218,Facility_2 -88,4,16,415.55555555555554,225.7742782152231,Facility_2 -89,4,17,418.72222222222223,227.494750656168,Facility_2 -90,4,18,411.55555555555554,223.6010498687664,Facility_2 -91,4,19,409.8333333333333,222.66535433070865,Facility_2 -92,4,20,393.72222222222223,213.91207349081367,Facility_2 -93,4,21,375.22222222222223,203.86089238845145,Facility_2 -94,4,22,315.6111111111111,171.4737532808399,Facility_2 -95,4,23,284.55555555555554,154.6010498687664,Facility_2 -96,5,0,232.25806451612902,126.18745237490475,Facility_2 -97,5,1,204.03225806451613,110.85217170434342,Facility_2 -98,5,2,199.247311827957,108.25247650495302,Facility_2 -99,5,3,194.19354838709677,105.50673101346203,Facility_2 -100,5,4,235.86021505376345,128.1445262890526,Facility_2 -101,5,5,245.21505376344086,133.22707645415292,Facility_2 -102,5,6,329.4623655913978,178.999237998476,Facility_2 -103,5,7,364.73118279569894,198.16103632207268,Facility_2 -104,5,8,397.5806451612903,216.00838201676405,Facility_2 -105,5,9,414.5698924731183,225.23876047752097,Facility_2 -106,5,10,426.55913978494624,231.75260350520702,Facility_2 -107,5,11,436.1290322580645,236.9519939039878,Facility_2 -108,5,12,443.1720430107527,240.77851155702314,Facility_2 -109,5,13,450.10752688172045,244.54660909321822,Facility_2 -110,5,14,453.3333333333333,246.2992125984252,Facility_2 -111,5,15,453.9247311827957,246.6205232410465,Facility_2 -112,5,16,455.59139784946234,247.5260350520701,Facility_2 -113,5,17,455.80645161290323,247.6428752857506,Facility_2 -114,5,18,455.86021505376345,247.6720853441707,Facility_2 -115,5,19,451.23655913978496,245.16002032004067,Facility_2 -116,5,20,436.8279569892473,237.33172466344934,Facility_2 -117,5,21,417.5268817204301,226.8453136906274,Facility_2 -118,5,22,342.0967741935484,185.86360172720347,Facility_2 -119,5,23,308.38709677419354,167.5488950977902,Facility_2 -120,6,0,267.72222222222223,145.45538057742783,Facility_2 -121,6,1,229.11111111111111,124.47769028871392,Facility_2 -122,6,2,217.38888888888889,118.10892388451444,Facility_2 -123,6,3,217.88888888888889,118.38057742782152,Facility_2 -124,6,4,263.3333333333333,143.0708661417323,Facility_2 -125,6,5,284.8888888888889,154.78215223097115,Facility_2 -126,6,6,387.0,210.25984251968507,Facility_2 -127,6,7,442.55555555555554,240.4435695538058,Facility_2 -128,6,8,478.5,259.9724409448819,Facility_2 -129,6,9,494.8888888888889,268.87664041994753,Facility_2 -130,6,10,505.6666666666667,274.73228346456693,Facility_2 -131,6,11,517.2777777777778,281.0406824146982,Facility_2 -132,6,12,528.6666666666666,287.2283464566929,Facility_2 -133,6,13,534.0,290.12598425196853,Facility_2 -134,6,14,542.1111111111111,294.5328083989501,Facility_2 -135,6,15,543.3888888888889,295.2270341207349,Facility_2 -136,6,16,545.7777777777778,296.52493438320215,Facility_2 -137,6,17,552.4444444444445,300.1469816272966,Facility_2 -138,6,18,550.7222222222222,299.21128608923885,Facility_2 -139,6,19,547.5555555555555,297.49081364829397,Facility_2 -140,6,20,530.3888888888889,288.1640419947507,Facility_2 -141,6,21,502.94444444444446,273.253280839895,Facility_2 -142,6,22,397.05555555555554,215.7230971128609,Facility_2 -143,6,23,358.27777777777777,194.65485564304464,Facility_2 -144,7,0,271.6666666666667,147.5984251968504,Facility_2 -145,7,1,235.91397849462365,128.1737363474727,Facility_2 -146,7,2,220.21505376344086,119.64439928879858,Facility_2 -147,7,3,216.0215053763441,117.36601473202947,Facility_2 -148,7,4,265.26881720430106,144.12242824485648,Facility_2 -149,7,5,291.2903225806452,158.26009652019306,Facility_2 -150,7,6,401.98924731182797,218.40360680721363,Facility_2 -151,7,7,468.6559139784946,254.6240792481585,Facility_2 -152,7,8,498.9247311827957,271.0693421386843,Facility_2 -153,7,9,518.2795698924731,281.58496316992637,Facility_2 -154,7,10,523.7096774193549,284.5351790703582,Facility_2 -155,7,11,531.9354838709677,289.004318008636,Facility_2 -156,7,12,539.3548387096774,293.0353060706122,Facility_2 -157,7,13,550.0537634408602,298.8481076962154,Facility_2 -158,7,14,552.0967741935484,299.95808991617986,Facility_2 -159,7,15,555.9677419354839,302.0612141224283,Facility_2 -160,7,16,557.2043010752689,302.73304546609097,Facility_2 -161,7,17,560.5913978494624,304.5732791465583,Facility_2 -162,7,18,556.989247311828,302.6162052324105,Facility_2 -163,7,19,552.4731182795699,300.1625603251207,Facility_2 -164,7,20,535.752688172043,291.0782321564643,Facility_2 -165,7,21,505.752688172043,274.7790195580391,Facility_2 -166,7,22,408.01075268817203,221.67513335026672,Facility_2 -167,7,23,370.80645161290323,201.46177292354585,Facility_2 -168,8,0,261.4516129032258,142.0485140970282,Facility_2 -169,8,1,230.69892473118279,125.34036068072136,Facility_2 -170,8,2,213.49462365591398,115.99314198628399,Facility_2 -171,8,3,208.33333333333334,113.18897637795277,Facility_2 -172,8,4,253.70967741935485,137.84226568453138,Facility_2 -173,8,5,278.3333333333333,151.2204724409449,Facility_2 -174,8,6,381.55913978494624,207.30378460756924,Facility_2 -175,8,7,447.63440860215053,243.20294640589282,Facility_2 -176,8,8,481.3440860215054,261.5176530353061,Facility_2 -177,8,9,495.3225806451613,269.1122682245365,Facility_2 -178,8,10,504.3010752688172,273.99034798069596,Facility_2 -179,8,11,518.0645161290323,281.46812293624595,Facility_2 -180,8,12,532.0967741935484,289.0919481838964,Facility_2 -181,8,13,541.989247311828,294.4665989331979,Facility_2 -182,8,14,548.763440860215,298.1470662941326,Facility_2 -183,8,15,551.8817204301075,299.8412496824994,Facility_2 -184,8,16,546.6129032258065,296.97866395732797,Facility_2 -185,8,17,548.1720430107526,297.8257556515113,Facility_2 -186,8,18,542.3655913978495,294.6710693421387,Facility_2 -187,8,19,534.7849462365591,290.5524511049022,Facility_2 -188,8,20,513.8172043010753,279.1605283210567,Facility_2 -189,8,21,487.741935483871,264.9936499873,Facility_2 -190,8,22,390.86021505376345,212.35712471424944,Facility_2 -191,8,23,352.9032258064516,191.73482346964693,Facility_2 -192,9,0,237.88888888888889,129.246719160105,Facility_2 -193,9,1,221.44444444444446,120.31233595800526,Facility_2 -194,9,2,202.27777777777777,109.8989501312336,Facility_2 -195,9,3,202.72222222222223,110.14041994750657,Facility_2 -196,9,4,243.44444444444446,132.26509186351709,Facility_2 -197,9,5,253.05555555555554,137.48687664041995,Facility_2 -198,9,6,358.94444444444446,195.0170603674541,Facility_2 -199,9,7,389.05555555555554,211.3766404199475,Facility_2 -200,9,8,408.55555555555554,221.9711286089239,Facility_2 -201,9,9,414.94444444444446,225.44225721784778,Facility_2 -202,9,10,424.6111111111111,230.6942257217848,Facility_2 -203,9,11,440.72222222222223,239.4475065616798,Facility_2 -204,9,12,451.5,245.30314960629923,Facility_2 -205,9,13,456.72222222222223,248.1404199475066,Facility_2 -206,9,14,455.94444444444446,247.7178477690289,Facility_2 -207,9,15,458.6666666666667,249.1968503937008,Facility_2 -208,9,16,460.6111111111111,250.253280839895,Facility_2 -209,9,17,456.44444444444446,247.989501312336,Facility_2 -210,9,18,452.8888888888889,246.05774278215225,Facility_2 -211,9,19,444.6111111111111,241.56036745406826,Facility_2 -212,9,20,426.8888888888889,231.93175853018374,Facility_2 -213,9,21,405.3333333333333,220.2204724409449,Facility_2 -214,9,22,335.22222222222223,182.12860892388454,Facility_2 -215,9,23,304.8888888888889,165.64829396325462,Facility_2 -216,10,0,234.6031746031746,127.461567304087,Facility_2 -217,10,1,210.6451612903226,114.44500889001779,Facility_2 -218,10,2,196.61290322580646,106.8211836423673,Facility_2 -219,10,3,195.7258064516129,106.33921767843536,Facility_2 -220,10,4,242.58064516129033,131.7957835915672,Facility_2 -221,10,5,250.16129032258064,135.91440182880368,Facility_2 -222,10,6,356.85483870967744,193.88176276352556,Facility_2 -223,10,7,384.51612903225805,208.91033782067564,Facility_2 -224,10,8,405.64516129032256,220.38989077978155,Facility_2 -225,10,9,401.2903225806452,218.0238760477521,Facility_2 -226,10,10,409.51612903225805,222.49301498602998,Facility_2 -227,10,11,414.6774193548387,225.2971805943612,Facility_2 -228,10,12,420.4032258064516,228.40805181610364,Facility_2 -229,10,13,423.6290322580645,230.16065532131066,Facility_2 -230,10,14,423.06451612903226,229.85394970789943,Facility_2 -231,10,15,422.741935483871,229.67868935737874,Facility_2 -232,10,16,423.2258064516129,229.9415798831598,Facility_2 -233,10,17,425.16129032258067,230.993141986284,Facility_2 -234,10,18,420.241935483871,228.3204216408433,Facility_2 -235,10,19,413.46774193548384,224.63995427990855,Facility_2 -236,10,20,400.64516129032256,217.6733553467107,Facility_2 -237,10,21,383.5483870967742,208.38455676911354,Facility_2 -238,10,22,321.69354838709677,174.7783845567691,Facility_2 -239,10,23,296.0483870967742,160.8451866903734,Facility_2 -240,11,0,224.33333333333334,121.88188976377954,Facility_2 -241,11,1,204.41666666666666,111.06102362204724,Facility_2 -242,11,2,198.41666666666666,107.80118110236221,Facility_2 -243,11,3,199.66666666666666,108.48031496062993,Facility_2 -244,11,4,241.83333333333334,131.38976377952758,Facility_2 -245,11,5,254.75,138.40748031496065,Facility_2 -246,11,6,359.0833333333333,195.09251968503938,Facility_2 -247,11,7,379.4166666666667,206.13976377952758,Facility_2 -248,11,8,390.8333333333333,212.34251968503938,Facility_2 -249,11,9,386.1666666666667,209.80708661417324,Facility_2 -250,11,10,387.5,210.53149606299215,Facility_2 -251,11,11,389.9166666666667,211.8444881889764,Facility_2 -252,11,12,393.0,213.5196850393701,Facility_2 -253,11,13,396.9166666666667,215.6476377952756,Facility_2 -254,11,14,404.8333333333333,219.9488188976378,Facility_2 -255,11,15,401.5,218.13779527559058,Facility_2 -256,11,16,396.0,215.14960629921262,Facility_2 -257,11,17,396.75,215.55708661417324,Facility_2 -258,11,18,398.4166666666667,216.4625984251969,Facility_2 -259,11,19,398.1666666666667,216.32677165354332,Facility_2 -260,11,20,384.5,208.90157480314963,Facility_2 -261,11,21,371.0,201.56692913385828,Facility_2 -262,11,22,311.5833333333333,169.28543307086613,Facility_2 -263,11,23,287.9166666666667,156.42716535433073,Facility_2 -264,12,0,252.09677419354838,136.96596393192786,Facility_2 -265,12,1,233.8709677419355,127.06375412750826,Facility_2 -266,12,2,230.40322580645162,125.17970535941073,Facility_2 -267,12,3,226.69354838709677,123.16421132842267,Facility_2 -268,12,4,270.7258064516129,147.08724917449837,Facility_2 -269,12,5,283.7096774193548,154.14147828295657,Facility_2 -270,12,6,387.741935483871,210.66294132588266,Facility_2 -271,12,7,416.53225806451616,226.30492760985524,Facility_2 -272,12,8,421.7741935483871,229.15290830581662,Facility_2 -273,12,9,422.66129032258067,229.63487426974856,Facility_2 -274,12,10,422.741935483871,229.67868935737874,Facility_2 -275,12,11,427.8225806451613,232.43903987807977,Facility_2 -276,12,12,427.98387096774195,232.52667005334013,Facility_2 -277,12,13,432.33870967741933,234.89268478536957,Facility_2 -278,12,14,432.5806451612903,235.0241300482601,Facility_2 -279,12,15,427.741935483871,232.3952247904496,Facility_2 -280,12,16,434.11290322580646,235.85661671323345,Facility_2 -281,12,17,431.3709677419355,234.36690373380748,Facility_2 -282,12,18,427.9032258064516,232.48285496570992,Facility_2 -283,12,19,427.33870967741933,232.1761493522987,Facility_2 -284,12,20,417.741935483871,226.96215392430787,Facility_2 -285,12,21,405.4032258064516,220.25844551689104,Facility_2 -286,12,22,345.48387096774195,187.70383540767082,Facility_2 -287,12,23,314.2741935483871,170.74739649479298,Facility_2 -0,1,0,248.27956989247312,599.1943950554568,Facility_3 -1,1,1,231.72043010752688,559.230801794937,Facility_3 -2,1,2,225.05376344086022,543.1415629497926,Facility_3 -3,1,3,224.56989247311827,541.9737956142579,Facility_3 -4,1,4,267.1505376344086,644.7373211413089,Facility_3 -5,1,5,281.02150537634407,678.2133180933029,Facility_3 -6,1,6,367.63440860215053,887.243671154009,Facility_3 -7,1,7,397.741935483871,959.9047498094997,Facility_3 -8,1,8,427.9032258064516,1032.6955803911608,Facility_3 -9,1,9,431.55913978494624,1041.5187113707561,Facility_3 -10,1,10,437.31182795698925,1055.4021674710016,Facility_3 -11,1,11,436.18279569892474,1052.6773770214209,Facility_3 -12,1,12,436.7204301075269,1053.974896283126,Facility_3 -13,1,13,440.59139784946234,1063.3170349674033,Facility_3 -14,1,14,440.16129032258067,1062.2790195580392,Facility_3 -15,1,15,438.6559139784946,1058.6459656252646,Facility_3 -16,1,16,438.8709677419355,1059.1649733299466,Facility_3 -17,1,17,440.16129032258067,1062.2790195580392,Facility_3 -18,1,18,438.2258064516129,1057.6079502159005,Facility_3 -19,1,19,438.1720430107527,1057.47819828973,Facility_3 -20,1,20,426.8279569892473,1030.1005418677505,Facility_3 -21,1,21,410.64516129032256,991.0452120904242,Facility_3 -22,1,22,348.44086021505376,840.9222335111338,Facility_3 -23,1,23,314.89247311827955,759.9570315807298,Facility_3 -24,2,0,238.33333333333334,575.1902887139108,Facility_3 -25,2,1,219.3452380952381,529.3646887889014,Facility_3 -26,2,2,214.9404761904762,518.7342988376454,Facility_3 -27,2,3,211.9047619047619,511.4079490063742,Facility_3 -28,2,4,258.57142857142856,624.0326209223847,Facility_3 -29,2,5,276.7857142857143,667.9907199100113,Facility_3 -30,2,6,366.01190476190476,883.3279433820773,Facility_3 -31,2,7,391.48809523809524,944.8118203974503,Facility_3 -32,2,8,422.26190476190476,1019.0808961379828,Facility_3 -33,2,9,433.92857142857144,1047.2370641169855,Facility_3 -34,2,10,430.6547619047619,1039.3360986126736,Facility_3 -35,2,11,430.35714285714283,1038.6178290213722,Facility_3 -36,2,12,430.6547619047619,1039.3360986126736,Facility_3 -37,2,13,431.07142857142856,1040.341676040495,Facility_3 -38,2,14,429.82142857142856,1037.3249437570305,Facility_3 -39,2,15,426.3690476190476,1028.9930164979378,Facility_3 -40,2,16,422.26190476190476,1019.0808961379828,Facility_3 -41,2,17,426.60714285714283,1029.5676321709786,Facility_3 -42,2,18,427.67857142857144,1032.1534026996626,Facility_3 -43,2,19,424.5238095238095,1024.539745031871,Facility_3 -44,2,20,414.04761904761904,999.2566554180728,Facility_3 -45,2,21,400.6547619047619,966.934523809524,Facility_3 -46,2,22,342.9761904761905,827.7338770153732,Facility_3 -47,2,23,301.7857142857143,728.3253655793026,Facility_3 -48,3,0,223.1720430107527,538.6002455338245,Facility_3 -49,3,1,203.44086021505376,490.981288629244,Facility_3 -50,3,2,196.88888888888889,475.16885389326336,Facility_3 -51,3,3,196.88172043010752,475.1515536364406,Facility_3 -52,3,4,240.48387096774192,580.3803657607315,Facility_3 -53,3,5,257.4731182795699,621.3819744306156,Facility_3 -54,3,6,350.6989247311828,846.3718144102955,Facility_3 -55,3,7,378.2258064516129,912.8048006096013,Facility_3 -56,3,8,410.752688172043,991.3047159427653,Facility_3 -57,3,9,416.8817204301075,1006.0964355262045,Facility_3 -58,3,10,412.5268817204301,995.5865295063924,Facility_3 -59,3,11,411.3440860215054,992.7319871306411,Facility_3 -60,3,12,412.36559139784947,995.1972737278809,Facility_3 -61,3,13,413.1182795698925,997.0138006942682,Facility_3 -62,3,14,414.247311827957,999.738591143849,Facility_3 -63,3,15,412.258064516129,994.9377698755397,Facility_3 -64,3,16,410.80645161290323,991.4344678689358,Facility_3 -65,3,17,411.61290322580646,993.3807467614936,Facility_3 -66,3,18,410.64516129032256,991.0452120904242,Facility_3 -67,3,19,409.13978494623655,987.4121581576496,Facility_3 -68,3,20,397.63440860215053,959.6452459571586,Facility_3 -69,3,21,382.2043010752688,922.4064431462197,Facility_3 -70,3,22,320.6989247311828,773.9702396071459,Facility_3 -71,3,23,292.1505376344086,705.0719668106003,Facility_3 -72,4,0,215.72222222222223,520.6209536307962,Facility_3 -73,4,1,196.72222222222223,474.7666229221348,Facility_3 -74,4,2,190.38888888888889,459.4818460192476,Facility_3 -75,4,3,187.66666666666666,452.91207349081367,Facility_3 -76,4,4,228.0,550.2519685039371,Facility_3 -77,4,5,241.94444444444446,583.905293088364,Facility_3 -78,4,6,326.8888888888889,788.9090113735784,Facility_3 -79,4,7,354.27777777777777,855.0089676290464,Facility_3 -80,4,8,386.55555555555554,932.9076990376203,Facility_3 -81,4,9,393.22222222222223,948.9969378827648,Facility_3 -82,4,10,395.1666666666667,953.6896325459319,Facility_3 -83,4,11,402.3333333333333,970.985564304462,Facility_3 -84,4,12,407.6111111111111,983.7228783902012,Facility_3 -85,4,13,414.0,999.1417322834646,Facility_3 -86,4,14,415.6666666666667,1003.1640419947507,Facility_3 -87,4,15,413.1111111111111,996.9965004374453,Facility_3 -88,4,16,415.55555555555554,1002.8958880139983,Facility_3 -89,4,17,418.72222222222223,1010.5382764654419,Facility_3 -90,4,18,411.55555555555554,993.2423447069117,Facility_3 -91,4,19,409.8333333333333,989.0859580052494,Facility_3 -92,4,20,393.72222222222223,950.2036307961506,Facility_3 -93,4,21,375.22222222222223,905.555993000875,Facility_3 -94,4,22,315.6111111111111,761.6913823272091,Facility_3 -95,4,23,284.55555555555554,686.7423447069117,Facility_3 -96,5,0,232.25806451612902,560.5283210566421,Facility_3 -97,5,1,204.03225806451613,492.4085598171197,Facility_3 -98,5,2,199.247311827957,480.8606383879435,Facility_3 -99,5,3,194.19354838709677,468.66395732791466,Facility_3 -100,5,4,235.86021505376345,569.221700110067,Facility_3 -101,5,5,245.21505376344086,591.7985352637372,Facility_3 -102,5,6,329.4623655913978,795.1198035729404,Facility_3 -103,5,7,364.73118279569894,880.2370671408011,Facility_3 -104,5,8,397.5806451612903,959.5154940309881,Facility_3 -105,5,9,414.5698924731183,1000.5171027008721,Facility_3 -106,5,10,426.55913978494624,1029.4517822368978,Facility_3 -107,5,11,436.1290322580645,1052.5476250952502,Facility_3 -108,5,12,443.1720430107527,1069.5451274235884,Facility_3 -109,5,13,450.10752688172045,1086.2831258995852,Facility_3 -110,5,14,453.3333333333333,1094.0682414698163,Facility_3 -111,5,15,453.9247311827957,1095.4955126576922,Facility_3 -112,5,16,455.59139784946234,1099.5178223689782,Facility_3 -113,5,17,455.80645161290323,1100.0368300736602,Facility_3 -114,5,18,455.86021505376345,1100.1665819998307,Facility_3 -115,5,19,451.23655913978496,1089.0079163491662,Facility_3 -116,5,20,436.8279569892473,1054.234400135467,Facility_3 -117,5,21,417.5268817204301,1007.6534586402506,Facility_3 -118,5,22,342.0967741935484,825.6115062230126,Facility_3 -119,5,23,308.38709677419354,744.257048514097,Facility_3 -120,6,0,267.72222222222223,646.1170166229222,Facility_3 -121,6,1,229.11111111111111,552.9335083114611,Facility_3 -122,6,2,217.38888888888889,524.6432633420823,Facility_3 -123,6,3,217.88888888888889,525.8499562554681,Facility_3 -124,6,4,263.3333333333333,635.5249343832021,Facility_3 -125,6,5,284.8888888888889,687.546806649169,Facility_3 -126,6,6,387.0,933.9803149606299,Facility_3 -127,6,7,442.55555555555554,1068.057305336833,Facility_3 -128,6,8,478.5,1154.8051181102362,Facility_3 -129,6,9,494.8888888888889,1194.3578302712162,Facility_3 -130,6,10,505.6666666666667,1220.3687664041995,Facility_3 -131,6,11,517.2777777777778,1248.390857392826,Facility_3 -132,6,12,528.6666666666666,1275.8766404199475,Facility_3 -133,6,13,534.0,1288.748031496063,Facility_3 -134,6,14,542.1111111111111,1308.3232720909887,Facility_3 -135,6,15,543.3888888888889,1311.4070428696414,Facility_3 -136,6,16,545.7777777777778,1317.1723534558182,Facility_3 -137,6,17,552.4444444444445,1333.2615923009625,Facility_3 -138,6,18,550.7222222222222,1329.1052055993,Facility_3 -139,6,19,547.5555555555555,1321.4628171478566,Facility_3 -140,6,20,530.3888888888889,1280.0330271216098,Facility_3 -141,6,21,502.94444444444446,1213.7989938757657,Facility_3 -142,6,22,397.05555555555554,958.2482502187227,Facility_3 -143,6,23,358.27777777777777,864.662510936133,Facility_3 -144,7,0,271.6666666666667,655.6364829396326,Facility_3 -145,7,1,235.91397849462365,569.3514520362374,Facility_3 -146,7,2,220.21505376344086,531.4638895944458,Facility_3 -147,7,3,216.0215053763441,521.3432393531455,Facility_3 -148,7,4,265.26881720430106,640.1960037253408,Facility_3 -149,7,5,291.2903225806452,702.9959359918721,Facility_3 -150,7,6,401.98924731182797,970.1551519769707,Facility_3 -151,7,7,468.6559139784946,1131.047540428414,Facility_3 -152,7,8,498.9247311827957,1204.0978748624166,Facility_3 -153,7,9,518.2795698924731,1250.8085682838032,Facility_3 -154,7,10,523.7096774193549,1263.913512827026,Facility_3 -155,7,11,531.9354838709677,1283.765557531115,Facility_3 -156,7,12,539.3548387096774,1301.6713233426467,Facility_3 -157,7,13,550.0537634408602,1327.4919566505798,Facility_3 -158,7,14,552.0967741935484,1332.42252984506,Facility_3 -159,7,15,555.9677419354839,1341.7646685293373,Facility_3 -160,7,16,557.2043010752689,1344.7489628312592,Facility_3 -161,7,17,560.5913978494624,1352.9233341800018,Facility_3 -162,7,18,556.989247311828,1344.2299551265771,Facility_3 -163,7,19,552.4731182795699,1333.3307933282535,Facility_3 -164,7,20,535.752688172043,1292.977944289222,Facility_3 -165,7,21,505.752688172043,1220.5763694860723,Facility_3 -166,7,22,408.01075268817203,984.6873677080688,Facility_3 -167,7,23,370.80645161290323,894.8990347980697,Facility_3 -168,8,0,261.4516129032258,630.983616967234,Facility_3 -169,8,1,230.69892473118279,556.765515197697,Facility_3 -170,8,2,213.49462365591398,515.244898823131,Facility_3 -171,8,3,208.33333333333334,502.7887139107612,Facility_3 -172,8,4,253.70967741935485,612.2993395986792,Facility_3 -173,8,5,278.3333333333333,671.7257217847769,Facility_3 -174,8,6,381.55913978494624,920.8494200321735,Facility_3 -175,8,7,447.63440860215053,1080.3145372957413,Facility_3 -176,8,8,481.3440860215054,1161.6689950046568,Facility_3 -177,8,9,495.3225806451613,1195.4044958089917,Facility_3 -178,8,10,504.3010752688172,1217.0730674794684,Facility_3 -179,8,11,518.0645161290323,1250.2895605791214,Facility_3 -180,8,12,532.0967741935484,1284.1548133096267,Facility_3 -181,8,13,541.989247311828,1308.0291677250023,Facility_3 -182,8,14,548.763440860215,1324.3779104224875,Facility_3 -183,8,15,551.8817204301075,1331.9035221403776,Facility_3 -184,8,16,546.6129032258065,1319.187833375667,Facility_3 -185,8,17,548.1720430107526,1322.9506392346118,Facility_3 -186,8,18,542.3655913978495,1308.937431208196,Facility_3 -187,8,19,534.7849462365591,1290.6424096181527,Facility_3 -188,8,20,513.8172043010753,1240.0391584116503,Facility_3 -189,8,21,487.741935483871,1177.1094742189484,Facility_3 -190,8,22,390.86021505376345,943.2965032596733,Facility_3 -191,8,23,352.9032258064516,851.6916433832868,Facility_3 -192,9,0,237.88888888888889,574.1176727909011,Facility_3 -193,9,1,221.44444444444446,534.4308836395451,Facility_3 -194,9,2,202.27777777777777,488.17432195975505,Facility_3 -195,9,3,202.72222222222223,489.2469378827647,Facility_3 -196,9,4,243.44444444444446,587.5253718285215,Facility_3 -197,9,5,253.05555555555554,610.7206911636046,Facility_3 -198,9,6,358.94444444444446,866.2714348206475,Facility_3 -199,9,7,389.05555555555554,938.9411636045495,Facility_3 -200,9,8,408.55555555555554,986.0021872265967,Facility_3 -201,9,9,414.94444444444446,1001.4210411198601,Facility_3 -202,9,10,424.6111111111111,1024.7504374453194,Facility_3 -203,9,11,440.72222222222223,1063.6327646544182,Facility_3 -204,9,12,451.5,1089.6437007874017,Facility_3 -205,9,13,456.72222222222223,1102.2469378827648,Facility_3 -206,9,14,455.94444444444446,1100.369860017498,Facility_3 -207,9,15,458.6666666666667,1106.9396325459318,Facility_3 -208,9,16,460.6111111111111,1111.6323272090988,Facility_3 -209,9,17,456.44444444444446,1101.5765529308837,Facility_3 -210,9,18,452.8888888888889,1092.9956255468069,Facility_3 -211,9,19,444.6111111111111,1073.0181539807525,Facility_3 -212,9,20,426.8888888888889,1030.2475940507438,Facility_3 -213,9,21,405.3333333333333,978.225721784777,Facility_3 -214,9,22,335.22222222222223,809.0205599300089,Facility_3 -215,9,23,304.8888888888889,735.8145231846021,Facility_3 -216,10,0,234.6031746031746,566.1879765029372,Facility_3 -217,10,1,210.6451612903226,508.3680467360935,Facility_3 -218,10,2,196.61290322580646,474.50279400558804,Facility_3 -219,10,3,195.7258064516129,472.3618872237745,Facility_3 -220,10,4,242.58064516129033,585.4406908813818,Facility_3 -221,10,5,250.16129032258064,603.735712471425,Facility_3 -222,10,6,356.85483870967744,861.22840995682,Facility_3 -223,10,7,384.51612903225805,927.985775971552,Facility_3 -224,10,8,405.64516129032256,978.978282956566,Facility_3 -225,10,9,401.2903225806452,968.468376936754,Facility_3 -226,10,10,409.51612903225805,988.3204216408433,Facility_3 -227,10,11,414.6774193548387,1000.7766065532132,Facility_3 -228,10,12,420.4032258064516,1014.5951866903733,Facility_3 -229,10,13,423.6290322580645,1022.3803022606046,Facility_3 -230,10,14,423.06451612903226,1021.0179070358141,Facility_3 -231,10,15,422.741935483871,1020.239395478791,Facility_3 -232,10,16,423.2258064516129,1021.4071628143257,Facility_3 -233,10,17,425.16129032258067,1026.0782321564645,Facility_3 -234,10,18,420.241935483871,1014.2059309118619,Facility_3 -235,10,19,413.46774193548384,997.8571882143764,Facility_3 -236,10,20,400.64516129032256,966.9113538227076,Facility_3 -237,10,21,383.5483870967742,925.6502413004827,Facility_3 -238,10,22,321.69354838709677,776.3706502413005,Facility_3 -239,10,23,296.0483870967742,714.478981457963,Facility_3 -240,11,0,224.33333333333334,541.4028871391076,Facility_3 -241,11,1,204.41666666666666,493.33628608923885,Facility_3 -242,11,2,198.41666666666666,478.8559711286089,Facility_3 -243,11,3,199.66666666666666,481.8727034120735,Facility_3 -244,11,4,241.83333333333334,583.6371391076116,Facility_3 -245,11,5,254.75,614.8100393700788,Facility_3 -246,11,6,359.0833333333333,866.6066272965879,Facility_3 -247,11,7,379.4166666666667,915.6788057742783,Facility_3 -248,11,8,390.8333333333333,943.2316272965879,Facility_3 -249,11,9,386.1666666666667,931.9691601049869,Facility_3 -250,11,10,387.5,935.1870078740158,Facility_3 -251,11,11,389.9166666666667,941.0193569553807,Facility_3 -252,11,12,393.0,948.4606299212599,Facility_3 -253,11,13,396.9166666666667,957.9130577427823,Facility_3 -254,11,14,404.8333333333333,977.0190288713911,Facility_3 -255,11,15,401.5,968.974409448819,Facility_3 -256,11,16,396.0,955.7007874015749,Facility_3 -257,11,17,396.75,957.5108267716536,Facility_3 -258,11,18,398.4166666666667,961.5331364829398,Facility_3 -259,11,19,398.1666666666667,960.9297900262468,Facility_3 -260,11,20,384.5,927.9468503937009,Facility_3 -261,11,21,371.0,895.3661417322835,Facility_3 -262,11,22,311.5833333333333,751.9708005249344,Facility_3 -263,11,23,287.9166666666667,694.854002624672,Facility_3 -264,12,0,252.09677419354838,608.4067818135636,Facility_3 -265,12,1,233.8709677419355,564.4208788417577,Facility_3 -266,12,2,230.40322580645162,556.0518796037593,Facility_3 -267,12,3,226.69354838709677,547.0989966979935,Facility_3 -268,12,4,270.7258064516129,653.3658242316485,Facility_3 -269,12,5,283.7096774193548,684.7009144018288,Facility_3 -270,12,6,387.741935483871,935.7708915417832,Facility_3 -271,12,7,416.53225806451616,1005.2530480060962,Facility_3 -272,12,8,421.7741935483871,1017.9038608077216,Facility_3 -273,12,9,422.66129032258067,1020.0447675895354,Facility_3 -274,12,10,422.741935483871,1020.239395478791,Facility_3 -275,12,11,427.8225806451613,1032.500952501905,Facility_3 -276,12,12,427.98387096774195,1032.8902082804166,Facility_3 -277,12,13,432.33870967741933,1043.4001143002286,Facility_3 -278,12,14,432.5806451612903,1043.983997967996,Facility_3 -279,12,15,427.741935483871,1032.3063246126494,Facility_3 -280,12,16,434.11290322580646,1047.681927863856,Facility_3 -281,12,17,431.3709677419355,1041.0645796291594,Facility_3 -282,12,18,427.9032258064516,1032.6955803911608,Facility_3 -283,12,19,427.33870967741933,1031.3331851663704,Facility_3 -284,12,20,417.741935483871,1008.1724663449328,Facility_3 -285,12,21,405.4032258064516,978.3943992887986,Facility_3 -286,12,22,345.48387096774195,833.7858775717552,Facility_3 -287,12,23,314.2741935483871,758.4648844297689,Facility_3 -0,1,0,248.27956989247312,1059.0980865295064,Facility_4 -1,1,1,231.72043010752688,988.4609685886038,Facility_4 -2,1,2,225.05376344086022,960.0226483786302,Facility_4 -3,1,3,224.56989247311827,957.9585767504868,Facility_4 -4,1,4,267.1505376344086,1139.5968800270932,Facility_4 -5,1,5,281.02150537634407,1198.7669333672,Facility_4 -6,1,6,367.63440860215053,1568.2357548048428,Facility_4 -7,1,7,397.741935483871,1696.6668783337566,Facility_4 -8,1,8,427.9032258064516,1825.327343154686,Facility_4 -9,1,9,431.55913978494624,1840.9225510117687,Facility_4 -10,1,10,437.31182795698925,1865.4620692574717,Facility_4 -11,1,11,436.18279569892474,1860.6459021251376,Facility_4 -12,1,12,436.7204301075269,1862.9393150452968,Facility_4 -13,1,13,440.59139784946234,1879.4518880704427,Facility_4 -14,1,14,440.16129032258067,1877.6171577343155,Facility_4 -15,1,15,438.6559139784946,1871.1956015578696,Facility_4 -16,1,16,438.8709677419355,1872.1129667259333,Facility_4 -17,1,17,440.16129032258067,1877.6171577343155,Facility_4 -18,1,18,438.2258064516129,1869.3608712217426,Facility_4 -19,1,19,438.1720430107527,1869.1315299297266,Facility_4 -20,1,20,426.8279569892473,1820.740517314368,Facility_4 -21,1,21,410.64516129032256,1751.7087884175767,Facility_4 -22,1,22,348.44086021505376,1486.3609135551603,Facility_4 -23,1,23,314.89247311827955,1343.2519473372279,Facility_4 -24,2,0,238.33333333333334,1016.6699475065617,Facility_4 -25,2,1,219.3452380952381,935.6715176227972,Facility_4 -26,2,2,214.9404761904762,916.8819131983503,Facility_4 -27,2,3,211.9047619047619,903.93232095988,Facility_4 -28,2,4,258.57142857142856,1103.0005624296962,Facility_4 -29,2,5,276.7857142857143,1180.6981158605174,Facility_4 -30,2,6,366.01190476190476,1561.3145622422196,Facility_4 -31,2,7,391.48809523809524,1669.989571616048,Facility_4 -32,2,8,422.26190476190476,1801.2628890138733,Facility_4 -33,2,9,433.92857142857144,1851.0299493813275,Facility_4 -34,2,10,430.6547619047619,1837.064702849644,Facility_4 -35,2,11,430.35714285714283,1835.795134983127,Facility_4 -36,2,12,430.6547619047619,1837.064702849644,Facility_4 -37,2,13,431.07142857142856,1838.842097862767,Facility_4 -38,2,14,429.82142857142856,1833.509912823397,Facility_4 -39,2,15,426.3690476190476,1818.7829255718034,Facility_4 -40,2,16,422.26190476190476,1801.2628890138733,Facility_4 -41,2,17,426.60714285714283,1819.7985798650168,Facility_4 -42,2,18,427.67857142857144,1824.369024184477,Facility_4 -43,2,19,424.5238095238095,1810.9116047994,Facility_4 -44,2,20,414.04761904761904,1766.2228158980126,Facility_4 -45,2,21,400.6547619047619,1709.092261904762,Facility_4 -46,2,22,342.9761904761905,1463.0500093738283,Facility_4 -47,2,23,301.7857142857143,1287.341816647919,Facility_4 -48,3,0,223.1720430107527,951.9957031580731,Facility_4 -49,3,1,203.44086021505376,867.8274489882313,Facility_4 -50,3,2,196.88888888888889,839.8783902012249,Facility_4 -51,3,3,196.88172043010752,839.8478113622893,Facility_4 -52,3,4,240.48387096774192,1025.8435991871984,Facility_4 -53,3,5,257.4731182795699,1098.3154474642283,Facility_4 -54,3,6,350.6989247311828,1495.9932478198289,Facility_4 -55,3,7,378.2258064516129,1613.4159893319788,Facility_4 -56,3,8,410.752688172043,1752.1674710016086,Facility_4 -57,3,9,416.8817204301075,1778.312378291423,Facility_4 -58,3,10,412.5268817204301,1759.7357336381338,Facility_4 -59,3,11,411.3440860215054,1754.6902252137838,Facility_4 -60,3,12,412.36559139784947,1759.0477097620862,Facility_4 -61,3,13,413.1182795698925,1762.258487850309,Facility_4 -62,3,14,414.247311827957,1767.0746549826433,Facility_4 -63,3,15,412.258064516129,1758.5890271780543,Facility_4 -64,3,16,410.80645161290323,1752.3968122936246,Facility_4 -65,3,17,411.61290322580646,1755.8369316738633,Facility_4 -66,3,18,410.64516129032256,1751.7087884175767,Facility_4 -67,3,19,409.13978494623655,1745.287232241131,Facility_4 -68,3,20,397.63440860215053,1696.2081957497248,Facility_4 -69,3,21,382.2043010752688,1630.3872449411565,Facility_4 -70,3,22,320.6989247311828,1368.020806874947,Facility_4 -71,3,23,292.1505376344086,1246.240580814495,Facility_4 -72,4,0,215.72222222222223,920.2166447944007,Facility_4 -73,4,1,196.72222222222223,839.1674321959755,Facility_4 -74,4,2,190.38888888888889,812.1510279965004,Facility_4 -75,4,3,187.66666666666666,800.5387139107611,Facility_4 -76,4,4,228.0,972.5905511811023,Facility_4 -77,4,5,241.94444444444446,1032.0740376202975,Facility_4 -78,4,6,326.8888888888889,1394.425634295713,Facility_4 -79,4,7,354.27777777777777,1511.2597331583552,Facility_4 -80,4,8,386.55555555555554,1648.948600174978,Facility_4 -81,4,9,393.22222222222223,1677.386920384952,Facility_4 -82,4,10,395.1666666666667,1685.6814304461943,Facility_4 -83,4,11,402.3333333333333,1716.252624671916,Facility_4 -84,4,12,407.6111111111111,1738.766294838145,Facility_4 -85,4,13,414.0,1766.01968503937,Facility_4 -86,4,14,415.6666666666667,1773.1292650918635,Facility_4 -87,4,15,413.1111111111111,1762.2279090113734,Facility_4 -88,4,16,415.55555555555554,1772.6552930883638,Facility_4 -89,4,17,418.72222222222223,1786.1634951881015,Facility_4 -90,4,18,411.55555555555554,1755.5923009623796,Facility_4 -91,4,19,409.8333333333333,1748.2457349081365,Facility_4 -92,4,20,393.72222222222223,1679.5197944007,Facility_4 -93,4,21,375.22222222222223,1600.6034558180227,Facility_4 -94,4,22,315.6111111111111,1346.3174759405074,Facility_4 -95,4,23,284.55555555555554,1213.8423009623796,Facility_4 -96,5,0,232.25806451612902,990.754381508763,Facility_4 -97,5,1,204.03225806451613,870.3502032004064,Facility_4 -98,5,2,199.247311827957,849.9388282109898,Facility_4 -99,5,3,194.19354838709677,828.3807467614935,Facility_4 -100,5,4,235.86021505376345,1006.1202480738295,Facility_4 -101,5,5,245.21505376344086,1046.0256328845992,Facility_4 -102,5,6,329.4623655913978,1405.4034374735415,Facility_4 -103,5,7,364.73118279569894,1555.8513250359836,Facility_4 -104,5,8,397.5806451612903,1695.9788544577088,Facility_4 -105,5,9,414.5698924731183,1768.4507027347388,Facility_4 -106,5,10,426.55913978494624,1819.5938108542884,Facility_4 -107,5,11,436.1290322580645,1860.4165608331216,Facility_4 -108,5,12,443.1720430107527,1890.460270087207,Facility_4 -109,5,13,450.10752688172045,1920.0452967572603,Facility_4 -110,5,14,453.3333333333333,1933.805774278215,Facility_4 -111,5,15,453.9247311827957,1936.3285284903905,Facility_4 -112,5,16,455.59139784946234,1943.4381085428836,Facility_4 -113,5,17,455.80645161290323,1944.3554737109475,Facility_4 -114,5,18,455.86021505376345,1944.5848150029633,Facility_4 -115,5,19,451.23655913978496,1924.8614638895945,Facility_4 -116,5,20,436.8279569892473,1863.3979976293285,Facility_4 -117,5,21,417.5268817204301,1781.064473795614,Facility_4 -118,5,22,342.0967741935484,1459.2986410972824,Facility_4 -119,5,23,308.38709677419354,1315.501651003302,Facility_4 -120,6,0,267.72222222222223,1142.035542432196,Facility_4 -121,6,1,229.11111111111111,977.330271216098,Facility_4 -122,6,2,217.38888888888889,927.3262248468941,Facility_4 -123,6,3,217.88888888888889,929.4590988626421,Facility_4 -124,6,4,263.3333333333333,1123.313648293963,Facility_4 -125,6,5,284.8888888888889,1215.2642169728786,Facility_4 -126,6,6,387.0,1650.8444881889764,Facility_4 -127,6,7,442.55555555555554,1887.8304899387576,Facility_4 -128,6,8,478.5,2041.160433070866,Facility_4 -129,6,9,494.8888888888889,2111.0713035870517,Facility_4 -130,6,10,505.6666666666667,2157.0465879265093,Facility_4 -131,6,11,517.2777777777778,2206.5766622922138,Facility_4 -132,6,12,528.6666666666666,2255.1587926509183,Facility_4 -133,6,13,534.0,2277.9094488188975,Facility_4 -134,6,14,542.1111111111111,2312.5094050743655,Facility_4 -135,6,15,543.3888888888889,2317.960083114611,Facility_4 -136,6,16,545.7777777777778,2328.1504811898517,Facility_4 -137,6,17,552.4444444444445,2356.588801399825,Facility_4 -138,6,18,550.7222222222222,2349.242235345582,Facility_4 -139,6,19,547.5555555555555,2335.7340332458443,Facility_4 -140,6,20,530.3888888888889,2262.505358705162,Facility_4 -141,6,21,502.94444444444446,2145.43427384077,Facility_4 -142,6,22,397.05555555555554,1693.7389545056867,Facility_4 -143,6,23,358.27777777777777,1528.3227252843394,Facility_4 -144,7,0,271.6666666666667,1158.8615485564305,Facility_4 -145,7,1,235.91397849462365,1006.3495893658454,Facility_4 -146,7,2,220.21505376344086,939.3819320971976,Facility_4 -147,7,3,216.0215053763441,921.493311319956,Facility_4 -148,7,4,265.26881720430106,1131.5699348065361,Facility_4 -149,7,5,291.2903225806452,1242.5711201422403,Facility_4 -150,7,6,401.98924731182797,1714.7848404030142,Facility_4 -151,7,7,468.6559139784946,1999.1680425027516,Facility_4 -152,7,8,498.9247311827957,2128.287189907713,Facility_4 -153,7,9,518.2795698924731,2210.8500550334434,Facility_4 -154,7,10,523.7096774193549,2234.013525527051,Facility_4 -155,7,11,531.9354838709677,2269.102743205486,Facility_4 -156,7,12,539.3548387096774,2300.751841503683,Facility_4 -157,7,13,550.0537634408602,2346.3907586148503,Facility_4 -158,7,14,552.0967741935484,2355.1057277114555,Facility_4 -159,7,15,555.9677419354839,2371.6183007366017,Facility_4 -160,7,16,557.2043010752689,2376.893150452968,Facility_4 -161,7,17,560.5913978494624,2391.3416518499703,Facility_4 -162,7,18,556.989247311828,2375.975785284904,Facility_4 -163,7,19,552.4731182795699,2356.7111167555668,Facility_4 -164,7,20,535.752688172043,2285.3859749386165,Facility_4 -165,7,21,505.752688172043,2157.4135339937347,Facility_4 -166,7,22,408.01075268817203,1740.471065108797,Facility_4 -167,7,23,370.80645161290323,1581.766891033782,Facility_4 -168,8,0,261.4516129032258,1115.286703073406,Facility_4 -169,8,1,230.69892473118279,984.1034840403014,Facility_4 -170,8,2,213.49462365591398,910.7142705952078,Facility_4 -171,8,3,208.33333333333334,888.6975065616798,Facility_4 -172,8,4,253.70967741935485,1082.2615570231142,Facility_4 -173,8,5,278.3333333333333,1187.2998687664042,Facility_4 -174,8,6,381.55913978494624,1627.6351494369655,Facility_4 -175,8,7,447.63440860215053,1909.495597324528,Facility_4 -176,8,8,481.3440860215054,2053.2925874185084,Facility_4 -177,8,9,495.3225806451613,2112.9213233426467,Facility_4 -178,8,10,504.3010752688172,2151.221319109305,Facility_4 -179,8,11,518.0645161290323,2209.93268986538,Facility_4 -180,8,12,532.0967741935484,2269.7907670815343,Facility_4 -181,8,13,541.989247311828,2311.989564812463,Facility_4 -182,8,14,548.763440860215,2340.8865676064684,Facility_4 -183,8,15,551.8817204301075,2354.1883625433916,Facility_4 -184,8,16,546.6129032258065,2331.712915925832,Facility_4 -185,8,17,548.1720430107526,2338.363813394293,Facility_4 -186,8,18,542.3655913978495,2313.594953856574,Facility_4 -187,8,19,534.7849462365591,2281.25783168233,Facility_4 -188,8,20,513.8172043010753,2191.8147277961225,Facility_4 -189,8,21,487.741935483871,2080.584201168402,Facility_4 -190,8,22,390.86021505376345,1667.3111929557192,Facility_4 -191,8,23,352.9032258064516,1505.3962407924814,Facility_4 -192,9,0,237.88888888888889,1014.7740594925634,Facility_4 -193,9,1,221.44444444444446,944.6262029746282,Facility_4 -194,9,2,202.27777777777777,862.8660323709536,Facility_4 -195,9,3,202.72222222222223,864.7619203849518,Facility_4 -196,9,4,243.44444444444446,1038.4726596675416,Facility_4 -197,9,5,253.05555555555554,1079.4712379702537,Facility_4 -198,9,6,358.94444444444446,1531.166557305337,Facility_4 -199,9,7,389.05555555555554,1659.6129702537182,Facility_4 -200,9,8,408.55555555555554,1742.7950568678914,Facility_4 -201,9,9,414.94444444444446,1770.0484470691165,Facility_4 -202,9,10,424.6111111111111,1811.284011373578,Facility_4 -203,9,11,440.72222222222223,1880.0099518810148,Facility_4 -204,9,12,451.5,1925.9852362204724,Facility_4 -205,9,13,456.72222222222223,1948.261920384952,Facility_4 -206,9,14,455.94444444444446,1944.944116360455,Facility_4 -207,9,15,458.6666666666667,1956.5564304461943,Facility_4 -208,9,16,460.6111111111111,1964.8509405074365,Facility_4 -209,9,17,456.44444444444446,1947.076990376203,Facility_4 -210,9,18,452.8888888888889,1931.909886264217,Facility_4 -211,9,19,444.6111111111111,1896.5989720034995,Facility_4 -212,9,20,426.8888888888889,1821.0004374453194,Facility_4 -213,9,21,405.3333333333333,1729.0498687664042,Facility_4 -214,9,22,335.22222222222223,1429.9735345581803,Facility_4 -215,9,23,304.8888888888889,1300.5791776027997,Facility_4 -216,10,0,234.6031746031746,1000.7580302462193,Facility_4 -217,10,1,210.6451612903226,898.5591821183642,Facility_4 -218,10,2,196.61290322580646,838.7011049022099,Facility_4 -219,10,3,195.7258064516129,834.9169735839471,Facility_4 -220,10,4,242.58064516129033,1034.7879095758192,Facility_4 -221,10,5,250.16129032258064,1067.1250317500635,Facility_4 -222,10,6,356.85483870967744,1522.2528257556517,Facility_4 -223,10,7,384.51612903225805,1640.248920497841,Facility_4 -224,10,8,405.64516129032256,1730.3800482600964,Facility_4 -225,10,9,401.2903225806452,1711.8034036068073,Facility_4 -226,10,10,409.51612903225805,1746.8926212852425,Facility_4 -227,10,11,414.6774193548387,1768.9093853187708,Facility_4 -228,10,12,420.4032258064516,1793.3342329184657,Facility_4 -229,10,13,423.6290322580645,1807.0947104394209,Facility_4 -230,10,14,423.06451612903226,1804.6866268732538,Facility_4 -231,10,15,422.741935483871,1803.3105791211583,Facility_4 -232,10,16,423.2258064516129,1805.3746507493015,Facility_4 -233,10,17,425.16129032258067,1813.6309372618746,Facility_4 -234,10,18,420.241935483871,1792.6462090424181,Facility_4 -235,10,19,413.46774193548384,1763.7492062484123,Facility_4 -236,10,20,400.64516129032256,1709.051308102616,Facility_4 -237,10,21,383.5483870967742,1636.1207772415546,Facility_4 -238,10,22,321.69354838709677,1372.2636207772416,Facility_4 -239,10,23,296.0483870967742,1262.867824485649,Facility_4 -240,11,0,224.33333333333334,956.9494750656169,Facility_4 -241,11,1,204.41666666666666,871.9899934383202,Facility_4 -242,11,2,198.41666666666666,846.3955052493438,Facility_4 -243,11,3,199.66666666666666,851.7276902887139,Facility_4 -244,11,4,241.83333333333334,1031.600065616798,Facility_4 -245,11,5,254.75,1086.699311023622,Facility_4 -246,11,6,359.0833333333333,1531.759022309711,Facility_4 -247,11,7,379.4166666666667,1618.4958989501313,Facility_4 -248,11,8,390.8333333333333,1667.196522309711,Facility_4 -249,11,9,386.1666666666667,1647.2896981627298,Facility_4 -250,11,10,387.5,1652.9773622047244,Facility_4 -251,11,11,389.9166666666667,1663.28625328084,Facility_4 -252,11,12,393.0,1676.4389763779527,Facility_4 -253,11,13,396.9166666666667,1693.1464895013123,Facility_4 -254,11,14,404.8333333333333,1726.9169947506562,Facility_4 -255,11,15,401.5,1712.6978346456692,Facility_4 -256,11,16,396.0,1689.236220472441,Facility_4 -257,11,17,396.75,1692.435531496063,Facility_4 -258,11,18,398.4166666666667,1699.5451115485564,Facility_4 -259,11,19,398.1666666666667,1698.4786745406825,Facility_4 -260,11,20,384.5,1640.1801181102362,Facility_4 -261,11,21,371.0,1582.5925196850394,Facility_4 -262,11,22,311.5833333333333,1329.1359908136483,Facility_4 -263,11,23,287.9166666666667,1228.1799540682416,Facility_4 -264,12,0,252.09677419354838,1075.3813182626366,Facility_4 -265,12,1,233.8709677419355,997.6346202692406,Facility_4 -266,12,2,230.40322580645162,982.8421069342139,Facility_4 -267,12,3,226.69354838709677,967.0175577851155,Facility_4 -268,12,4,270.7258064516129,1154.848075946152,Facility_4 -269,12,5,283.7096774193548,1210.233997967996,Facility_4 -270,12,6,387.741935483871,1654.009398018796,Facility_4 -271,12,7,416.53225806451616,1776.82165989332,Facility_4 -272,12,8,421.7741935483871,1799.1824358648716,Facility_4 -273,12,9,422.66129032258067,1802.9665671831344,Facility_4 -274,12,10,422.741935483871,1803.3105791211583,Facility_4 -275,12,11,427.8225806451613,1824.9833312166625,Facility_4 -276,12,12,427.98387096774195,1825.6713550927102,Facility_4 -277,12,13,432.33870967741933,1844.2479997459993,Facility_4 -278,12,14,432.5806451612903,1845.280035560071,Facility_4 -279,12,15,427.741935483871,1824.6393192786386,Facility_4 -280,12,16,434.11290322580646,1851.8162623825249,Facility_4 -281,12,17,431.3709677419355,1840.119856489713,Facility_4 -282,12,18,427.9032258064516,1825.327343154686,Facility_4 -283,12,19,427.33870967741933,1822.919259588519,Facility_4 -284,12,20,417.741935483871,1781.981838963678,Facility_4 -285,12,21,405.4032258064516,1729.3480124460248,Facility_4 -286,12,22,345.48387096774195,1473.747142494285,Facility_4 -287,12,23,314.2741935483871,1340.6145224790448,Facility_4 -0,1,0,248.27956989247312,349.4486072305478,Facility_5 -1,1,1,231.72043010752688,326.14194395055455,Facility_5 -2,1,2,225.05376344086022,316.75874185081705,Facility_5 -3,1,3,224.56989247311827,316.0777029887393,Facility_5 -4,1,4,267.1505376344086,376.009122851579,Facility_5 -5,1,5,281.02150537634407,395.5322368978071,Facility_5 -6,1,6,367.63440860215053,517.4381932097198,Facility_5 -7,1,7,397.741935483871,559.8139446278892,Facility_5 -8,1,8,427.9032258064516,602.265367030734,Facility_5 -9,1,9,431.55913978494624,607.4109939886546,Facility_5 -10,1,10,437.31182795698925,615.507789348912,Facility_5 -11,1,11,436.18279569892474,613.9186986707307,Facility_5 -12,1,12,436.7204301075269,614.6754085174837,Facility_5 -13,1,13,440.59139784946234,620.1237194141054,Facility_5 -14,1,14,440.16129032258067,619.5183515367031,Facility_5 -15,1,15,438.6559139784946,617.3995639657945,Facility_5 -16,1,16,438.8709677419355,617.7022479044958,Facility_5 -17,1,17,440.16129032258067,619.5183515367031,Facility_5 -18,1,18,438.2258064516129,616.7941960883921,Facility_5 -19,1,19,438.1720430107527,616.7185251037168,Facility_5 -20,1,20,426.8279569892473,600.751947337228,Facility_5 -21,1,21,410.64516129032256,577.9749809499618,Facility_5 -22,1,22,348.44086021505376,490.4236516806367,Facility_5 -23,1,23,314.89247311827955,443.2049572432478,Facility_5 -24,2,0,238.33333333333334,335.4494750656168,Facility_5 -25,2,1,219.3452380952381,308.7241047994001,Facility_5 -26,2,2,214.9404761904762,302.5244891263592,Facility_5 -27,2,3,211.9047619047619,298.2517810273716,Facility_5 -28,2,4,258.57142857142856,363.93419572553427,Facility_5 -29,2,5,276.7857142857143,389.57044431946,Facility_5 -30,2,6,366.01190476190476,515.1545509936258,Facility_5 -31,2,7,391.48809523809524,551.0117875890513,Facility_5 -32,2,8,422.26190476190476,594.3253187101612,Facility_5 -33,2,9,433.92857142857144,610.7459223847019,Facility_5 -34,2,10,430.6547619047619,606.1380999250093,Facility_5 -35,2,11,430.35714285714283,605.7192069741282,Facility_5 -36,2,12,430.6547619047619,606.1380999250093,Facility_5 -37,2,13,431.07142857142856,606.724550056243,Facility_5 -38,2,14,429.82142857142856,604.9651996625421,Facility_5 -39,2,15,426.3690476190476,600.1060414323209,Facility_5 -40,2,16,422.26190476190476,594.3253187101612,Facility_5 -41,2,17,426.60714285714283,600.4411557930258,Facility_5 -42,2,18,427.67857142857144,601.949170416198,Facility_5 -43,2,19,424.5238095238095,597.5089051368578,Facility_5 -44,2,20,414.04761904761904,582.7638732658418,Facility_5 -45,2,21,400.6547619047619,563.9136904761905,Facility_5 -46,2,22,342.9761904761905,482.73223659542555,Facility_5 -47,2,23,301.7857142857143,424.7574521934758,Facility_5 -48,3,0,223.1720430107527,314.11025738718143,Facility_5 -49,3,1,203.44086021505376,286.33900601134536,Facility_5 -50,3,2,196.88888888888889,277.1172353455818,Facility_5 -51,3,3,196.88172043010752,277.1071458809584,Facility_5 -52,3,4,240.48387096774192,338.47631445262886,Facility_5 -53,3,5,257.4731182795699,362.3883456100246,Facility_5 -54,3,6,350.6989247311828,493.6018330369994,Facility_5 -55,3,7,378.2258064516129,532.3453771907543,Facility_5 -56,3,8,410.752688172043,578.1263229193124,Facility_5 -57,3,9,416.8817204301075,586.752815172297,Facility_5 -58,3,10,412.5268817204301,580.6234654135974,Facility_5 -59,3,11,411.3440860215054,578.9587037507408,Facility_5 -60,3,12,412.36559139784947,580.3964524595716,Facility_5 -61,3,13,413.1182795698925,581.4558462450258,Facility_5 -62,3,14,414.247311827957,583.0449369232072,Facility_5 -63,3,15,412.258064516129,580.2451104902209,Facility_5 -64,3,16,410.80645161290323,578.2019939039878,Facility_5 -65,3,17,411.61290322580646,579.3370586741173,Facility_5 -66,3,18,410.64516129032256,577.9749809499618,Facility_5 -67,3,19,409.13978494623655,575.8561933790534,Facility_5 -68,3,20,397.63440860215053,559.6626026585386,Facility_5 -69,3,21,382.2043010752688,537.9450300567268,Facility_5 -70,3,22,320.6989247311828,451.3774235881805,Facility_5 -71,3,23,292.1505376344086,411.19613072559474,Facility_5 -72,4,0,215.72222222222223,303.62478127734033,Facility_5 -73,4,1,196.72222222222223,276.88265529308836,Facility_5 -74,4,2,190.38888888888889,267.9686132983377,Facility_5 -75,4,3,187.66666666666666,264.1371391076115,Facility_5 -76,4,4,228.0,320.9055118110236,Facility_5 -77,4,5,241.94444444444446,340.5320428696413,Facility_5 -78,4,6,326.8888888888889,460.08967629046373,Facility_5 -79,4,7,354.27777777777777,498.6389982502187,Facility_5 -80,4,8,386.55555555555554,544.0693350831145,Facility_5 -81,4,9,393.22222222222223,553.4525371828521,Facility_5 -82,4,10,395.1666666666667,556.1893044619422,Facility_5 -83,4,11,402.3333333333333,566.2762467191601,Facility_5 -84,4,12,407.6111111111111,573.704615048119,Facility_5 -85,4,13,414.0,582.6968503937007,Facility_5 -86,4,14,415.6666666666667,585.0426509186352,Facility_5 -87,4,15,413.1111111111111,581.4457567804023,Facility_5 -88,4,16,415.55555555555554,584.8862642169728,Facility_5 -89,4,17,418.72222222222223,589.3432852143482,Facility_5 -90,4,18,411.55555555555554,579.2563429571303,Facility_5 -91,4,19,409.8333333333333,576.8323490813648,Facility_5 -92,4,20,393.72222222222223,554.1562773403324,Facility_5 -93,4,21,375.22222222222223,528.1178915135608,Facility_5 -94,4,22,315.6111111111111,444.21642607174095,Facility_5 -95,4,23,284.55555555555554,400.5063429571303,Facility_5 -96,5,0,232.25806451612902,326.8986537973076,Facility_5 -97,5,1,204.03225806451613,287.1713868427737,Facility_5 -98,5,2,199.247311827957,280.43666920667175,Facility_5 -99,5,3,194.19354838709677,273.32359664719326,Facility_5 -100,5,4,235.86021505376345,331.96860977055286,Facility_5 -101,5,5,245.21505376344086,345.1353611040555,Facility_5 -102,5,6,329.4623655913978,463.7117940902548,Facility_5 -103,5,7,364.73118279569894,513.3519600372534,Facility_5 -104,5,8,397.5806451612903,559.5869316738633,Facility_5 -105,5,9,414.5698924731183,583.498962831259,Facility_5 -106,5,10,426.55913978494624,600.3735924138515,Facility_5 -107,5,11,436.1290322580645,613.8430276860554,Facility_5 -108,5,12,443.1720430107527,623.75592667852,Facility_5 -109,5,13,450.10752688172045,633.5174837016341,Facility_5 -110,5,14,453.3333333333333,638.0577427821522,Facility_5 -111,5,15,453.9247311827957,638.8901236135805,Facility_5 -112,5,16,455.59139784946234,641.2359241385149,Facility_5 -113,5,17,455.80645161290323,641.5386080772162,Facility_5 -114,5,18,455.86021505376345,641.6142790618915,Facility_5 -115,5,19,451.23655913978496,635.1065743798155,Facility_5 -116,5,20,436.8279569892473,614.8267504868343,Facility_5 -117,5,21,417.5268817204301,587.6608669884006,Facility_5 -118,5,22,342.0967741935484,481.49447548895097,Facility_5 -119,5,23,308.38709677419354,434.04876809753614,Facility_5 -120,6,0,267.72222222222223,376.8137576552931,Facility_5 -121,6,1,229.11111111111111,322.46937882764655,Facility_5 -122,6,2,217.38888888888889,305.9705818022747,Facility_5 -123,6,3,217.88888888888889,306.674321959755,Facility_5 -124,6,4,263.3333333333333,370.6364829396325,Facility_5 -125,6,5,284.8888888888889,400.97550306211724,Facility_5 -126,6,6,387.0,544.6948818897638,Facility_5 -127,6,7,442.55555555555554,622.8882327209099,Facility_5 -128,6,8,478.5,673.4793307086613,Facility_5 -129,6,9,494.8888888888889,696.5463692038495,Facility_5 -130,6,10,505.6666666666667,711.7158792650919,Facility_5 -131,6,11,517.2777777777778,728.0582895888015,Facility_5 -132,6,12,528.6666666666666,744.0879265091862,Facility_5 -133,6,13,534.0,751.5944881889764,Facility_5 -134,6,14,542.1111111111111,763.0107174103237,Facility_5 -135,6,15,543.3888888888889,764.80916447944,Facility_5 -136,6,16,545.7777777777778,768.1714785651794,Facility_5 -137,6,17,552.4444444444445,777.5546806649169,Facility_5 -138,6,18,550.7222222222222,775.1306867891512,Facility_5 -139,6,19,547.5555555555555,770.673665791776,Facility_5 -140,6,20,530.3888888888889,746.5119203849518,Facility_5 -141,6,21,502.94444444444446,707.8844050743656,Facility_5 -142,6,22,397.05555555555554,558.8478783902012,Facility_5 -143,6,23,358.27777777777777,504.2689195100612,Facility_5 -144,7,0,271.6666666666667,382.3654855643045,Facility_5 -145,7,1,235.91397849462365,332.04428075522816,Facility_5 -146,7,2,220.21505376344086,309.9483532300398,Facility_5 -147,7,3,216.0215053763441,304.0460164253662,Facility_5 -148,7,4,265.26881720430106,373.3606383879434,Facility_5 -149,7,5,291.2903225806452,409.98539497078997,Facility_5 -150,7,6,401.98924731182797,565.7919524172381,Facility_5 -151,7,7,468.6559139784946,659.6239734146134,Facility_5 -152,7,8,498.9247311827957,702.2267377868089,Facility_5 -153,7,9,518.2795698924731,729.4682922699178,Facility_5 -154,7,10,523.7096774193549,737.1110617221235,Facility_5 -155,7,11,531.9354838709677,748.6887223774446,Facility_5 -156,7,12,539.3548387096774,759.1313182626366,Facility_5 -157,7,13,550.0537634408602,774.1898442130216,Facility_5 -158,7,14,552.0967741935484,777.0653416306833,Facility_5 -159,7,15,555.9677419354839,782.5136525273051,Facility_5 -160,7,16,557.2043010752689,784.2540851748371,Facility_5 -161,7,17,560.5913978494624,789.0213572093811,Facility_5 -162,7,18,556.989247311828,783.9514012361358,Facility_5 -163,7,19,552.4731182795699,777.5950385234104,Facility_5 -164,7,20,535.752688172043,754.0613622893912,Facility_5 -165,7,21,505.752688172043,711.8369528405723,Facility_5 -166,7,22,408.01075268817203,574.267102700872,Facility_5 -167,7,23,370.80645161290323,521.9027813055626,Facility_5 -168,8,0,261.4516129032258,367.9879984759969,Facility_5 -169,8,1,230.69892473118279,324.70419524172377,Facility_5 -170,8,2,213.49462365591398,300.48948014562694,Facility_5 -171,8,3,208.33333333333334,293.2250656167979,Facility_5 -172,8,4,253.70967741935485,357.0913766827534,Facility_5 -173,8,5,278.3333333333333,391.74868766404194,Facility_5 -174,8,6,381.55913978494624,537.0369782406232,Facility_5 -175,8,7,447.63440860215053,630.0366184065701,Facility_5 -176,8,8,481.3440860215054,677.4823257979849,Facility_5 -177,8,9,495.3225806451613,697.1567818135636,Facility_5 -178,8,10,504.3010752688172,709.7938362543391,Facility_5 -179,8,11,518.0645161290323,729.1656083312167,Facility_5 -180,8,12,532.0967741935484,748.9157353314706,Facility_5 -181,8,13,541.989247311828,762.8391965117263,Facility_5 -182,8,14,548.763440860215,772.3737405808145,Facility_5 -183,8,15,551.8817204301075,776.762657691982,Facility_5 -184,8,16,546.6129032258065,769.3469011938024,Facility_5 -185,8,17,548.1720430107526,771.5413597493861,Facility_5 -186,8,18,542.3655913978495,763.3688934044535,Facility_5 -187,8,19,534.7849462365591,752.6992845652358,Facility_5 -188,8,20,513.8172043010753,723.1876005418678,Facility_5 -189,8,21,487.741935483871,686.487172974346,Facility_5 -190,8,22,390.86021505376345,550.1280585894505,Facility_5 -191,8,23,352.9032258064516,496.7043434086868,Facility_5 -192,9,0,237.88888888888889,334.8239282589676,Facility_5 -193,9,1,221.44444444444446,311.6786964129484,Facility_5 -194,9,2,202.27777777777777,284.70199037620296,Facility_5 -195,9,3,202.72222222222223,285.32753718285215,Facility_5 -196,9,4,243.44444444444446,342.64326334208226,Facility_5 -197,9,5,253.05555555555554,356.1707130358705,Facility_5 -198,9,6,358.94444444444446,505.207239720035,Facility_5 -199,9,7,389.05555555555554,547.5880358705161,Facility_5 -200,9,8,408.55555555555554,575.0339020122484,Facility_5 -201,9,9,414.94444444444446,584.0261373578303,Facility_5 -202,9,10,424.6111111111111,597.6317804024496,Facility_5 -203,9,11,440.72222222222223,620.307852143482,Facility_5 -204,9,12,451.5,635.4773622047244,Facility_5 -205,9,13,456.72222222222223,642.8275371828521,Facility_5 -206,9,14,455.94444444444446,641.7328302712161,Facility_5 -207,9,15,458.6666666666667,645.5643044619422,Facility_5 -208,9,16,460.6111111111111,648.3010717410323,Facility_5 -209,9,17,456.44444444444446,642.4365704286964,Facility_5 -210,9,18,452.8888888888889,637.4321959755031,Facility_5 -211,9,19,444.6111111111111,625.7813867016622,Facility_5 -212,9,20,426.8888888888889,600.8377077865267,Facility_5 -213,9,21,405.3333333333333,570.498687664042,Facility_5 -214,9,22,335.22222222222223,471.8186789151356,Facility_5 -215,9,23,304.8888888888889,429.12510936132986,Facility_5 -216,10,0,234.6031746031746,330.19935008123986,Facility_5 -217,10,1,210.6451612903226,296.4789179578359,Facility_5 -218,10,2,196.61290322580646,276.7287909575819,Facility_5 -219,10,3,195.7258064516129,275.4802197104394,Facility_5 -220,10,4,242.58064516129033,341.4274828549657,Facility_5 -221,10,5,250.16129032258064,352.09709169418335,Facility_5 -222,10,6,356.85483870967744,502.26616078232155,Facility_5 -223,10,7,384.51612903225805,541.1988823977648,Facility_5 -224,10,8,405.64516129032256,570.9375793751587,Facility_5 -225,10,9,401.2903225806452,564.8082296164592,Facility_5 -226,10,10,409.51612903225805,576.3858902717805,Facility_5 -227,10,11,414.6774193548387,583.6503048006095,Facility_5 -228,10,12,420.4032258064516,591.7092646685293,Facility_5 -229,10,13,423.6290322580645,596.2495237490475,Facility_5 -230,10,14,423.06451612903226,595.4549784099568,Facility_5 -231,10,15,422.741935483871,595.000952501905,Facility_5 -232,10,16,423.2258064516129,595.6819913639828,Facility_5 -233,10,17,425.16129032258067,598.4061468122936,Facility_5 -234,10,18,420.241935483871,591.4822517145034,Facility_5 -235,10,19,413.46774193548384,581.9477076454152,Facility_5 -236,10,20,400.64516129032256,563.9001778003556,Facility_5 -237,10,21,383.5483870967742,539.8368046736093,Facility_5 -238,10,22,321.69354838709677,452.7773368046736,Facility_5 -239,10,23,296.0483870967742,416.6822771145542,Facility_5 -240,11,0,224.33333333333334,315.744750656168,Facility_5 -241,11,1,204.41666666666666,287.7124343832021,Facility_5 -242,11,2,198.41666666666666,279.2675524934383,Facility_5 -243,11,3,199.66666666666666,281.0269028871391,Facility_5 -244,11,4,241.83333333333334,340.375656167979,Facility_5 -245,11,5,254.75,358.55561023622045,Facility_5 -246,11,6,359.0833333333333,505.4027230971128,Facility_5 -247,11,7,379.4166666666667,534.0214895013123,Facility_5 -248,11,8,390.8333333333333,550.0902230971128,Facility_5 -249,11,9,386.1666666666667,543.5219816272966,Facility_5 -250,11,10,387.5,545.3986220472441,Facility_5 -251,11,11,389.9166666666667,548.800032808399,Facility_5 -252,11,12,393.0,553.1397637795276,Facility_5 -253,11,13,396.9166666666667,558.6523950131234,Facility_5 -254,11,14,404.8333333333333,569.7949475065616,Facility_5 -255,11,15,401.5,565.1033464566929,Facility_5 -256,11,16,396.0,557.3622047244095,Facility_5 -257,11,17,396.75,558.4178149606299,Facility_5 -258,11,18,398.4166666666667,560.7636154855643,Facility_5 -259,11,19,398.1666666666667,560.4117454068241,Facility_5 -260,11,20,384.5,541.1761811023622,Facility_5 -261,11,21,371.0,522.1751968503937,Facility_5 -262,11,22,311.5833333333333,438.5474081364829,Facility_5 -263,11,23,287.9166666666667,405.2370406824147,Facility_5 -264,12,0,252.09677419354838,354.82124714249426,Facility_5 -265,12,1,233.8709677419355,329.16878333756665,Facility_5 -266,12,2,230.40322580645162,324.2880048260096,Facility_5 -267,12,3,226.69354838709677,319.06670688341376,Facility_5 -268,12,4,270.7258064516129,381.04124333248666,Facility_5 -269,12,5,283.7096774193548,399.3157861315722,Facility_5 -270,12,6,387.741935483871,545.7391414782829,Facility_5 -271,12,7,416.53225806451616,586.2609537719076,Facility_5 -272,12,8,421.7741935483871,593.6388747777495,Facility_5 -273,12,9,422.66129032258067,594.887446024892,Facility_5 -274,12,10,422.741935483871,595.000952501905,Facility_5 -275,12,11,427.8225806451613,602.1518605537211,Facility_5 -276,12,12,427.98387096774195,602.378873507747,Facility_5 -277,12,13,432.33870967741933,608.5082232664465,Facility_5 -278,12,14,432.5806451612903,608.8487426974854,Facility_5 -279,12,15,427.741935483871,602.0383540767082,Facility_5 -280,12,16,434.11290322580646,611.0053657607315,Facility_5 -281,12,17,431.3709677419355,607.146145542291,Facility_5 -282,12,18,427.9032258064516,602.265367030734,Facility_5 -283,12,19,427.33870967741933,601.4708216916433,Facility_5 -284,12,20,417.741935483871,587.9635509271019,Facility_5 -285,12,21,405.4032258064516,570.5970599441198,Facility_5 -286,12,22,345.48387096774195,486.26174752349505,Facility_5 -287,12,23,314.2741935483871,442.3347409194818,Facility_5 -0,1,0,248.27956989247312,403.6986707306748,Facility_6 -1,1,1,231.72043010752688,376.7737702142071,Facility_6 -2,1,2,225.05376344086022,365.93387520108377,Facility_6 -3,1,3,224.56989247311827,365.14710862755055,Facility_6 -4,1,4,267.1505376344086,434.3825670984675,Facility_6 -5,1,5,281.02150537634407,456.9365422064177,Facility_6 -6,1,6,367.63440860215053,597.767758868851,Facility_6 -7,1,7,397.741935483871,646.7221234442469,Facility_6 -8,1,8,427.9032258064516,695.763906527813,Facility_6 -9,1,9,431.55913978494624,701.7083650833969,Facility_6 -10,1,10,437.31182795698925,711.0621454576243,Facility_6 -11,1,11,436.18279569892474,709.226356786047,Facility_6 -12,1,12,436.7204301075269,710.1005418677504,Facility_6 -13,1,13,440.59139784946234,716.3946744560155,Facility_6 -14,1,14,440.16129032258067,715.6953263906528,Facility_6 -15,1,15,438.6559139784946,713.2476081618829,Facility_6 -16,1,16,438.8709677419355,713.5972821945644,Facility_6 -17,1,17,440.16129032258067,715.6953263906528,Facility_6 -18,1,18,438.2258064516129,712.5482600965203,Facility_6 -19,1,19,438.1720430107527,712.4608415883499,Facility_6 -20,1,20,426.8279569892473,694.015536364406,Facility_6 -21,1,21,410.64516129032256,667.7025654051308,Facility_6 -22,1,22,348.44086021505376,566.5593514520363,Facility_6 -23,1,23,314.89247311827955,512.010202353738,Facility_6 -24,2,0,238.33333333333334,387.5262467191601,Facility_6 -25,2,1,219.3452380952381,356.6519028871391,Facility_6 -26,2,2,214.9404761904762,349.4898293963255,Facility_6 -27,2,3,211.9047619047619,344.5538057742782,Facility_6 -28,2,4,258.57142857142856,420.4330708661417,Facility_6 -29,2,5,276.7857142857143,450.0492125984252,Facility_6 -30,2,6,366.01190476190476,595.129593175853,Facility_6 -31,2,7,391.48809523809524,636.5534776902887,Facility_6 -32,2,8,422.26190476190476,686.5912073490814,Facility_6 -33,2,9,433.92857142857144,705.5610236220473,Facility_6 -34,2,10,430.6547619047619,700.2378608923885,Facility_6 -35,2,11,430.35714285714283,699.753937007874,Facility_6 -36,2,12,430.6547619047619,700.2378608923885,Facility_6 -37,2,13,431.07142857142856,700.9153543307086,Facility_6 -38,2,14,429.82142857142856,698.882874015748,Facility_6 -39,2,15,426.3690476190476,693.2693569553805,Facility_6 -40,2,16,422.26190476190476,686.5912073490814,Facility_6 -41,2,17,426.60714285714283,693.6564960629921,Facility_6 -42,2,18,427.67857142857144,695.3986220472441,Facility_6 -43,2,19,424.5238095238095,690.269028871391,Facility_6 -44,2,20,414.04761904761904,673.2349081364829,Facility_6 -45,2,21,400.6547619047619,651.4583333333334,Facility_6 -46,2,22,342.9761904761905,557.6738845144357,Facility_6 -47,2,23,301.7857142857143,490.6988188976378,Facility_6 -48,3,0,223.1720430107527,362.87422741512154,Facility_6 -49,3,1,203.44086021505376,330.7916349166032,Facility_6 -50,3,2,196.88888888888889,320.13823272090985,Facility_6 -51,3,3,196.88172043010752,320.1265769198205,Facility_6 -52,3,4,240.48387096774192,391.02298704597405,Facility_6 -53,3,5,257.4731182795699,418.6472356278046,Facility_6 -54,3,6,350.6989247311828,570.230928795191,Facility_6 -55,3,7,378.2258064516129,614.98920497841,Facility_6 -56,3,8,410.752688172043,667.8774024214715,Facility_6 -57,3,9,416.8817204301075,677.8431123528914,Facility_6 -58,3,10,412.5268817204301,670.762213191093,Facility_6 -59,3,11,411.3440860215054,668.8390060113454,Facility_6 -60,3,12,412.36559139784947,670.499957666582,Facility_6 -61,3,13,413.1182795698925,671.7238167809669,Facility_6 -62,3,14,414.247311827957,673.5596054525442,Facility_6 -63,3,15,412.258064516129,670.3251206502413,Facility_6 -64,3,16,410.80645161290323,667.9648209296419,Facility_6 -65,3,17,411.61290322580646,669.2760985521971,Facility_6 -66,3,18,410.64516129032256,667.7025654051308,Facility_6 -67,3,19,409.13978494623655,665.254847176361,Facility_6 -68,3,20,397.63440860215053,646.5472864279062,Facility_6 -69,3,21,382.2043010752688,621.4581745830158,Facility_6 -70,3,22,320.6989247311828,521.4514012361358,Facility_6 -71,3,23,292.1505376344086,475.0321733976801,Facility_6 -72,4,0,215.72222222222223,350.7609361329834,Facility_6 -73,4,1,196.72222222222223,319.86723534558183,Facility_6 -74,4,2,190.38888888888889,309.5693350831146,Facility_6 -75,4,3,187.66666666666666,305.14304461942254,Facility_6 -76,4,4,228.0,370.7244094488189,Facility_6 -77,4,5,241.94444444444446,393.3978565179353,Facility_6 -78,4,6,326.8888888888889,531.5161854768154,Facility_6 -79,4,7,354.27777777777777,576.0500874890639,Facility_6 -80,4,8,386.55555555555554,628.5332458442695,Facility_6 -81,4,9,393.22222222222223,639.3731408573929,Facility_6 -82,4,10,395.1666666666667,642.5347769028872,Facility_6 -83,4,11,402.3333333333333,654.1876640419947,Facility_6 -84,4,12,407.6111111111111,662.7692475940507,Facility_6 -85,4,13,414.0,673.1574803149606,Facility_6 -86,4,14,415.6666666666667,675.8674540682415,Facility_6 -87,4,15,413.1111111111111,671.7121609798775,Facility_6 -88,4,16,415.55555555555554,675.686789151356,Facility_6 -89,4,17,418.72222222222223,680.8357392825897,Facility_6 -90,4,18,411.55555555555554,669.182852143482,Facility_6 -91,4,19,409.8333333333333,666.3825459317585,Facility_6 -92,4,20,393.72222222222223,640.1861329833771,Facility_6 -93,4,21,375.22222222222223,610.1054243219597,Facility_6 -94,4,22,315.6111111111111,513.1786964129483,Facility_6 -95,4,23,284.55555555555554,462.682852143482,Facility_6 -96,5,0,232.25806451612902,377.6479552959106,Facility_6 -97,5,1,204.03225806451613,331.75323850647703,Facility_6 -98,5,2,199.247311827957,323.9729912793159,Facility_6 -99,5,3,194.19354838709677,315.75565151130303,Facility_6 -100,5,4,235.86021505376345,383.504995343324,Facility_6 -101,5,5,245.21505376344086,398.7158157649649,Facility_6 -102,5,6,329.4623655913978,535.7006180679027,Facility_6 -103,5,7,364.73118279569894,593.0471594276522,Facility_6 -104,5,8,397.5806451612903,646.4598679197358,Facility_6 -105,5,9,414.5698924731183,674.0841165015663,Facility_6 -106,5,10,426.55913978494624,693.5784438235543,Facility_6 -107,5,11,436.1290322580645,709.1389382778766,Facility_6 -108,5,12,443.1720430107527,720.5907628481924,Facility_6 -109,5,13,450.10752688172045,731.8677504021675,Facility_6 -110,5,14,453.3333333333333,737.1128608923884,Facility_6 -111,5,15,453.9247311827957,738.0744644822623,Facility_6 -112,5,16,455.59139784946234,740.7844382355431,Facility_6 -113,5,17,455.80645161290323,741.1341122682245,Facility_6 -114,5,18,455.86021505376345,741.221530776395,Facility_6 -115,5,19,451.23655913978496,733.7035390737449,Facility_6 -116,5,20,436.8279569892473,710.2753788840911,Facility_6 -117,5,21,417.5268817204301,678.8921344509355,Facility_6 -118,5,22,342.0967741935484,556.243967487935,Facility_6 -119,5,23,308.38709677419354,501.4325628651257,Facility_6 -120,6,0,267.72222222222223,435.31211723534557,Facility_6 -121,6,1,229.11111111111111,372.5310586176728,Facility_6 -122,6,2,217.38888888888889,353.4709098862642,Facility_6 -123,6,3,217.88888888888889,354.28390201224846,Facility_6 -124,6,4,263.3333333333333,428.17585301837266,Facility_6 -125,6,5,284.8888888888889,463.2248468941383,Facility_6 -126,6,6,387.0,629.2559055118111,Facility_6 -127,6,7,442.55555555555554,719.5883639545057,Facility_6 -128,6,8,478.5,778.0334645669292,Facility_6 -129,6,9,494.8888888888889,804.6815398075241,Facility_6 -130,6,10,505.6666666666667,822.2060367454069,Facility_6 -131,6,11,517.2777777777778,841.08552055993,Facility_6 -132,6,12,528.6666666666666,859.6036745406824,Facility_6 -133,6,13,534.0,868.2755905511812,Facility_6 -134,6,14,542.1111111111111,881.4641294838145,Facility_6 -135,6,15,543.3888888888889,883.5417760279965,Facility_6 -136,6,16,545.7777777777778,887.4260717410325,Facility_6 -137,6,17,552.4444444444445,898.2659667541558,Facility_6 -138,6,18,550.7222222222222,895.4656605424321,Facility_6 -139,6,19,547.5555555555555,890.3167104111985,Facility_6 -140,6,20,530.3888888888889,862.403980752406,Facility_6 -141,6,21,502.94444444444446,817.7797462817148,Facility_6 -142,6,22,397.05555555555554,645.6060804899388,Facility_6 -143,6,23,358.27777777777777,582.5540244969379,Facility_6 -144,7,0,271.6666666666667,441.7257217847769,Facility_6 -145,7,1,235.91397849462365,383.59241385149437,Facility_6 -146,7,2,220.21505376344086,358.06620946575225,Facility_6 -147,7,3,216.0215053763441,351.247565828465,Facility_6 -148,7,4,265.26881720430106,431.3229193125053,Facility_6 -149,7,5,291.2903225806452,473.63347726695457,Facility_6 -150,7,6,401.98924731182797,653.6281855897046,Facility_6 -151,7,7,468.6559139784946,762.0271357209381,Facility_6 -152,7,8,498.9247311827957,811.243755820845,Facility_6 -153,7,9,518.2795698924731,842.7144187621708,Facility_6 -154,7,10,523.7096774193549,851.5436880873763,Facility_6 -155,7,11,531.9354838709677,864.9187198374395,Facility_6 -156,7,12,539.3548387096774,876.982473964948,Facility_6 -157,7,13,550.0537634408602,894.3787570908474,Facility_6 -158,7,14,552.0967741935484,897.7006604013209,Facility_6 -159,7,15,555.9677419354839,903.994792989586,Facility_6 -160,7,16,557.2043010752689,906.005418677504,Facility_6 -161,7,17,560.5913978494624,911.5127846922361,Facility_6 -162,7,18,556.989247311828,905.6557446448227,Facility_6 -163,7,19,552.4731182795699,898.3125899585133,Facility_6 -164,7,20,535.752688172043,871.1254339175345,Facility_6 -165,7,21,505.752688172043,822.3459063584794,Facility_6 -166,7,22,408.01075268817203,663.4190585047836,Facility_6 -167,7,23,370.80645161290323,602.9254508509017,Facility_6 -168,8,0,261.4516129032258,425.11620523241044,Facility_6 -169,8,1,230.69892473118279,375.11281855897045,Facility_6 -170,8,2,213.49462365591398,347.13889594445857,Facility_6 -171,8,3,208.33333333333334,338.746719160105,Facility_6 -172,8,4,253.70967741935485,412.52794005588015,Facility_6 -173,8,5,278.3333333333333,452.56561679790025,Facility_6 -174,8,6,381.55913978494624,620.4091524849716,Facility_6 -175,8,7,447.63440860215053,727.8464990263313,Facility_6 -176,8,8,481.3440860215054,782.6579036491406,Facility_6 -177,8,9,495.3225806451613,805.3867157734315,Facility_6 -178,8,10,504.3010752688172,819.98560663788,Facility_6 -179,8,11,518.0645161290323,842.3647447294895,Facility_6 -180,8,12,532.0967741935484,865.1809753619508,Facility_6 -181,8,13,541.989247311828,881.2659808652951,Facility_6 -182,8,14,548.763440860215,892.2807128947591,Facility_6 -183,8,15,551.8817204301075,897.3509863686394,Facility_6 -184,8,16,546.6129032258065,888.7839725679452,Facility_6 -185,8,17,548.1720430107526,891.3191093048852,Facility_6 -186,8,18,542.3655913978495,881.8779104224875,Facility_6 -187,8,19,534.7849462365591,869.5519007704681,Facility_6 -188,8,20,513.8172043010753,835.4586825840319,Facility_6 -189,8,21,487.741935483871,793.0607061214123,Facility_6 -190,8,22,390.86021505376345,635.5325543984421,Facility_6 -191,8,23,352.9032258064516,573.8150876301752,Facility_6 -192,9,0,237.88888888888889,386.80358705161854,Facility_6 -193,9,1,221.44444444444446,360.06517935258097,Facility_6 -194,9,2,202.27777777777777,328.90048118985123,Facility_6 -195,9,3,202.72222222222223,329.62314085739285,Facility_6 -196,9,4,243.44444444444446,395.83683289588805,Facility_6 -197,9,5,253.05555555555554,411.46434820647414,Facility_6 -198,9,6,358.94444444444446,583.6380139982502,Facility_6 -199,9,7,389.05555555555554,632.5982064741908,Facility_6 -200,9,8,408.55555555555554,664.3048993875765,Facility_6 -201,9,9,414.94444444444446,674.6931321084865,Facility_6 -202,9,10,424.6111111111111,690.4109798775153,Facility_6 -203,9,11,440.72222222222223,716.6073928258968,Facility_6 -204,9,12,451.5,734.1318897637796,Facility_6 -205,9,13,456.72222222222223,742.6231408573929,Facility_6 -206,9,14,455.94444444444446,741.3584864391951,Facility_6 -207,9,15,458.6666666666667,745.7847769028872,Facility_6 -208,9,16,460.6111111111111,748.9464129483814,Facility_6 -209,9,17,456.44444444444446,742.1714785651794,Facility_6 -210,9,18,452.8888888888889,736.3902012248469,Facility_6 -211,9,19,444.6111111111111,722.9306649168853,Facility_6 -212,9,20,426.8888888888889,694.1146106736659,Facility_6 -213,9,21,405.3333333333333,659.0656167979002,Facility_6 -214,9,22,335.22222222222223,545.0660542432196,Facility_6 -215,9,23,304.8888888888889,495.74453193350837,Facility_6 -216,10,0,234.6031746031746,381.4610673665792,Facility_6 -217,10,1,210.6451612903226,342.50571501143,Facility_6 -218,10,2,196.61290322580646,319.68948437896876,Facility_6 -219,10,3,195.7258064516129,318.24707899415796,Facility_6 -220,10,4,242.58064516129033,394.43230886461777,Facility_6 -221,10,5,250.16129032258064,406.758318516637,Facility_6 -222,10,6,356.85483870967744,580.240347980696,Facility_6 -223,10,7,384.51612903225805,625.2171704343408,Facility_6 -224,10,8,405.64516129032256,659.5726441452882,Facility_6 -225,10,9,401.2903225806452,652.49174498349,Facility_6 -226,10,10,409.51612903225805,665.8667767335535,Facility_6 -227,10,11,414.6774193548387,674.258953517907,Facility_6 -228,10,12,420.4032258064516,683.5690246380492,Facility_6 -229,10,13,423.6290322580645,688.8141351282702,Facility_6 -230,10,14,423.06451612903226,687.8962407924815,Facility_6 -231,10,15,422.741935483871,687.3717297434595,Facility_6 -232,10,16,423.2258064516129,688.1584963169927,Facility_6 -233,10,17,425.16129032258067,691.3055626111253,Facility_6 -234,10,18,420.241935483871,683.3067691135383,Facility_6 -235,10,19,413.46774193548384,672.2920370840741,Facility_6 -236,10,20,400.64516129032256,651.4427228854457,Facility_6 -237,10,21,383.5483870967742,623.6436372872746,Facility_6 -238,10,22,321.69354838709677,523.0686436372872,Facility_6 -239,10,23,296.0483870967742,481.3700152400305,Facility_6 -240,11,0,224.33333333333334,364.76246719160105,Facility_6 -241,11,1,204.41666666666666,332.378280839895,Facility_6 -242,11,2,198.41666666666666,322.622375328084,Facility_6 -243,11,3,199.66666666666666,324.6548556430446,Facility_6 -244,11,4,241.83333333333334,393.2171916010499,Facility_6 -245,11,5,254.75,414.21948818897636,Facility_6 -246,11,6,359.0833333333333,583.8638451443569,Facility_6 -247,11,7,379.4166666666667,616.9255249343832,Facility_6 -248,11,8,390.8333333333333,635.4888451443569,Facility_6 -249,11,9,386.1666666666667,627.9009186351707,Facility_6 -250,11,10,387.5,630.0688976377953,Facility_6 -251,11,11,389.9166666666667,633.9983595800526,Facility_6 -252,11,12,393.0,639.011811023622,Facility_6 -253,11,13,396.9166666666667,645.380249343832,Facility_6 -254,11,14,404.8333333333333,658.252624671916,Facility_6 -255,11,15,401.5,652.8326771653543,Facility_6 -256,11,16,396.0,643.8897637795276,Facility_6 -257,11,17,396.75,645.1092519685039,Facility_6 -258,11,18,398.4166666666667,647.8192257217848,Facility_6 -259,11,19,398.1666666666667,647.4127296587927,Facility_6 -260,11,20,384.5,625.1909448818898,Facility_6 -261,11,21,371.0,603.2401574803149,Facility_6 -262,11,22,311.5833333333333,506.62959317585296,Facility_6 -263,11,23,287.9166666666667,468.14796587926514,Facility_6 -264,12,0,252.09677419354838,409.9053848107696,Facility_6 -265,12,1,233.8709677419355,380.2705105410211,Facility_6 -266,12,2,230.40322580645162,374.63201676403355,Facility_6 -267,12,3,226.69354838709677,368.6001397002794,Facility_6 -268,12,4,270.7258064516129,440.1958978917958,Facility_6 -269,12,5,283.7096774193548,461.3074676149352,Facility_6 -270,12,6,387.741935483871,630.4622809245618,Facility_6 -271,12,7,416.53225806451616,677.2748920497842,Facility_6 -272,12,8,421.7741935483871,685.7981965963932,Facility_6 -273,12,9,422.66129032258067,687.240601981204,Facility_6 -274,12,10,422.741935483871,687.3717297434595,Facility_6 -275,12,11,427.8225806451613,695.6327787655575,Facility_6 -276,12,12,427.98387096774195,695.8950342900686,Facility_6 -277,12,13,432.33870967741933,702.9759334518668,Facility_6 -278,12,14,432.5806451612903,703.3693167386334,Facility_6 -279,12,15,427.741935483871,695.5016510033021,Facility_6 -280,12,16,434.11290322580646,705.8607442214885,Facility_6 -281,12,17,431.3709677419355,701.4024003048006,Facility_6 -282,12,18,427.9032258064516,695.763906527813,Facility_6 -283,12,19,427.33870967741933,694.8460121920243,Facility_6 -284,12,20,417.741935483871,679.241808483617,Facility_6 -285,12,21,405.4032258064516,659.1792608585217,Facility_6 -286,12,22,345.48387096774195,561.7513335026671,Facility_6 -287,12,23,314.2741935483871,511.004889509779,Facility_6 -0,1,0,248.27956989247312,248.27956989247312,Facility_KoeBogen -1,1,1,231.72043010752688,231.72043010752688,Facility_KoeBogen -2,1,2,225.05376344086022,225.05376344086022,Facility_KoeBogen -3,1,3,224.56989247311827,224.56989247311827,Facility_KoeBogen -4,1,4,267.1505376344086,267.1505376344086,Facility_KoeBogen -5,1,5,281.02150537634407,281.02150537634407,Facility_KoeBogen -6,1,6,367.63440860215053,367.63440860215053,Facility_KoeBogen -7,1,7,397.741935483871,397.741935483871,Facility_KoeBogen -8,1,8,427.9032258064516,427.9032258064516,Facility_KoeBogen -9,1,9,431.55913978494624,431.55913978494624,Facility_KoeBogen -10,1,10,437.31182795698925,437.31182795698925,Facility_KoeBogen -11,1,11,436.18279569892474,436.18279569892474,Facility_KoeBogen -12,1,12,436.7204301075269,436.7204301075269,Facility_KoeBogen -13,1,13,440.59139784946234,440.59139784946234,Facility_KoeBogen -14,1,14,440.16129032258067,440.16129032258067,Facility_KoeBogen -15,1,15,438.6559139784946,438.6559139784946,Facility_KoeBogen -16,1,16,438.8709677419355,438.8709677419355,Facility_KoeBogen -17,1,17,440.16129032258067,440.16129032258067,Facility_KoeBogen -18,1,18,438.2258064516129,438.2258064516129,Facility_KoeBogen -19,1,19,438.1720430107527,438.1720430107527,Facility_KoeBogen -20,1,20,426.8279569892473,426.8279569892473,Facility_KoeBogen -21,1,21,410.64516129032256,410.64516129032256,Facility_KoeBogen -22,1,22,348.44086021505376,348.44086021505376,Facility_KoeBogen -23,1,23,314.89247311827955,314.89247311827955,Facility_KoeBogen -24,2,0,238.33333333333334,238.33333333333334,Facility_KoeBogen -25,2,1,219.3452380952381,219.3452380952381,Facility_KoeBogen -26,2,2,214.9404761904762,214.9404761904762,Facility_KoeBogen -27,2,3,211.9047619047619,211.9047619047619,Facility_KoeBogen -28,2,4,258.57142857142856,258.57142857142856,Facility_KoeBogen -29,2,5,276.7857142857143,276.7857142857143,Facility_KoeBogen -30,2,6,366.01190476190476,366.01190476190476,Facility_KoeBogen -31,2,7,391.48809523809524,391.48809523809524,Facility_KoeBogen -32,2,8,422.26190476190476,422.26190476190476,Facility_KoeBogen -33,2,9,433.92857142857144,433.92857142857144,Facility_KoeBogen -34,2,10,430.6547619047619,430.6547619047619,Facility_KoeBogen -35,2,11,430.35714285714283,430.35714285714283,Facility_KoeBogen -36,2,12,430.6547619047619,430.6547619047619,Facility_KoeBogen -37,2,13,431.07142857142856,431.07142857142856,Facility_KoeBogen -38,2,14,429.82142857142856,429.82142857142856,Facility_KoeBogen -39,2,15,426.3690476190476,426.3690476190476,Facility_KoeBogen -40,2,16,422.26190476190476,422.26190476190476,Facility_KoeBogen -41,2,17,426.60714285714283,426.60714285714283,Facility_KoeBogen -42,2,18,427.67857142857144,427.67857142857144,Facility_KoeBogen -43,2,19,424.5238095238095,424.5238095238095,Facility_KoeBogen -44,2,20,414.04761904761904,414.04761904761904,Facility_KoeBogen -45,2,21,400.6547619047619,400.6547619047619,Facility_KoeBogen -46,2,22,342.9761904761905,342.9761904761905,Facility_KoeBogen -47,2,23,301.7857142857143,301.7857142857143,Facility_KoeBogen -48,3,0,223.1720430107527,223.1720430107527,Facility_KoeBogen -49,3,1,203.44086021505376,203.44086021505376,Facility_KoeBogen -50,3,2,196.88888888888889,196.88888888888889,Facility_KoeBogen -51,3,3,196.88172043010752,196.88172043010752,Facility_KoeBogen -52,3,4,240.48387096774192,240.48387096774192,Facility_KoeBogen -53,3,5,257.4731182795699,257.4731182795699,Facility_KoeBogen -54,3,6,350.6989247311828,350.6989247311828,Facility_KoeBogen -55,3,7,378.2258064516129,378.2258064516129,Facility_KoeBogen -56,3,8,410.752688172043,410.752688172043,Facility_KoeBogen -57,3,9,416.8817204301075,416.8817204301075,Facility_KoeBogen -58,3,10,412.5268817204301,412.5268817204301,Facility_KoeBogen -59,3,11,411.3440860215054,411.3440860215054,Facility_KoeBogen -60,3,12,412.36559139784947,412.36559139784947,Facility_KoeBogen -61,3,13,413.1182795698925,413.1182795698925,Facility_KoeBogen -62,3,14,414.247311827957,414.247311827957,Facility_KoeBogen -63,3,15,412.258064516129,412.258064516129,Facility_KoeBogen -64,3,16,410.80645161290323,410.80645161290323,Facility_KoeBogen -65,3,17,411.61290322580646,411.61290322580646,Facility_KoeBogen -66,3,18,410.64516129032256,410.64516129032256,Facility_KoeBogen -67,3,19,409.13978494623655,409.13978494623655,Facility_KoeBogen -68,3,20,397.63440860215053,397.63440860215053,Facility_KoeBogen -69,3,21,382.2043010752688,382.2043010752688,Facility_KoeBogen -70,3,22,320.6989247311828,320.6989247311828,Facility_KoeBogen -71,3,23,292.1505376344086,292.1505376344086,Facility_KoeBogen -72,4,0,215.72222222222223,215.72222222222223,Facility_KoeBogen -73,4,1,196.72222222222223,196.72222222222223,Facility_KoeBogen -74,4,2,190.38888888888889,190.38888888888889,Facility_KoeBogen -75,4,3,187.66666666666666,187.66666666666666,Facility_KoeBogen -76,4,4,228.0,228.0,Facility_KoeBogen -77,4,5,241.94444444444446,241.94444444444446,Facility_KoeBogen -78,4,6,326.8888888888889,326.8888888888889,Facility_KoeBogen -79,4,7,354.27777777777777,354.27777777777777,Facility_KoeBogen -80,4,8,386.55555555555554,386.55555555555554,Facility_KoeBogen -81,4,9,393.22222222222223,393.22222222222223,Facility_KoeBogen -82,4,10,395.1666666666667,395.1666666666667,Facility_KoeBogen -83,4,11,402.3333333333333,402.3333333333333,Facility_KoeBogen -84,4,12,407.6111111111111,407.6111111111111,Facility_KoeBogen -85,4,13,414.0,414.0,Facility_KoeBogen -86,4,14,415.6666666666667,415.6666666666667,Facility_KoeBogen -87,4,15,413.1111111111111,413.1111111111111,Facility_KoeBogen -88,4,16,415.55555555555554,415.55555555555554,Facility_KoeBogen -89,4,17,418.72222222222223,418.72222222222223,Facility_KoeBogen -90,4,18,411.55555555555554,411.55555555555554,Facility_KoeBogen -91,4,19,409.8333333333333,409.8333333333333,Facility_KoeBogen -92,4,20,393.72222222222223,393.72222222222223,Facility_KoeBogen -93,4,21,375.22222222222223,375.22222222222223,Facility_KoeBogen -94,4,22,315.6111111111111,315.6111111111111,Facility_KoeBogen -95,4,23,284.55555555555554,284.55555555555554,Facility_KoeBogen -96,5,0,232.25806451612902,232.25806451612902,Facility_KoeBogen -97,5,1,204.03225806451613,204.03225806451613,Facility_KoeBogen -98,5,2,199.247311827957,199.247311827957,Facility_KoeBogen -99,5,3,194.19354838709677,194.19354838709677,Facility_KoeBogen -100,5,4,235.86021505376345,235.86021505376345,Facility_KoeBogen -101,5,5,245.21505376344086,245.21505376344086,Facility_KoeBogen -102,5,6,329.4623655913978,329.4623655913978,Facility_KoeBogen -103,5,7,364.73118279569894,364.73118279569894,Facility_KoeBogen -104,5,8,397.5806451612903,397.5806451612903,Facility_KoeBogen -105,5,9,414.5698924731183,414.5698924731183,Facility_KoeBogen -106,5,10,426.55913978494624,426.55913978494624,Facility_KoeBogen -107,5,11,436.1290322580645,436.1290322580645,Facility_KoeBogen -108,5,12,443.1720430107527,443.1720430107527,Facility_KoeBogen -109,5,13,450.10752688172045,450.10752688172045,Facility_KoeBogen -110,5,14,453.3333333333333,453.3333333333333,Facility_KoeBogen -111,5,15,453.9247311827957,453.9247311827957,Facility_KoeBogen -112,5,16,455.59139784946234,455.59139784946234,Facility_KoeBogen -113,5,17,455.80645161290323,455.80645161290323,Facility_KoeBogen -114,5,18,455.86021505376345,455.86021505376345,Facility_KoeBogen -115,5,19,451.23655913978496,451.23655913978496,Facility_KoeBogen -116,5,20,436.8279569892473,436.8279569892473,Facility_KoeBogen -117,5,21,417.5268817204301,417.5268817204301,Facility_KoeBogen -118,5,22,342.0967741935484,342.0967741935484,Facility_KoeBogen -119,5,23,308.38709677419354,308.38709677419354,Facility_KoeBogen -120,6,0,267.72222222222223,267.72222222222223,Facility_KoeBogen -121,6,1,229.11111111111111,229.11111111111111,Facility_KoeBogen -122,6,2,217.38888888888889,217.38888888888889,Facility_KoeBogen -123,6,3,217.88888888888889,217.88888888888889,Facility_KoeBogen -124,6,4,263.3333333333333,263.3333333333333,Facility_KoeBogen -125,6,5,284.8888888888889,284.8888888888889,Facility_KoeBogen -126,6,6,387.0,387.0,Facility_KoeBogen -127,6,7,442.55555555555554,442.55555555555554,Facility_KoeBogen -128,6,8,478.5,478.5,Facility_KoeBogen -129,6,9,494.8888888888889,494.8888888888889,Facility_KoeBogen -130,6,10,505.6666666666667,505.6666666666667,Facility_KoeBogen -131,6,11,517.2777777777778,517.2777777777778,Facility_KoeBogen -132,6,12,528.6666666666666,528.6666666666666,Facility_KoeBogen -133,6,13,534.0,534.0,Facility_KoeBogen -134,6,14,542.1111111111111,542.1111111111111,Facility_KoeBogen -135,6,15,543.3888888888889,543.3888888888889,Facility_KoeBogen -136,6,16,545.7777777777778,545.7777777777778,Facility_KoeBogen -137,6,17,552.4444444444445,552.4444444444445,Facility_KoeBogen -138,6,18,550.7222222222222,550.7222222222222,Facility_KoeBogen -139,6,19,547.5555555555555,547.5555555555555,Facility_KoeBogen -140,6,20,530.3888888888889,530.3888888888889,Facility_KoeBogen -141,6,21,502.94444444444446,502.94444444444446,Facility_KoeBogen -142,6,22,397.05555555555554,397.05555555555554,Facility_KoeBogen -143,6,23,358.27777777777777,358.27777777777777,Facility_KoeBogen -144,7,0,271.6666666666667,271.6666666666667,Facility_KoeBogen -145,7,1,235.91397849462365,235.91397849462365,Facility_KoeBogen -146,7,2,220.21505376344086,220.21505376344086,Facility_KoeBogen -147,7,3,216.0215053763441,216.0215053763441,Facility_KoeBogen -148,7,4,265.26881720430106,265.26881720430106,Facility_KoeBogen -149,7,5,291.2903225806452,291.2903225806452,Facility_KoeBogen -150,7,6,401.98924731182797,401.98924731182797,Facility_KoeBogen -151,7,7,468.6559139784946,468.6559139784946,Facility_KoeBogen -152,7,8,498.9247311827957,498.9247311827957,Facility_KoeBogen -153,7,9,518.2795698924731,518.2795698924731,Facility_KoeBogen -154,7,10,523.7096774193549,523.7096774193549,Facility_KoeBogen -155,7,11,531.9354838709677,531.9354838709677,Facility_KoeBogen -156,7,12,539.3548387096774,539.3548387096774,Facility_KoeBogen -157,7,13,550.0537634408602,550.0537634408602,Facility_KoeBogen -158,7,14,552.0967741935484,552.0967741935484,Facility_KoeBogen -159,7,15,555.9677419354839,555.9677419354839,Facility_KoeBogen -160,7,16,557.2043010752689,557.2043010752689,Facility_KoeBogen -161,7,17,560.5913978494624,560.5913978494624,Facility_KoeBogen -162,7,18,556.989247311828,556.989247311828,Facility_KoeBogen -163,7,19,552.4731182795699,552.4731182795699,Facility_KoeBogen -164,7,20,535.752688172043,535.752688172043,Facility_KoeBogen -165,7,21,505.752688172043,505.752688172043,Facility_KoeBogen -166,7,22,408.01075268817203,408.01075268817203,Facility_KoeBogen -167,7,23,370.80645161290323,370.80645161290323,Facility_KoeBogen -168,8,0,261.4516129032258,261.4516129032258,Facility_KoeBogen -169,8,1,230.69892473118279,230.69892473118279,Facility_KoeBogen -170,8,2,213.49462365591398,213.49462365591398,Facility_KoeBogen -171,8,3,208.33333333333334,208.33333333333334,Facility_KoeBogen -172,8,4,253.70967741935485,253.70967741935485,Facility_KoeBogen -173,8,5,278.3333333333333,278.3333333333333,Facility_KoeBogen -174,8,6,381.55913978494624,381.55913978494624,Facility_KoeBogen -175,8,7,447.63440860215053,447.63440860215053,Facility_KoeBogen -176,8,8,481.3440860215054,481.3440860215054,Facility_KoeBogen -177,8,9,495.3225806451613,495.3225806451613,Facility_KoeBogen -178,8,10,504.3010752688172,504.3010752688172,Facility_KoeBogen -179,8,11,518.0645161290323,518.0645161290323,Facility_KoeBogen -180,8,12,532.0967741935484,532.0967741935484,Facility_KoeBogen -181,8,13,541.989247311828,541.989247311828,Facility_KoeBogen -182,8,14,548.763440860215,548.763440860215,Facility_KoeBogen -183,8,15,551.8817204301075,551.8817204301075,Facility_KoeBogen -184,8,16,546.6129032258065,546.6129032258065,Facility_KoeBogen -185,8,17,548.1720430107526,548.1720430107526,Facility_KoeBogen -186,8,18,542.3655913978495,542.3655913978495,Facility_KoeBogen -187,8,19,534.7849462365591,534.7849462365591,Facility_KoeBogen -188,8,20,513.8172043010753,513.8172043010753,Facility_KoeBogen -189,8,21,487.741935483871,487.741935483871,Facility_KoeBogen -190,8,22,390.86021505376345,390.86021505376345,Facility_KoeBogen -191,8,23,352.9032258064516,352.9032258064516,Facility_KoeBogen -192,9,0,237.88888888888889,237.88888888888889,Facility_KoeBogen -193,9,1,221.44444444444446,221.44444444444446,Facility_KoeBogen -194,9,2,202.27777777777777,202.27777777777777,Facility_KoeBogen -195,9,3,202.72222222222223,202.72222222222223,Facility_KoeBogen -196,9,4,243.44444444444446,243.44444444444446,Facility_KoeBogen -197,9,5,253.05555555555554,253.05555555555554,Facility_KoeBogen -198,9,6,358.94444444444446,358.94444444444446,Facility_KoeBogen -199,9,7,389.05555555555554,389.05555555555554,Facility_KoeBogen -200,9,8,408.55555555555554,408.55555555555554,Facility_KoeBogen -201,9,9,414.94444444444446,414.94444444444446,Facility_KoeBogen -202,9,10,424.6111111111111,424.6111111111111,Facility_KoeBogen -203,9,11,440.72222222222223,440.72222222222223,Facility_KoeBogen -204,9,12,451.5,451.5,Facility_KoeBogen -205,9,13,456.72222222222223,456.72222222222223,Facility_KoeBogen -206,9,14,455.94444444444446,455.94444444444446,Facility_KoeBogen -207,9,15,458.6666666666667,458.6666666666667,Facility_KoeBogen -208,9,16,460.6111111111111,460.6111111111111,Facility_KoeBogen -209,9,17,456.44444444444446,456.44444444444446,Facility_KoeBogen -210,9,18,452.8888888888889,452.8888888888889,Facility_KoeBogen -211,9,19,444.6111111111111,444.6111111111111,Facility_KoeBogen -212,9,20,426.8888888888889,426.8888888888889,Facility_KoeBogen -213,9,21,405.3333333333333,405.3333333333333,Facility_KoeBogen -214,9,22,335.22222222222223,335.22222222222223,Facility_KoeBogen -215,9,23,304.8888888888889,304.8888888888889,Facility_KoeBogen -216,10,0,234.6031746031746,234.6031746031746,Facility_KoeBogen -217,10,1,210.6451612903226,210.6451612903226,Facility_KoeBogen -218,10,2,196.61290322580646,196.61290322580646,Facility_KoeBogen -219,10,3,195.7258064516129,195.7258064516129,Facility_KoeBogen -220,10,4,242.58064516129033,242.58064516129033,Facility_KoeBogen -221,10,5,250.16129032258064,250.16129032258064,Facility_KoeBogen -222,10,6,356.85483870967744,356.85483870967744,Facility_KoeBogen -223,10,7,384.51612903225805,384.51612903225805,Facility_KoeBogen -224,10,8,405.64516129032256,405.64516129032256,Facility_KoeBogen -225,10,9,401.2903225806452,401.2903225806452,Facility_KoeBogen -226,10,10,409.51612903225805,409.51612903225805,Facility_KoeBogen -227,10,11,414.6774193548387,414.6774193548387,Facility_KoeBogen -228,10,12,420.4032258064516,420.4032258064516,Facility_KoeBogen -229,10,13,423.6290322580645,423.6290322580645,Facility_KoeBogen -230,10,14,423.06451612903226,423.06451612903226,Facility_KoeBogen -231,10,15,422.741935483871,422.741935483871,Facility_KoeBogen -232,10,16,423.2258064516129,423.2258064516129,Facility_KoeBogen -233,10,17,425.16129032258067,425.16129032258067,Facility_KoeBogen -234,10,18,420.241935483871,420.241935483871,Facility_KoeBogen -235,10,19,413.46774193548384,413.46774193548384,Facility_KoeBogen -236,10,20,400.64516129032256,400.64516129032256,Facility_KoeBogen -237,10,21,383.5483870967742,383.5483870967742,Facility_KoeBogen -238,10,22,321.69354838709677,321.69354838709677,Facility_KoeBogen -239,10,23,296.0483870967742,296.0483870967742,Facility_KoeBogen -240,11,0,224.33333333333334,224.33333333333334,Facility_KoeBogen -241,11,1,204.41666666666666,204.41666666666666,Facility_KoeBogen -242,11,2,198.41666666666666,198.41666666666666,Facility_KoeBogen -243,11,3,199.66666666666666,199.66666666666666,Facility_KoeBogen -244,11,4,241.83333333333334,241.83333333333334,Facility_KoeBogen -245,11,5,254.75,254.75,Facility_KoeBogen -246,11,6,359.0833333333333,359.0833333333333,Facility_KoeBogen -247,11,7,379.4166666666667,379.4166666666667,Facility_KoeBogen -248,11,8,390.8333333333333,390.8333333333333,Facility_KoeBogen -249,11,9,386.1666666666667,386.1666666666667,Facility_KoeBogen -250,11,10,387.5,387.5,Facility_KoeBogen -251,11,11,389.9166666666667,389.9166666666667,Facility_KoeBogen -252,11,12,393.0,393.0,Facility_KoeBogen -253,11,13,396.9166666666667,396.9166666666667,Facility_KoeBogen -254,11,14,404.8333333333333,404.8333333333333,Facility_KoeBogen -255,11,15,401.5,401.5,Facility_KoeBogen -256,11,16,396.0,396.0,Facility_KoeBogen -257,11,17,396.75,396.75,Facility_KoeBogen -258,11,18,398.4166666666667,398.4166666666667,Facility_KoeBogen -259,11,19,398.1666666666667,398.1666666666667,Facility_KoeBogen -260,11,20,384.5,384.5,Facility_KoeBogen -261,11,21,371.0,371.0,Facility_KoeBogen -262,11,22,311.5833333333333,311.5833333333333,Facility_KoeBogen -263,11,23,287.9166666666667,287.9166666666667,Facility_KoeBogen -264,12,0,252.09677419354838,252.09677419354838,Facility_KoeBogen -265,12,1,233.8709677419355,233.8709677419355,Facility_KoeBogen -266,12,2,230.40322580645162,230.40322580645162,Facility_KoeBogen -267,12,3,226.69354838709677,226.69354838709677,Facility_KoeBogen -268,12,4,270.7258064516129,270.7258064516129,Facility_KoeBogen -269,12,5,283.7096774193548,283.7096774193548,Facility_KoeBogen -270,12,6,387.741935483871,387.741935483871,Facility_KoeBogen -271,12,7,416.53225806451616,416.53225806451616,Facility_KoeBogen -272,12,8,421.7741935483871,421.7741935483871,Facility_KoeBogen -273,12,9,422.66129032258067,422.66129032258067,Facility_KoeBogen -274,12,10,422.741935483871,422.741935483871,Facility_KoeBogen -275,12,11,427.8225806451613,427.8225806451613,Facility_KoeBogen -276,12,12,427.98387096774195,427.98387096774195,Facility_KoeBogen -277,12,13,432.33870967741933,432.33870967741933,Facility_KoeBogen -278,12,14,432.5806451612903,432.5806451612903,Facility_KoeBogen -279,12,15,427.741935483871,427.741935483871,Facility_KoeBogen -280,12,16,434.11290322580646,434.11290322580646,Facility_KoeBogen -281,12,17,431.3709677419355,431.3709677419355,Facility_KoeBogen -282,12,18,427.9032258064516,427.9032258064516,Facility_KoeBogen -283,12,19,427.33870967741933,427.33870967741933,Facility_KoeBogen -284,12,20,417.741935483871,417.741935483871,Facility_KoeBogen -285,12,21,405.4032258064516,405.4032258064516,Facility_KoeBogen -286,12,22,345.48387096774195,345.48387096774195,Facility_KoeBogen -287,12,23,314.2741935483871,314.2741935483871,Facility_KoeBogen diff --git a/Simulation/Operations/Operator_utils.py b/Simulation/Operations/Operator_utils.py index 5d7c7cd..315fe06 100644 --- a/Simulation/Operations/Operator_utils.py +++ b/Simulation/Operations/Operator_utils.py @@ -1,55 +1,53 @@ -# utilities.py -def get_exp_free_grid_capacity_utility( - current_time, - sim_time, - planning_interval, - num_lookahead_planning_periods, - num_lookback_periods, - baseload, - non_dispatchable_generator, - electric_storage, - charging_strategy, - charging_hub, - grid_capa -): + +def compute_free_grid_capacity(self) -> dict: + """ + Compute free grid capacity based on expected base load and non-dispatchable generation. + + Args: + self: Operator instance containing all necessary attributes + + Returns: + dict: Dictionary containing computed capacity values and time series + """ final_time = min( - sim_time, - round(current_time + planning_interval * num_lookahead_planning_periods), + self.sim_time, + round(self.env.now + self.planning_interval * self.num_lookahead_planning_periods), ) periods = [] - t = current_time + t = self.env.now while t < final_time: periods.append(t) - t += planning_interval + t += self.planning_interval free_capa_list_actual = [] base_load_list = [] generation_list = [] free_capa_list_predicted = [] + first_period_without_storage = None for t in periods: # ACTUAL baseload_max = max( - baseload.loc[t : t + planning_interval - 1]["load_kw_rescaled"] + self.baseload.loc[t : t + self.planning_interval - 1]["load_kw_rescaled"] ) generation_min = min( - non_dispatchable_generator.generation_profile_actual.loc[ - t : t + planning_interval - 1 + self.non_dispatchable_generator.generation_profile_actual.loc[ + t : t + self.planning_interval - 1 ]["pv_generation"] ) battery_max = min( - electric_storage.kW_discharge_peak, + self.electric_storage.kW_discharge_peak, ( ( - electric_storage.SoC - - electric_storage.min_energy_stored_kWh + self.electric_storage.SoC + - self.electric_storage.min_energy_stored_kWh ) - * (60 / planning_interval) + * (60 / self.planning_interval) ), ) - if charging_strategy in [ + if self.charging_strategy in [ "dynamic", "integrated_storage", "online_multi_period", @@ -57,45 +55,49 @@ def get_exp_free_grid_capacity_utility( battery_max = 0 battery_usage = 0 - if charging_hub.dynamic_pricing: + if self.charging_hub.dynamic_pricing: battery_usage = ( - electric_storage.discharging_power - - electric_storage.charging_power + self.electric_storage.discharging_power + - self.electric_storage.charging_power ) free_capa_list_actual.append( - grid_capa + self.grid_capa - baseload_max + generation_min + battery_max + battery_usage ) + # Capture the first period's capacity without storage correctly (no battery discharge or usage) + if first_period_without_storage is None: + first_period_without_storage = self.grid_capa - baseload_max + generation_min + # PREDICTED - offset_period = num_lookback_periods + offset_period = self.num_lookback_periods baseload_max_pred = max( - baseload.loc[ - (t - offset_period):(t - offset_period) + (planning_interval - 1) + self.baseload.loc[ + (t - offset_period):(t - offset_period) + (self.planning_interval - 1) ]["load_kw_rescaled"] ) generation_min_pred = min( - non_dispatchable_generator.generation_profile_forecast.loc[ - t : t + planning_interval - 1 + self.non_dispatchable_generator.generation_profile_forecast.loc[ + t : t + self.planning_interval - 1 ]["pv_generation"] ) battery_max = min( - electric_storage.kW_discharge_peak, + self.electric_storage.kW_discharge_peak, ( ( - electric_storage.SoC - - electric_storage.min_energy_stored_kWh + self.electric_storage.SoC + - self.electric_storage.min_energy_stored_kWh ) - * (60 / planning_interval) + * (60 / self.planning_interval) ), ) free_capa_list_predicted.append( - grid_capa + self.grid_capa - baseload_max_pred + generation_min_pred + battery_max @@ -105,9 +107,8 @@ def get_exp_free_grid_capacity_utility( base_load_list.append(baseload_max_pred) generation_list.append(generation_min_pred) - free_grid_capa_without_storage = ( - free_capa_list_actual[0] - battery_max - battery_usage - ) + # Use the first period's actual baseload and generation only + free_grid_capa_without_storage = first_period_without_storage if first_period_without_storage is not None else 0 return { "free_grid_capa_actual": free_capa_list_actual, diff --git a/Simulation/Operations/operator.py b/Simulation/Operations/operator.py index 0def293..9975ee0 100644 --- a/Simulation/Operations/operator.py +++ b/Simulation/Operations/operator.py @@ -7,139 +7,314 @@ from resources.logging.log import lg import numpy as np import pandas as pd +from typing import List, Dict, Any, Optional +from dataclasses import dataclass from Simulation.Operations.NonLinearAlgorithms import nonlinear_pricing -from Simulation.Operations.Operator_utils import get_exp_free_grid_capacity_utility +from Simulation.Operations.Operator_utils import compute_free_grid_capacity from Utilities.RL_environments.rl_pricing_env import convert_to_vector -class Operator: # we also need a class for normal vehicles!!! +@dataclass +class GridCapacityData: + """Data class for grid capacity information.""" + free_grid_capa_actual: List[float] + free_grid_capa_predicted: List[float] + free_grid_capa_without_storage: float + base_load_list: List[float] + generation_list: List[float] + + +@dataclass +class PricingData: + """Data class for pricing information.""" + energy_price: float + parking_price: float + pricing_mode: str + price_history: pd.DataFrame + + +@dataclass +class ChargingRequest: + """Data class for charging request information.""" + request_id: str + energy_requested: float + park_duration: int + ev: bool + mode: Optional[str] + charging_power: float + assigned_charger: Optional[Any] + + +class Operator: + """ + Main operator class for managing EV charging operations. + + Handles routing, charging, storage, and pricing decisions for electric vehicle + charging infrastructure. + """ def __init__( self, - env, - requests, - chargers, - routing_strategy, - charging_strategy, - storage_strategy, - charging_capa, - grid_capa, - sim_time, - electricity_tariff, - connector_num, - parking_spots, - baseload, - max_facility_baseload, - non_dispatchable_generator, - electric_storage, - num_lookback_periods, - planning_interval, - optimization_period_length, - num_lookahead_planning_periods, - service_level, - charging_hub, - minimum_served_demand, + env: simpy.Environment, + requests: List[Any], + chargers: List[Any], + routing_strategy: str, + charging_strategy: str, + storage_strategy: str, + charging_capa: float, + grid_capa: float, + sim_time: int, + electricity_tariff: float, + connector_num: int, + parking_spots: int, + baseload: Any, + max_facility_baseload: float, + non_dispatchable_generator: Any, + electric_storage: Any, + num_lookback_periods: int, + planning_interval: int, + optimization_period_length: int, + num_lookahead_planning_periods: int, + service_level: float, + charging_hub: Any, + minimum_served_demand: float, ): - - self.env = env # simulation environment + """ + Initialize the Operator with simulation parameters and strategies. + + Args: + env: SimPy environment for discrete event simulation + requests: List of charging requests + chargers: List of charging stations + routing_strategy: Strategy for routing vehicles to chargers + charging_strategy: Strategy for charging optimization + storage_strategy: Strategy for energy storage management + charging_capa: Charging capacity limit + grid_capa: Grid capacity limit + sim_time: Total simulation time + electricity_tariff: Electricity price + connector_num: Number of connectors + parking_spots: Number of parking spots + baseload: Base load data + max_facility_baseload: Maximum facility base load + non_dispatchable_generator: Renewable energy generator + electric_storage: Energy storage system + num_lookback_periods: Number of historical periods for prediction + planning_interval: Planning interval duration + optimization_period_length: Length of optimization period + num_lookahead_planning_periods: Number of future periods to plan + service_level: Target service level + charging_hub: Charging hub object + minimum_served_demand: Minimum demand to serve + """ + self._init_simulation_environment(env, sim_time) + self._init_planning_parameters( + num_lookback_periods, + planning_interval, + optimization_period_length, + num_lookahead_planning_periods + ) + self._init_strategies(routing_strategy, charging_strategy, storage_strategy) + self._init_infrastructure( + requests, chargers, charging_capa, grid_capa, + connector_num, parking_spots, charging_hub + ) + self._init_energy_systems( + baseload, max_facility_baseload, + non_dispatchable_generator, electric_storage + ) + self._init_pricing_configuration( + electricity_tariff, service_level, minimum_served_demand + ) + self._init_agents_and_events() + self._init_capacity_tracking() + + # Initialize based on configuration + self._initialize_strategy_dependent_behavior() + + def _init_simulation_environment(self, env: simpy.Environment, sim_time: int) -> None: + """Initialize simulation environment and timing parameters.""" + if env is None: + raise ValueError("SimPy environment cannot be None") + if sim_time <= 0: + raise ValueError("Simulation time must be positive") + + self.env = env self.sim_time = sim_time - self.num_lookback_periods = num_lookback_periods # how many pr sim periods to retrieve (history for prediction models) + + def _init_planning_parameters( + self, + num_lookback_periods: int, + planning_interval: int, + optimization_period_length: int, + num_lookahead_planning_periods: int + ) -> None: + """Initialize planning and optimization parameters.""" + # Validate parameters + if num_lookback_periods < 0: + raise ValueError("Number of lookback periods cannot be negative") + if planning_interval <= 0: + raise ValueError("Planning interval must be positive") + if optimization_period_length <= 0: + raise ValueError("Optimization period length must be positive") + if num_lookahead_planning_periods <= 0: + raise ValueError("Number of lookahead planning periods must be positive") + + self.num_lookback_periods = num_lookback_periods self.planning_interval = planning_interval self.optimization_period_length = optimization_period_length - self.num_lookahead_planning_periods = num_lookahead_planning_periods # how many planning periods do we look ahead? - self.demand_threshold = Configuration.instance().demand_threshold # min demand for serving request in kWh - self.duration_threshold = ( - Configuration.instance().duration_threshold # min duration for serving request in sim periods (i.e., seconds) - ) + self.num_lookahead_planning_periods = num_lookahead_planning_periods + + # Load configuration thresholds + config = Configuration.instance() + self.demand_threshold = config.demand_threshold + self.duration_threshold = config.duration_threshold + + def _init_strategies( + self, + routing_strategy: str, + charging_strategy: str, + storage_strategy: str + ) -> None: + """Initialize operational strategies.""" self.routing_strategy = routing_strategy self.charging_strategy = charging_strategy self.storage_strategy = storage_strategy + + def _init_infrastructure( + self, + requests: List[Any], + chargers: List[Any], + charging_capa: float, + grid_capa: float, + connector_num: int, + parking_spots: int, + charging_hub: Any + ) -> None: + """Initialize charging infrastructure components.""" self.requests = requests self.chargers = chargers self.charging_capa = charging_capa self.grid_capa = grid_capa - self.baseload = baseload - self.non_dispatchable_generator = ( - non_dispatchable_generator # this is an object - ) - self.electric_storage = electric_storage # this is an object - self.free_grid_capa_actual = ( - 0 # self.update_expected_free_grid_capacity()#0 #initialize as 0 - ) - self.free_grid_capa_predicted = ( - 0 # self.update_expected_free_grid_capacity()#0 #initialize as 0 - ) - self.free_battery_load_capa = 0 - self.free_grid_capa_without_storage = 0 - self.peak_load_history = list( - [int(max_facility_baseload)] - ) # collects peak load over sim horizon (necessary to compute l_star), initialize with base facility peak load - self.peak_load_history_inc_storage = list([int(max_facility_baseload)]) - self.electricity_tariff = electricity_tariff self.connector_num = connector_num self.parking_spots = parking_spots - self.service_level = service_level - self.arrival_event = env.event() - self.routing_decision_event = env.event() self.charging_hub = charging_hub self.storage_object = charging_hub.electric_storage - self.charging_agent = None - self.storage_agent = None - self.pricing_agent = None + + def _init_energy_systems( + self, + baseload: Any, + max_facility_baseload: float, + non_dispatchable_generator: Any, + electric_storage: Any + ) -> None: + """Initialize energy systems and load tracking.""" + self.baseload = baseload + self.non_dispatchable_generator = non_dispatchable_generator + self.electric_storage = electric_storage + + # Initialize peak load history + self.peak_load_history = [int(max_facility_baseload)] + self.peak_load_history_inc_storage = [int(max_facility_baseload)] + + def _init_pricing_configuration( + self, + electricity_tariff: float, + service_level: float, + minimum_served_demand: float + ) -> None: + """Initialize pricing and service configuration.""" + self.electricity_tariff = electricity_tariff + self.service_level = service_level self.minimum_served_demand = minimum_served_demand - self.agent_name = "PGMM" # PGM or n_step - self.generation_min = 0 - self.peak_threshold = Configuration.instance().peak_threshold - self.peak_cost = Configuration.instance().peak_cost + + # Load pricing configuration + config = Configuration.instance() + self.peak_threshold = config.peak_threshold + self.peak_cost = config.peak_cost + self.B2G = config.B2G + self.price_pairs = config.energy_prices + self.multiple_power = config.multiple_power + self.parking_fee = config.parking_price + self.pricing_parameters = config.price_parameters + self.pricing_mode = config.pricing_mode + + # Initialize pricing state + self.price_history = pd.DataFrame() self.energy_reward = 0 self.objective = 0 - self.B2G = Configuration.instance().B2G - self.price_pairs = ( - Configuration.instance().energy_prices - ) # [minimum_average_power, price] - self.price_history = pd.DataFrame() - self.multiple_power = Configuration.instance().multiple_power - self.parking_fee = Configuration.instance().parking_price - self.pricing_parameters = Configuration.instance().price_parameters - self.pricing_mode = Configuration.instance().pricing_mode + self.generation_min = 0 + + def _init_agents_and_events(self) -> None: + """Initialize agents and simulation events.""" + self.charging_agent = None + self.storage_agent = None + self.pricing_agent = None + self.agent_name = "PGMM" + + # Initialize simulation events + self.arrival_event = self.env.event() + self.routing_decision_event = self.env.event() self.organizer = simpy.Resource(self.env, capacity=1) + + def _init_capacity_tracking(self) -> None: + """Initialize capacity tracking variables.""" + self.free_grid_capa_actual = 0 + self.free_grid_capa_predicted = 0 + self.free_battery_load_capa = 0 + self.free_grid_capa_without_storage = 0 + + def _initialize_strategy_dependent_behavior(self) -> None: + """Initialize behavior based on selected strategies.""" if self.pricing_mode == "perfect_info": self.solve_pricing_with_perfect_info() + if self.charging_strategy == "average_power": - for i in requests: - i.charging_power = i.energy_requested / (i.park_duration) * 60 + self._set_average_power_charging() + + def _set_average_power_charging(self) -> None: + """Set average power charging for all requests.""" + for request in self.requests: + request.charging_power = request.energy_requested / request.park_duration * 60 ########################################## # BELOW FUNCTIONS DERIVE DECISIONS # have this update automatically each planning_period - def get_exp_free_grid_capacity(self): + def get_exp_free_grid_capacity(self) -> GridCapacityData: """ - Updates free grid capacity based on expected base load and non-dispatchable generation - :param planning_period_length: length and planning window in sim periods - :param num_lookahead_periods: number of planning periods for which plan is created - :return: + Compute and update expected free grid capacity and related time series. + + Returns: + GridCapacityData: Structured data containing all grid capacity information + + Notes: + - Reads simulation context (time, planning window) and calls the shared utility. + - Sets instance attributes used by scheduling and pricing routines. + - Returns structured data for better type safety. """ - results = get_exp_free_grid_capacity_utility( - current_time=self.env.now, - sim_time=self.sim_time, - planning_interval=self.planning_interval, - num_lookahead_planning_periods=self.num_lookahead_planning_periods, - num_lookback_periods=self.num_lookback_periods, - baseload=self.baseload, - non_dispatchable_generator=self.non_dispatchable_generator, - electric_storage=self.electric_storage, - charging_strategy=self.charging_strategy, - charging_hub=self.charging_hub, - grid_capa=self.grid_capa, + results = compute_free_grid_capacity(self) + + # Create structured data object + grid_data = GridCapacityData( + free_grid_capa_actual=results.get("free_grid_capa_actual", []), + free_grid_capa_predicted=results.get("free_grid_capa_predicted", []), + free_grid_capa_without_storage=results.get("free_grid_capa_without_storage", 0.0), + base_load_list=results.get("base_load_list", []), + generation_list=results.get("generation_list", []) ) - self.free_grid_capa_actual = results["free_grid_capa_actual"] - self.base_load_list = results["base_load_list"] - self.generation_list = results["generation_list"] - self.free_grid_capa_without_storage = results["free_grid_capa_without_storage"] - self.free_grid_capa_predicted = results["free_grid_capa_predicted"] + # Update instance attributes for backward compatibility + self.free_grid_capa_actual = grid_data.free_grid_capa_actual + self.base_load_list = grid_data.base_load_list + self.generation_list = grid_data.generation_list + self.free_grid_capa_without_storage = grid_data.free_grid_capa_without_storage + self.free_grid_capa_predicted = grid_data.free_grid_capa_predicted + + return grid_data + + def get_available_battery_load(self): """ @@ -160,208 +335,462 @@ def get_available_battery_load(self): self.free_battery_load_capa = battery_max - # routing - def get_routing_instructions(self, request): + # ============================================================================ + # ROUTING METHODS + # ============================================================================ + + def get_routing_instructions(self, request: Any) -> Any: """ - Routes new arrivals to charging stations. This is on a discrete event basis, i.e. per each arrival (as opposed to the ca) - :param routing_strategy: - :return: + Route new arrivals to charging stations. + + This is called on a discrete event basis (per arrival) as opposed to + continuous optimization approaches. + + Args: + request: Charging request to route + + Returns: + Assigned charger for the request """ - strategy_functions = { - "random": route_algos.random_charger_assignment, - "lowest_occupancy_first": route_algos.lowest_occupancy_first_charger_assignment, - "fill_one_after_other": route_algos.fill_one_after_other_charger_assignment, - "lowest_utilization_first": route_algos.lowest_utilization_first_charger_assignment, - "matching_supply_demand": route_algos.matching_supply_demand_level, - "minimum_power_requirement": route_algos.assign_to_the_minimum_power + return self._route_request_by_strategy(request) + + def _route_request_by_strategy(self, request: Any) -> Any: + """Route request using the configured routing strategy.""" + if self.routing_strategy in self._ROUTING_STRATEGIES: + return self._ROUTING_STRATEGIES[self.routing_strategy](request) + + # Fallback for perfect info strategies + if self.routing_strategy in ["perfect_info", "perfect_info_with_storage"]: + return request.assigned_charger + + raise ValueError(f"Unknown routing strategy: {self.routing_strategy}") + + @property + def _ROUTING_STRATEGIES(self) -> Dict[str, callable]: + """Get routing strategy functions.""" + return { + "random": self._route_random, + "lowest_occupancy_first": self._route_lowest_occupancy_first, + "fill_one_after_other": self._route_fill_one_after_other, + "lowest_utilization_first": self._route_lowest_utilization_first, + "matching_supply_demand": self._route_matching_supply_demand, + "minimum_power_requirement": self._route_minimum_power_requirement, } - if self.routing_strategy in strategy_functions: - charger = strategy_functions[self.routing_strategy]( - charging_stations=self.chargers, - number_of_connectors=self.connector_num, - request=request, - demand_threshold=self.demand_threshold, - duration_threshold=self.duration_threshold, - ) + def _route_random(self, request: Any) -> Any: + """Route using random charger assignment.""" + return route_algos.random_charger_assignment( + charging_stations=self.chargers, + number_of_connectors=self.connector_num, + request=request, + demand_threshold=self.demand_threshold, + duration_threshold=self.duration_threshold, + ) - if self.routing_strategy == "perfect_info": - charger = request.assigned_charger - if self.routing_strategy == "perfect_info_with_storage": - charger = request.assigned_charger - return charger + def _route_lowest_occupancy_first(self, request: Any) -> Any: + """Route using lowest occupancy first strategy.""" + return route_algos.lowest_occupancy_first_charger_assignment( + charging_stations=self.chargers, + number_of_connectors=self.connector_num, + request=request, + demand_threshold=self.demand_threshold, + duration_threshold=self.duration_threshold, + ) + + def _route_fill_one_after_other(self, request: Any) -> Any: + """Route using fill one after other strategy.""" + return route_algos.fill_one_after_other_charger_assignment( + charging_stations=self.chargers, + number_of_connectors=self.connector_num, + request=request, + demand_threshold=self.demand_threshold, + duration_threshold=self.duration_threshold, + ) - # charging - def schedule_charging_and_routing_perfect_info(self, strategy): + def _route_lowest_utilization_first(self, request: Any) -> Any: + """Route using lowest utilization first strategy.""" + return route_algos.lowest_utilization_first_charger_assignment( + charging_stations=self.chargers, + number_of_connectors=self.connector_num, + request=request, + demand_threshold=self.demand_threshold, + duration_threshold=self.duration_threshold, + ) + + def _route_matching_supply_demand(self, request: Any) -> Any: + """Route using matching supply demand strategy.""" + return route_algos.matching_supply_demand_level( + charging_stations=self.chargers, + number_of_connectors=self.connector_num, + request=request, + demand_threshold=self.demand_threshold, + duration_threshold=self.duration_threshold, + ) + + def _route_minimum_power_requirement(self, request: Any) -> Any: + """Route using minimum power requirement strategy.""" + return route_algos.assign_to_the_minimum_power( + charging_stations=self.chargers, + number_of_connectors=self.connector_num, + request=request, + demand_threshold=self.demand_threshold, + duration_threshold=self.duration_threshold, + ) + + # ============================================================================ + # CHARGING METHODS + # ============================================================================ + + def schedule_charging_and_routing_perfect_info(self, strategy: str) -> None: + """ + Schedule charging and routing using perfect information strategies. + + Args: + strategy: Charging strategy to use ("perfect_info" or "perfect_info_with_storage") + """ self.get_exp_free_grid_capacity() - connected_vehicles = [x for x in self.requests if x.mode is None and x.ev == 1] + connected_vehicles = self._get_connected_vehicles() if strategy == "perfect_info": - integrate_algos.perfect_info_charging_routing( - vehicles=connected_vehicles, - charging_stations=self.chargers, - env=self.env, - grid_capacity=self.free_grid_capa_actual, - electricity_cost=self.electricity_tariff, - baseload=self.base_load_list, - sim_time=self.sim_time, - generation=self.generation_list, - ) + self._schedule_perfect_info_charging(connected_vehicles) elif strategy == "perfect_info_with_storage" and connected_vehicles: - integrate_algos.perfect_info_charging_routing_storage( - vehicles=connected_vehicles, - charging_stations=self.chargers, - env=self.env, - grid_capacity=self.free_grid_capa_actual, - electricity_cost=self.electricity_tariff, - sim_time=self.sim_time, - storage=self.electric_storage, - baseload=self.baseload_list, - ) + self._schedule_perfect_info_charging_with_storage(connected_vehicles) + + def _get_connected_vehicles(self) -> List[Any]: + """Get list of connected vehicles that are EVs and not yet assigned a mode.""" + return [x for x in self.requests if x.mode is None and x.ev == 1] + + def _schedule_perfect_info_charging(self, connected_vehicles: List[Any]) -> None: + """Schedule charging using perfect information without storage.""" + integrate_algos.perfect_info_charging_routing( + vehicles=connected_vehicles, + charging_stations=self.chargers, + env=self.env, + grid_capacity=self.free_grid_capa_actual, + electricity_cost=self.electricity_tariff, + baseload=self.base_load_list, + sim_time=self.sim_time, + generation=self.generation_list, + ) - def apply_charging_routing_storage_perfect_info(self, charging_strategy): - hour = int((self.env.now % 1440) / 60) if charging_strategy == "perfect_info_with_storage" else int( - self.env.now / 60) + def _schedule_perfect_info_charging_with_storage(self, connected_vehicles: List[Any]) -> None: + """Schedule charging using perfect information with storage integration.""" + integrate_algos.perfect_info_charging_routing_storage( + vehicles=connected_vehicles, + charging_stations=self.chargers, + env=self.env, + grid_capacity=self.free_grid_capa_actual, + electricity_cost=self.electricity_tariff, + sim_time=self.sim_time, + storage=self.electric_storage, + baseload=self.base_load_list, + ) + def apply_charging_routing_storage_perfect_info(self, charging_strategy: str) -> None: + """ + Apply charging and storage schedules based on perfect information. + + Args: + charging_strategy: Strategy to use for charging and storage + """ + hour = self._get_current_hour(charging_strategy) + self._apply_vehicle_charging_schedules(hour) + + if self._should_apply_storage_schedule(charging_strategy): + self._apply_storage_schedule(hour) + + def _get_current_hour(self, charging_strategy: str) -> int: + """Get current hour based on charging strategy.""" + if charging_strategy == "perfect_info_with_storage": + return int((self.env.now % 1440) / 60) + return int(self.env.now / 60) + + def _apply_vehicle_charging_schedules(self, hour: int) -> None: + """Apply charging schedules to all EV requests.""" for request in self.requests: if request.ev == 1: request.charging_power = request.charge_schedule[hour] - if charging_strategy == "perfect_info_with_storage" and self.storage_object.max_capacity_kWh > 0: - storage_power = self.electric_storage.charge_schedule[hour] - if storage_power >= 0: - self.electric_storage.charge_yn = 1 - self.electric_storage.discharge_yn = 0 - self.electric_storage.discharging_power = 0 - self.electric_storage.charging_power = storage_power - else: - self.electric_storage.charge_yn = 0 - self.electric_storage.discharge_yn = 1 - self.electric_storage.discharging_power = storage_power - self.electric_storage.charging_power = 0 + def _should_apply_storage_schedule(self, charging_strategy: str) -> bool: + """Check if storage schedule should be applied.""" + return (charging_strategy == "perfect_info_with_storage" and + self.storage_object.max_capacity_kWh > 0) - def take_dynamic_pricing_actions(self): + def _apply_storage_schedule(self, hour: int) -> None: + """Apply storage charging/discharging schedule.""" + storage_power = self.electric_storage.charge_schedule[hour] + + if storage_power >= 0: + self._set_storage_charging(storage_power) + else: + self._set_storage_discharging(storage_power) + + def _set_storage_charging(self, power: float) -> None: + """Set storage to charging mode.""" + self.electric_storage.charge_yn = 1 + self.electric_storage.discharge_yn = 0 + self.electric_storage.discharging_power = 0 + self.electric_storage.charging_power = power + + def _set_storage_discharging(self, power: float) -> None: + """Set storage to discharging mode.""" + self.electric_storage.charge_yn = 0 + self.electric_storage.discharge_yn = 1 + self.electric_storage.discharging_power = power + self.electric_storage.charging_power = 0 + + # ============================================================================ + # PRICING METHODS + # ============================================================================ + + def take_dynamic_pricing_actions(self) -> None: + """Execute dynamic pricing actions and update price history.""" self.get_exp_free_grid_capacity() self.update_vehicles_status() self.take_pricing_action() - if self.pricing_mode == "Discrete": - self.price_history = pd.concat( - [ - self.price_history, - pd.DataFrame(self.price_pairs[:, 1]).transpose(), - ] - ) - if self.pricing_mode == "Continuous": - # print([self.pricing_parameters[1], self.parking_fee]) - self.price_history = pd.concat( - [ - self.price_history, - pd.DataFrame( - [self.pricing_parameters[0], self.pricing_parameters[1]] - ).transpose(), - ] - ) + self._update_dynamic_price_history() - def take_static_pricing_action(self): + def take_static_pricing_action(self) -> None: + """Execute static pricing actions and update price history.""" self.get_exp_free_grid_capacity() self.update_vehicles_status() - if self.pricing_mode == "ToU": - hour = int((self.env.now % 1440) / 60) - self.pricing_parameters[0] = ( - self.electricity_tariff[hour] - / max(self.electricity_tariff) - * Configuration.instance().max_price_ToU - ) - if self.pricing_mode == "perfect_info": - if Configuration.instance().dynamic_fix_term_pricing: - self.pricing_parameters[1] = self.price_schedules[1][hour] - self.pricing_parameters[0] = self.price_schedules[0][hour] - else: - self.pricing_parameters[1] = self.price_schedules[hour] + self._update_pricing_parameters() + self._update_static_price_history() + + def _update_dynamic_price_history(self) -> None: + """Update price history for dynamic pricing modes.""" if self.pricing_mode == "Discrete": - self.price_history = pd.concat( - [ - self.price_history, - pd.DataFrame(self.price_pairs[:, 1]).transpose(), - ] - ) - if self.pricing_mode == "Continuous" or self.pricing_mode == "ToU": - self.price_history = pd.concat( - [ - self.price_history, - pd.DataFrame( - [self.pricing_parameters[0], self.pricing_parameters[1]] - ).transpose(), - ] - ) + self._add_discrete_price_to_history() + elif self.pricing_mode == "Continuous": + self._add_continuous_price_to_history() - def take_non_learning_charging_actions(self, charging_strategy, connected_vehicles): - strategy_functions = { - "uncontrolled": charge_algos.uncontrolled, - "average_power": charge_algos.average_power, - "first_come_first_served": charge_algos.first_come_first_served, - "earliest_deadline_first": charge_algos.earliest_deadline_first, - "least_laxity_first": charge_algos.least_laxity_first, - "equal_sharing": charge_algos.equal_sharing - } - - if charging_strategy in strategy_functions: - strategy_functions[charging_strategy](env=self.env, - connected_vehicles=connected_vehicles, - charging_stations=self.chargers, - charging_capacity=self.charging_capa, - free_grid_capacity=self.free_grid_capa_actual, - planning_period_length=self.planning_interval,) + def _update_static_price_history(self) -> None: + """Update price history for static pricing modes.""" + if self.pricing_mode == "Discrete": + self._add_discrete_price_to_history() + elif self.pricing_mode in ["Continuous", "ToU"]: + self._add_continuous_price_to_history() + + def _update_pricing_parameters(self) -> None: + """Update pricing parameters based on current mode and time.""" + if self.pricing_mode == "ToU": + self._update_tou_pricing() + elif self.pricing_mode == "perfect_info": + self._update_perfect_info_pricing() + + def _update_tou_pricing(self) -> None: + """Update Time-of-Use pricing parameters.""" + hour = self._get_current_hour() + max_price = Configuration.instance().max_price_ToU + self.pricing_parameters[0] = ( + self.electricity_tariff[hour] / max(self.electricity_tariff) * max_price + ) + + def _update_perfect_info_pricing(self) -> None: + """Update perfect information pricing parameters.""" + hour = self._get_current_hour() + config = Configuration.instance() + + if config.dynamic_fix_term_pricing: + self.pricing_parameters[1] = self.price_schedules[1][hour] + self.pricing_parameters[0] = self.price_schedules[0][hour] + else: + self.pricing_parameters[1] = self.price_schedules[hour] + + def _get_current_hour(self) -> int: + """Get current hour of the simulation.""" + return int((self.env.now % 1440) / 60) + + def _add_discrete_price_to_history(self) -> None: + """Add discrete pricing data to price history.""" + self.price_history = pd.concat([ + self.price_history, + pd.DataFrame(self.price_pairs[:, 1]).transpose(), + ]) + + def _add_continuous_price_to_history(self) -> None: + """Add continuous pricing data to price history.""" + self.price_history = pd.concat([ + self.price_history, + pd.DataFrame([ + self.pricing_parameters[0], + self.pricing_parameters[1] + ]).transpose(), + ]) + + def get_current_pricing_data(self) -> PricingData: + """ + Get current pricing information as structured data. + + Returns: + PricingData: Current pricing information + """ + return PricingData( + energy_price=self.pricing_parameters[0] if len(self.pricing_parameters) > 0 else 0.0, + parking_price=self.parking_fee, + pricing_mode=self.pricing_mode, + price_history=self.price_history + ) - if charging_strategy == "online_myopic": - charge_algos.online_myopic( + # ============================================================================ + # CHARGING ACTION METHODS + # ============================================================================ + + def take_non_learning_charging_actions(self, charging_strategy: str, connected_vehicles: List[Any]) -> None: + """ + Execute non-learning charging actions based on strategy. + + Args: + charging_strategy: Strategy to use for charging + connected_vehicles: List of connected vehicles + """ + self._execute_basic_charging_strategies(charging_strategy, connected_vehicles) + self._execute_advanced_charging_strategies(charging_strategy, connected_vehicles) + + def _execute_basic_charging_strategies(self, charging_strategy: str, connected_vehicles: List[Any]) -> None: + """Execute basic charging strategies that don't require foresight.""" + basic_strategies = { + "uncontrolled": self._execute_uncontrolled_charging, + "average_power": self._execute_average_power_charging, + "first_come_first_served": self._execute_fcfs_charging, + "earliest_deadline_first": self._execute_edf_charging, + "least_laxity_first": self._execute_llf_charging, + "equal_sharing": self._execute_equal_sharing_charging, + "online_myopic": self._execute_online_myopic_charging, + } + + if charging_strategy in basic_strategies: + basic_strategies[charging_strategy](connected_vehicles) + + def _execute_advanced_charging_strategies(self, charging_strategy: str, connected_vehicles: List[Any]) -> None: + """Execute advanced charging strategies that require foresight.""" + if charging_strategy == "online_multi_period": + self._execute_online_multi_period_charging(connected_vehicles) + elif charging_strategy == "integrated_storage": + self._execute_integrated_storage_charging(connected_vehicles) + + def _execute_uncontrolled_charging(self, connected_vehicles: List[Any]) -> None: + """Execute uncontrolled charging strategy.""" + charge_algos.uncontrolled( + env=self.env, + connected_vehicles=connected_vehicles, + charging_stations=self.chargers, + charging_capacity=self.charging_capa, + free_grid_capacity=self.free_grid_capa_actual, + planning_period_length=self.planning_interval, + ) + + def _execute_average_power_charging(self, connected_vehicles: List[Any]) -> None: + """Execute average power charging strategy.""" + charge_algos.average_power( + env=self.env, + connected_vehicles=connected_vehicles, + charging_stations=self.chargers, + charging_capacity=self.charging_capa, + free_grid_capacity=self.free_grid_capa_actual, + planning_period_length=self.planning_interval, + ) + + def _execute_fcfs_charging(self, connected_vehicles: List[Any]) -> None: + """Execute first-come-first-served charging strategy.""" + charge_algos.first_come_first_served( + env=self.env, + connected_vehicles=connected_vehicles, + charging_stations=self.chargers, + charging_capacity=self.charging_capa, + free_grid_capacity=self.free_grid_capa_actual, + planning_period_length=self.planning_interval, + ) + + def _execute_edf_charging(self, connected_vehicles: List[Any]) -> None: + """Execute earliest deadline first charging strategy.""" + charge_algos.earliest_deadline_first( + env=self.env, + connected_vehicles=connected_vehicles, + charging_stations=self.chargers, + charging_capacity=self.charging_capa, + free_grid_capacity=self.free_grid_capa_actual, + planning_period_length=self.planning_interval, + ) + + def _execute_llf_charging(self, connected_vehicles: List[Any]) -> None: + """Execute least laxity first charging strategy.""" + charge_algos.least_laxity_first( + env=self.env, + connected_vehicles=connected_vehicles, + charging_stations=self.chargers, + charging_capacity=self.charging_capa, + free_grid_capacity=self.free_grid_capa_actual, + planning_period_length=self.planning_interval, + ) + + def _execute_equal_sharing_charging(self, connected_vehicles: List[Any]) -> None: + """Execute equal sharing charging strategy.""" + charge_algos.equal_sharing( + env=self.env, + connected_vehicles=connected_vehicles, + charging_stations=self.chargers, + charging_capacity=self.charging_capa, + free_grid_capacity=self.free_grid_capa_actual, + planning_period_length=self.planning_interval, + ) + + def _execute_online_myopic_charging(self, connected_vehicles: List[Any]) -> None: + """Execute online myopic charging strategy.""" + charge_algos.online_myopic( + vehicles=connected_vehicles, + charging_stations=self.chargers, + env=self.env, + grid_capacity=self.free_grid_capa_actual, + optimization_period_length=self.optimization_period_length, + alpha=0, + ) + + def _execute_online_multi_period_charging(self, connected_vehicles: List[Any]) -> None: + """Execute online multi-period charging strategy.""" + self._update_peak_threshold() + + if connected_vehicles: + charge_algos.online_multi_period( vehicles=connected_vehicles, charging_stations=self.chargers, env=self.env, - grid_capacity=self.free_grid_capa_actual, + free_grid_capa_actual=self.free_grid_capa_actual, + free_grid_capa_predicted=self.free_grid_capa_predicted, + peak_load_history=self.peak_load_history, + electricity_cost=self.electricity_tariff, + sim_time=self.sim_time, + service_level=self.service_level, optimization_period_length=self.optimization_period_length, - alpha=0, + num_lookahead_planning_periods=4, + flex_margin=0.5, + peak_threshold=self.peak_threshold, ) - # Charging algos that DO require foresight - - if charging_strategy == "online_multi_period": - if max(self.charging_hub.grid.grid_usage) > self.peak_threshold: - self.peak_threshold = max(self.charging_hub.grid.grid_usage) - if len(connected_vehicles) > 0: - charge_algos.online_multi_period( - vehicles=connected_vehicles, - charging_stations=self.chargers, - env=self.env, - free_grid_capa_actual=self.free_grid_capa_actual, - free_grid_capa_predicted=self.free_grid_capa_predicted, - peak_load_history=self.peak_load_history, - electricity_cost=self.electricity_tariff, - sim_time=self.sim_time, - service_level=self.service_level, - optimization_period_length=self.optimization_period_length, - num_lookahead_planning_periods=4, - flex_margin=0.5, - peak_threshold=self.peak_threshold, - ) + def _execute_integrated_storage_charging(self, connected_vehicles: List[Any]) -> None: + """Execute integrated storage charging strategy.""" + if connected_vehicles: + charge_algos.integrated_charging_storage( + storage=self.electric_storage, + vehicles=connected_vehicles, + charging_stations=self.chargers, + env=self.env, + free_grid_capa_actual=self.free_grid_capa_actual, + free_grid_capa_predicted=self.free_grid_capa_predicted, + peak_load_history=self.peak_load_history, + electricity_cost=self.electricity_tariff, + sim_time=self.sim_time, + service_level=self.service_level, + optimization_period_length=self.optimization_period_length, + num_lookahead_planning_periods=12, + flex_margin=0.5, + ) - if charging_strategy == "integrated_storage": - if len(connected_vehicles) > 0: - charge_algos.integrated_charging_storage( - storage=self.electric_storage, - vehicles=connected_vehicles, - charging_stations=self.chargers, - env=self.env, - free_grid_capa_actual=self.free_grid_capa_actual, - free_grid_capa_predicted=self.free_grid_capa_predicted, - peak_load_history=self.peak_load_history, - electricity_cost=self.electricity_tariff, - sim_time=self.sim_time, - service_level=self.service_level, - optimization_period_length=self.optimization_period_length, - num_lookahead_planning_periods=12, - flex_margin=0.5, - ) + def _update_peak_threshold(self) -> None: + """Update peak threshold based on current grid usage.""" + current_peak = max(self.charging_hub.grid.grid_usage) + if current_peak > self.peak_threshold: + self.peak_threshold = current_peak def take_learning_charging_actions(self, charging_strategy): if charging_strategy == "dynamic": self.update_vehicles_status() diff --git a/Simulation/model.py b/Simulation/model.py index 8c2f896..dda24f7 100644 --- a/Simulation/model.py +++ b/Simulation/model.py @@ -9,137 +9,537 @@ from Simulation.Infrastructure.electric_storage import ElectricStorage import Utilities.visualization as viz import Utilities.sim_input_processing as prep +import numpy as np +from typing import List, Dict, Any, Optional, Union +from dataclasses import dataclass # NOTE: unit sim time is defined as 1 minute real time! -# from Preferences.request_generator import RequestGenerator from Simulation.Preferences.vehicle import Vehicle -import numpy as np + + +@dataclass +class SimulationConfig: + """Configuration data for simulation parameters.""" + base_path: str + raw_output_save_path: str + visuals_save_path: str + cache_path: str + post_fix: str + sim_season: str + sim_start_date: str + day_types: List[str] + sim_duration: int + facility_list: List[str] + ev_share: float + demand_gen_approach: str + geography: str + limit_requests_to_capa: bool + year: int + + +@dataclass +class InfrastructureConfig: + """Configuration data for infrastructure parameters.""" + parking_capa: int + grid_capa: float + transformer_num: int + charging_capa: Union[float, Dict[str, float]] + min_facility_baseload: float + max_facility_baseload: float + installed_capa_PV: float + installed_storage: float + charging_num: Union[int, Dict[str, int]] + connector_num: int + chargers_type: str + + +@dataclass +class OperationsConfig: + """Configuration data for operations parameters.""" + planning_interval: int + optimization_period_length: int + lookahead: int + lookback: int + routing_algo: str + charging_algo: str + storage_algo: str + scheduling_mode: str + service_level: float + minimum_served_demand: float + penalty_for_missed_kWh: float + planning: bool + objective: str + class EVCC_Sim_Model: - # There is only one instance of this class. + """ + Main simulation model for Electric Vehicle Charging Center (EVCC). + + This class implements the singleton pattern and manages the entire simulation + including infrastructure, vehicles, and operations. + """ + + # Singleton instance __instance = None @staticmethod def instance() -> "EVCC_Sim_Model": - """Static access method.""" + """Get the singleton instance of the simulation model.""" if EVCC_Sim_Model.__instance is None: raise Exception("World was not initialized") - else: - return EVCC_Sim_Model.__instance + return EVCC_Sim_Model.__instance @staticmethod def init( - env, - search_engine, - payment_engine, - vehicle_assignment_engine, - vehicle_choice_behavior, - population_factory, - reset=False, - ): - """Static access method.""" + env: Any, + base_path: str, + raw_output_save_path: str, + visuals_save_path: str, + cache_path: str, + post_fix: str, + sim_season: str, + sim_start_date: str, + day_types: List[str], + sim_duration: int, + facility_list: List[str], + ev_share: float, + demand_gen_approach: str, + geography: str, + limit_requests_to_capa: bool, + parking_capa: int, + grid_capa: float, + transformer_num: int, + charging_capa: Union[float, Dict[str, float]], + min_facility_baseload: float, + max_facility_baseload: float, + installed_capa_PV: float, + installed_storage: float, + charging_num: Union[int, Dict[str, int]], + connector_num: int, + electricity_tariff: List[float], + prices: Dict[str, float], + year: int, + planning_interval: int, + optimization_period_length: int, + lookahead: int, + lookback: int, + routing_algo: str, + charging_algo: str, + storage_algo: str, + scheduling_mode: str, + service_level: float, + minimum_served_demand: float, + penalty_for_missed_kWh: float, + planning: bool, + objective: str, + charging_agent: Optional[Any] = None, + storage_agent: Optional[Any] = None, + pricing_agent: Optional[Any] = None, + chargers_type: str = "single", + reset: bool = False, + ) -> "EVCC_Sim_Model": + """ + Initialize the singleton instance of the simulation model. + + Args: + env: SimPy environment + base_path: Base path for data files + raw_output_save_path: Path for raw output data + visuals_save_path: Path for visualization outputs + cache_path: Path for cached data + post_fix: Postfix for file naming + sim_season: Simulation season + sim_start_date: Simulation start date + day_types: List of day types + sim_duration: Simulation duration in days + facility_list: List of facility IDs + ev_share: Electric vehicle share + demand_gen_approach: Demand generation approach + geography: Geographic region + limit_requests_to_capa: Whether to limit requests to capacity + parking_capa: Parking capacity + grid_capa: Grid capacity + transformer_num: Number of transformers + charging_capa: Charging capacity + min_facility_baseload: Minimum facility base load + max_facility_baseload: Maximum facility base load + installed_capa_PV: Installed PV capacity + installed_storage: Installed storage capacity + charging_num: Number of chargers + connector_num: Number of connectors + electricity_tariff: Electricity tariff + prices: Price configuration + year: Simulation year + planning_interval: Planning interval + optimization_period_length: Optimization period length + lookahead: Lookahead periods + lookback: Lookback periods + routing_algo: Routing algorithm + charging_algo: Charging algorithm + storage_algo: Storage algorithm + scheduling_mode: Scheduling mode + service_level: Service level + minimum_served_demand: Minimum served demand + penalty_for_missed_kWh: Penalty for missed kWh + planning: Whether planning is enabled + objective: Objective function + charging_agent: Charging agent + storage_agent: Storage agent + pricing_agent: Pricing agent + chargers_type: Type of chargers + reset: Whether to reset the singleton instance + + Returns: + EVCC_Sim_Model: The singleton instance + """ if EVCC_Sim_Model.__instance is None or reset is True: EVCC_Sim_Model( - env, - search_engine, - payment_engine, - vehicle_assignment_engine, - vehicle_choice_behavior, - population_factory, - reset, + env=env, + base_path=base_path, + raw_output_save_path=raw_output_save_path, + visuals_save_path=visuals_save_path, + cache_path=cache_path, + post_fix=post_fix, + sim_season=sim_season, + sim_start_date=sim_start_date, + day_types=day_types, + sim_duration=sim_duration, + facility_list=facility_list, + ev_share=ev_share, + demand_gen_approach=demand_gen_approach, + geography=geography, + limit_requests_to_capa=limit_requests_to_capa, + parking_capa=parking_capa, + grid_capa=grid_capa, + transformer_num=transformer_num, + charging_capa=charging_capa, + min_facility_baseload=min_facility_baseload, + max_facility_baseload=max_facility_baseload, + installed_capa_PV=installed_capa_PV, + installed_storage=installed_storage, + charging_num=charging_num, + connector_num=connector_num, + electricity_tariff=electricity_tariff, + prices=prices, + year=year, + planning_interval=planning_interval, + optimization_period_length=optimization_period_length, + lookahead=lookahead, + lookback=lookback, + routing_algo=routing_algo, + charging_algo=charging_algo, + storage_algo=storage_algo, + scheduling_mode=scheduling_mode, + service_level=service_level, + minimum_served_demand=minimum_served_demand, + penalty_for_missed_kWh=penalty_for_missed_kWh, + planning=planning, + objective=objective, + charging_agent=charging_agent, + storage_agent=storage_agent, + pricing_agent=pricing_agent, + chargers_type=chargers_type, ) return EVCC_Sim_Model.__instance def __init__( self, - base_path, - raw_output_save_path, - visuals_save_path, - cache_path, - post_fix, - env, - sim_season, - sim_start_date, - day_types, - sim_duration, - facility_list, - ev_share, - demand_gen_approach, - geography, - limit_requests_to_capa, - parking_capa, - grid_capa, - transformer_num, - charging_capa, - min_facility_baseload, - max_facility_baseload, - installed_capa_PV, - installed_storage, - charging_num, - connector_num, - electricity_tariff, - prices, - year, - planning_interval, - optimization_period_length, - lookahead, - lookback, - routing_algo, - charging_algo, - storage_algo, - scheduling_mode, - service_level, - minimum_served_demand, - penalty_for_missed_kWh, - planning, - objective, - charging_agent, - storage_agent, - pricing_agent, - chargers_type="single", + env: Any, + base_path: str, + raw_output_save_path: str, + visuals_save_path: str, + cache_path: str, + post_fix: str, + sim_season: str, + sim_start_date: str, + day_types: List[str], + sim_duration: int, + facility_list: List[str], + ev_share: float, + demand_gen_approach: str, + geography: str, + limit_requests_to_capa: bool, + parking_capa: int, + grid_capa: float, + transformer_num: int, + charging_capa: Union[float, Dict[str, float]], + min_facility_baseload: float, + max_facility_baseload: float, + installed_capa_PV: float, + installed_storage: float, + charging_num: Union[int, Dict[str, int]], + connector_num: int, + electricity_tariff: List[float], + prices: Dict[str, float], + year: int, + planning_interval: int, + optimization_period_length: int, + lookahead: int, + lookback: int, + routing_algo: str, + charging_algo: str, + storage_algo: str, + scheduling_mode: str, + service_level: float, + minimum_served_demand: float, + penalty_for_missed_kWh: float, + planning: bool, + objective: str, + charging_agent: Optional[Any] = None, + storage_agent: Optional[Any] = None, + pricing_agent: Optional[Any] = None, + chargers_type: str = "single", ): + """ + Initialize the EVCC simulation model. + + Args: + base_path: Base path for data files + raw_output_save_path: Path for raw output data + visuals_save_path: Path for visualization outputs + cache_path: Path for cached data + post_fix: Postfix for file naming + env: SimPy environment + sim_season: Simulation season + sim_start_date: Simulation start date + day_types: List of day types + sim_duration: Simulation duration in days + facility_list: List of facility IDs + ev_share: Electric vehicle share + demand_gen_approach: Demand generation approach + geography: Geographic region + limit_requests_to_capa: Whether to limit requests to capacity + parking_capa: Parking capacity + grid_capa: Grid capacity + transformer_num: Number of transformers + charging_capa: Charging capacity + min_facility_baseload: Minimum facility base load + max_facility_baseload: Maximum facility base load + installed_capa_PV: Installed PV capacity + installed_storage: Installed storage capacity + charging_num: Number of chargers + connector_num: Number of connectors + electricity_tariff: Electricity tariff + prices: Price configuration + year: Simulation year + planning_interval: Planning interval + optimization_period_length: Optimization period length + lookahead: Lookahead periods + lookback: Lookback periods + routing_algo: Routing algorithm + charging_algo: Charging algorithm + storage_algo: Storage algorithm + scheduling_mode: Scheduling mode + service_level: Service level + minimum_served_demand: Minimum served demand + penalty_for_missed_kWh: Penalty for missed kWh + planning: Whether planning is enabled + objective: Objective function + charging_agent: Charging agent + storage_agent: Storage agent + pricing_agent: Pricing agent + chargers_type: Type of chargers + """ + # Set singleton instance + EVCC_Sim_Model.__instance = self + + # Initialize configuration objects + self._init_simulation_config( + base_path, raw_output_save_path, visuals_save_path, cache_path, post_fix, + sim_season, sim_start_date, day_types, sim_duration, facility_list, + ev_share, demand_gen_approach, geography, limit_requests_to_capa, year + ) + + self._init_infrastructure_config( + parking_capa, grid_capa, transformer_num, charging_capa, + min_facility_baseload, max_facility_baseload, installed_capa_PV, + installed_storage, charging_num, connector_num, chargers_type + ) + + self._init_operations_config( + planning_interval, optimization_period_length, lookahead, lookback, + routing_algo, charging_algo, storage_algo, scheduling_mode, + service_level, minimum_served_demand, penalty_for_missed_kWh, + planning, objective + ) + + # Initialize simulation environment + self._init_simulation_environment(env, electricity_tariff, prices) + + # Initialize infrastructure and data + self._init_infrastructure_and_data() + + # Initialize operations + self._init_operations(charging_agent, storage_agent, pricing_agent) - self.random_demand = Configuration.instance().random_demand - self.data_source = Configuration.instance().data_source - self.planning = planning - self.objective = objective - # path settings + def _init_simulation_config( + self, + base_path: str, + raw_output_save_path: str, + visuals_save_path: str, + cache_path: str, + post_fix: str, + sim_season: str, + sim_start_date: str, + day_types: List[str], + sim_duration: int, + facility_list: List[str], + ev_share: float, + demand_gen_approach: str, + geography: str, + limit_requests_to_capa: bool, + year: int + ) -> None: + """Initialize simulation configuration parameters.""" + self.sim_config = SimulationConfig( + base_path=base_path, + raw_output_save_path=raw_output_save_path, + visuals_save_path=visuals_save_path, + cache_path=cache_path, + post_fix=post_fix, + sim_season=sim_season, + sim_start_date=sim_start_date, + day_types=day_types, + sim_duration=sim_duration, + facility_list=facility_list, + ev_share=ev_share, + demand_gen_approach=demand_gen_approach, + geography=geography, + limit_requests_to_capa=limit_requests_to_capa, + year=year + ) + + # Set instance attributes for backward compatibility self.base_path = base_path self.raw_output_save_path = raw_output_save_path self.post_fix = post_fix self.visuals_save_path = visuals_save_path self.cache_path = cache_path - # sim/env parameter settings - self.env = env self.sim_season = sim_season self.sim_start_date = sim_start_date self.day_types = day_types - self.sim_duration = sim_duration # in days - self.sim_time = sim_duration * 24 * 60 # in minutes + self.sim_duration = sim_duration self.facility_list = facility_list self.ev_share = ev_share self.geography = geography self.demand_gen_approach = demand_gen_approach - self.limit_requests_to_capa = limit_requests_to_capa # boolean of whether the limit parking requests to parking capacizy - self.planning_interval = planning_interval # at which intervals (in unit sim time) to do the routing/charging re-planning - self.optimization_period_length = optimization_period_length # how long a period is in the optimization (in unit sim time) - self.lookahead = lookahead # how many optimization periods ops algo looks ahead - self.lookback = lookback # how many pre-sim periods to include in data retrieval (this is the history) - self.electricity_tariff = electricity_tariff + self.limit_requests_to_capa = limit_requests_to_capa self.year = year - self.prices = prices - self.prices["peak"] = Configuration.instance().peak_cost - # infrastucture settings + + def _init_infrastructure_config( + self, + parking_capa: int, + grid_capa: float, + transformer_num: int, + charging_capa: Union[float, Dict[str, float]], + min_facility_baseload: float, + max_facility_baseload: float, + installed_capa_PV: float, + installed_storage: float, + charging_num: Union[int, Dict[str, int]], + connector_num: int, + chargers_type: str + ) -> None: + """Initialize infrastructure configuration parameters.""" + self.infrastructure_config = InfrastructureConfig( + parking_capa=parking_capa, + grid_capa=grid_capa, + transformer_num=transformer_num, + charging_capa=charging_capa, + min_facility_baseload=min_facility_baseload, + max_facility_baseload=max_facility_baseload, + installed_capa_PV=installed_capa_PV, + installed_storage=installed_storage, + charging_num=charging_num, + connector_num=connector_num, + chargers_type=chargers_type + ) + + # Set instance attributes for backward compatibility self.chargers_type = chargers_type self.charging_capa = charging_capa self.charging_num = charging_num - if chargers_type in ["single"]: - self.charging_capa = charging_capa["fast"] - self.charging_num = charging_num["fast_one"] self.connector_num = connector_num self.min_facility_baseload = min_facility_baseload self.max_facility_baseload = max_facility_baseload self.parking_capa = parking_capa + self.transformer_num = transformer_num + self.grid_capa = grid_capa + transformer_num * 200 # in kW + self.installed_capa_PV = installed_capa_PV + self.storage_capacity = installed_storage + + def _init_operations_config( + self, + planning_interval: int, + optimization_period_length: int, + lookahead: int, + lookback: int, + routing_algo: str, + charging_algo: str, + storage_algo: str, + scheduling_mode: str, + service_level: float, + minimum_served_demand: float, + penalty_for_missed_kWh: float, + planning: bool, + objective: str + ) -> None: + """Initialize operations configuration parameters.""" + self.operations_config = OperationsConfig( + planning_interval=planning_interval, + optimization_period_length=optimization_period_length, + lookahead=lookahead, + lookback=lookback, + routing_algo=routing_algo, + charging_algo=charging_algo, + storage_algo=storage_algo, + scheduling_mode=scheduling_mode, + service_level=service_level, + minimum_served_demand=minimum_served_demand, + penalty_for_missed_kWh=penalty_for_missed_kWh, + planning=planning, + objective=objective + ) + + # Set instance attributes for backward compatibility + self.planning_interval = planning_interval + self.optimization_period_length = optimization_period_length + self.lookahead = lookahead + self.lookback = lookback + self.routing_algo = routing_algo + self.charging_algo = charging_algo + self.storage_algo = storage_algo + self.scheduling_mode = scheduling_mode + self.service_level = service_level + self.minimum_served_demand = minimum_served_demand + self.penalty_for_missed_kWh = penalty_for_missed_kWh + self.planning = planning + self.objective = objective + + def _init_simulation_environment( + self, + env: Any, + electricity_tariff: List[float], + prices: Dict[str, float] + ) -> None: + """Initialize simulation environment and basic parameters.""" + self.env = env + self.sim_time = self.sim_duration * 24 * 60 # in minutes + self.electricity_tariff = electricity_tariff + self.prices = prices.copy() + self.prices["peak"] = Configuration.instance().peak_cost + + # Load configuration + config = Configuration.instance() + self.random_demand = config.random_demand + self.data_source = config.data_source + self.benchmarking = config.benchmarking + self.dynamic_pricing = config.dynamic_pricing + self.peak_threshold = config.peak_threshold + + def _init_infrastructure_and_data(self) -> None: + """Initialize infrastructure components and load data.""" + # Load base load data self.base_load = prep.get_sim_baseload_curve( base_path=self.base_path, cache_path=self.cache_path, @@ -149,12 +549,8 @@ def __init__( min_facility_baseload=self.min_facility_baseload, max_facility_baseload=self.max_facility_baseload, ) - self.transformer_num = transformer_num # Number - self.grid_capa = grid_capa + transformer_num * 200 # in Kw - self.installed_capa_PV = installed_capa_PV # in kW - self.storage_capacity = installed_storage # in kWh - - # charging requests + + # Load charging request data self.request_data = prep.get_sim_charging_requests( base_path=self.base_path, cache_path=self.cache_path, @@ -172,26 +568,26 @@ def __init__( data_source=self.data_source, random_demand=self.random_demand ) - # self.demand_factory = None#RequestGenerator(self.env) - self.benchmarking = Configuration.instance().benchmarking - self.requests = self.EVCC_sim_setup( - self.request_data - ) # vehicles are the requests - # ops settings - self.routing_algo = routing_algo - self.charging_algo = charging_algo - self.storage_algo = storage_algo - self.scheduling_mode = scheduling_mode + + # Setup simulation + self.requests = self.EVCC_sim_setup(self.request_data) + + def _init_operations( + self, + charging_agent: Optional[Any], + storage_agent: Optional[Any], + pricing_agent: Optional[Any] + ) -> None: + """Initialize operations and agents.""" + # Initialize costs and rewards self.costs = dict(investment=0, operations=0) - self.service_level = 0 - self.minimum_served_demand = minimum_served_demand - self.penalty_for_missed_kWh = penalty_for_missed_kWh self.objective_function = 0 self.total_energy_charged = 0 self.reward = dict(costs=0, missed=0, feasibility=0, feasibility_storage=0) - self.dynamic_pricing = Configuration.instance().dynamic_pricing + + # Create operator self.operator = Operator( - env=env, + env=self.env, requests=self.requests, chargers=self.chargers, routing_strategy=self.routing_algo, @@ -203,7 +599,7 @@ def __init__( electric_storage=self.electric_storage, sim_time=self.sim_time, electricity_tariff=self.electricity_tariff, - connector_num=connector_num, + connector_num=self.connector_num, parking_spots=self.parking_spots, baseload=self.base_load, max_facility_baseload=self.max_facility_baseload, @@ -211,46 +607,69 @@ def __init__( optimization_period_length=self.optimization_period_length, num_lookahead_planning_periods=self.lookahead, num_lookback_periods=self.lookback, - service_level=service_level, + service_level=self.service_level, charging_hub=self, - minimum_served_demand=minimum_served_demand, + minimum_served_demand=self.minimum_served_demand, ) - # decision-making agents + + # Initialize agents + self._init_agents(charging_agent, storage_agent, pricing_agent) + + def _init_agents( + self, + charging_agent: Optional[Any], + storage_agent: Optional[Any], + pricing_agent: Optional[Any] + ) -> None: + """Initialize decision-making agents.""" self.charging_agent = charging_agent + self.storage_agent = storage_agent + self.pricing_agent = pricing_agent + + # Setup charging agent if self.charging_agent: self.charging_agent.environment.state = ( self.charging_agent.environment.get_state(self, self.env) ) self.charging_agent.environment.env = self.env self.charging_agent.reset_game() - self.pricing_agent = pricing_agent - if pricing_agent: + + # Setup pricing agent + if self.pricing_agent: self.pricing_agent.environment.state = self.pricing_agent.environment.get_state( self, self.env ) self.pricing_agent.environment.env = self.env self.pricing_agent.reset_game() - - if storage_agent: - self.storage_agent = storage_agent + + # Setup storage agent + if self.storage_agent: self.storage_agent.environment.state = ( self.storage_agent.environment.get_state(self, self.env) ) self.storage_agent.environment.env = self.env self.storage_agent.reset_game() - + + # Link agents to operator self.operator.charging_agent = charging_agent self.operator.storage_agent = storage_agent self.operator.pricing_agent = pricing_agent - self.peak_threshold = Configuration.instance().peak_threshold - - ############################################################## + # ============================================================================ # SETUP ENVIRONMENT + # ============================================================================ - def EVCC_sim_setup(self, request_data): - - # infrastaructur + def EVCC_sim_setup(self, request_data: pd.DataFrame) -> List[Any]: + """ + Setup the EVCC simulation environment. + + Args: + request_data: DataFrame containing charging request data + + Returns: + List of vehicle request objects + """ + # Initialize infrastructure self.initialize_infrastructure() # TODO: This is just a hack to deal with requests with the same arrival period @@ -258,102 +677,101 @@ def EVCC_sim_setup(self, request_data): # request_data = request_data.drop_duplicates(subset=['EntryMinutesFromSimStart']) # request_data = request_data.reset_index(drop=True) - # requests + # Initialize vehicle population requests = self.initialize_vehicle_population(request_data) return requests - ############################################################## - # INITIALIZE + # ============================================================================ + # INFRASTRUCTURE INITIALIZATION + # ============================================================================ - def initialize_infrastructure(self): + def initialize_infrastructure(self) -> None: """ - Initializing the charging, parking and grid infrastructure + Initialize the charging, parking and grid infrastructure. + + Creates parking lots, chargers, grid capacity, PV generation, and storage systems. """ - # parking spots + # Initialize parking infrastructure + self._init_parking_infrastructure() + + # Initialize charging infrastructure + self._init_charging_infrastructure() + + # Initialize energy infrastructure + self._init_energy_infrastructure() + + def _init_parking_infrastructure(self) -> None: + """Initialize parking infrastructure.""" self.parking_lot = ParkingLot(env=self.env, parking_capacity=100000) - ParkingSpots = self.parking_lot.parking_spots - - # chargers - Chargers = [] - if self.chargers_type not in ["single"]: - id_indicator = 0 - for i in range(self.charging_num["fast_one"]): - charger = EVCharger( - env=self.env, - id=id_indicator, - power=self.charging_capa["fast"], - period_length=self.planning_interval, - number_of_connectors=1, - ) - id_indicator += 1 - Chargers.append(charger) - for i in range(self.charging_num["fast_two"]): - charger = EVCharger( - env=self.env, - id=id_indicator, - power=self.charging_capa["fast"], - period_length=self.planning_interval, - number_of_connectors=2, - ) - id_indicator += 1 - Chargers.append(charger) - for i in range(self.charging_num["fast_four"]): - charger = EVCharger( - env=self.env, - id=id_indicator, - power=self.charging_capa["fast"], - period_length=self.planning_interval, - number_of_connectors=4, - ) - id_indicator += 1 - Chargers.append(charger) - for i in range(self.charging_num["slow_one"]): - charger = EVCharger( - env=self.env, - id=id_indicator, - power=self.charging_capa["slow"], - period_length=self.planning_interval, - number_of_connectors=1, - ) - id_indicator += 1 - Chargers.append(charger) - for i in range(self.charging_num["slow_two"]): - charger = EVCharger( - env=self.env, - id=id_indicator, - power=self.charging_capa["slow"], - period_length=self.planning_interval, - number_of_connectors=2, - ) - id_indicator += 1 - Chargers.append(charger) - for i in range(self.charging_num["slow_four"]): - charger = EVCharger( - env=self.env, - id=id_indicator, - power=self.charging_capa["slow"], - period_length=self.planning_interval, - number_of_connectors=4, - ) - id_indicator += 1 - Chargers.append(charger) + self.parking_spots = self.parking_lot.parking_spots + + def _init_charging_infrastructure(self) -> None: + """Initialize charging infrastructure.""" + self.chargers = [] + + if self.chargers_type == "single": + self._create_single_type_chargers() else: - for i in range(self.charging_num): - charger = EVCharger( - env=self.env, - id=i, - power=self.charging_capa, - period_length=self.planning_interval, - number_of_connectors=self.connector_num, - ) - Chargers.append(charger) + self._create_mixed_type_chargers() - # grid capacity - Grid = GridCapacity(self.env, self.grid_capa) + def _create_single_type_chargers(self) -> None: + """Create chargers of a single type.""" + for i in range(self.charging_num): + charger = EVCharger( + env=self.env, + id=i, + power=self.charging_capa, + period_length=self.planning_interval, + number_of_connectors=self.connector_num, + ) + self.chargers.append(charger) - # PV capacity - PV = NonDispatchableGenerator( + def _create_mixed_type_chargers(self) -> None: + """Create chargers of mixed types.""" + id_indicator = 0 + + # Create fast chargers + self._create_charger_group("fast_one", 1, id_indicator) + id_indicator += self.charging_num.get("fast_one", 0) + + self._create_charger_group("fast_two", 2, id_indicator) + id_indicator += self.charging_num.get("fast_two", 0) + + self._create_charger_group("fast_four", 4, id_indicator) + id_indicator += self.charging_num.get("fast_four", 0) + + # Create slow chargers + self._create_charger_group("slow_one", 1, id_indicator) + id_indicator += self.charging_num.get("slow_one", 0) + + self._create_charger_group("slow_two", 2, id_indicator) + id_indicator += self.charging_num.get("slow_two", 0) + + self._create_charger_group("slow_four", 4, id_indicator) + + def _create_charger_group(self, charger_type: str, connectors: int, start_id: int) -> None: + """Create a group of chargers with the same specifications.""" + count = self.charging_num.get(charger_type, 0) + power = self.charging_capa["fast"] if "fast" in charger_type else self.charging_capa["slow"] + + for i in range(count): + charger = EVCharger( + env=self.env, + id=start_id + i, + power=power, + period_length=self.planning_interval, + number_of_connectors=connectors, + ) + self.chargers.append(charger) + + def _init_energy_infrastructure(self) -> None: + """Initialize energy infrastructure (grid, PV, storage).""" + # Initialize grid capacity + self.grid = GridCapacity(self.env, self.grid_capa) + + # Initialize PV generation + self.non_dispatchable_generator = NonDispatchableGenerator( env=self.env, kW_peak=self.installed_capa_PV, base_path=self.base_path, @@ -363,78 +781,115 @@ def initialize_infrastructure(self): num_lookback_periods=self.lookback, ) - # electric storage - Storage = ElectricStorage(env=self.env, max_capacity_kWh=self.storage_capacity) + # Initialize electric storage + self.electric_storage = ElectricStorage( + env=self.env, + max_capacity_kWh=self.storage_capacity + ) - # save to objects - ( - self.parking_spots, - self.chargers, - self.grid, - self.electric_storage, - self.non_dispatchable_generator, - ) = (ParkingSpots, Chargers, Grid, Storage, PV) + # ============================================================================ + # VEHICLE POPULATION INITIALIZATION + # ============================================================================ - def initialize_vehicle_population(self, request_data): + def initialize_vehicle_population(self, request_data: pd.DataFrame) -> List[Any]: """ - Generate ordered list of Vehicle objects entering the EVCC on day=day - :param request_data: A dataframe of parking and charging requests - :param data: empirical preference data - :return: generator object containing + Generate ordered list of Vehicle objects entering the EVCC. + + Args: + request_data: DataFrame containing parking and charging requests + + Returns: + List of Vehicle objects representing charging requests """ requests = [] + for i in range(len(request_data)): - id = i # int - facility = request_data.loc[i, "SiteID"] - user_type = request_data.loc[i, "ClusterName"] - arrival_date = request_data.loc[i, "EntryDate"] # datetime object - departure_date = request_data.loc[i, "ExitDate"] # datetime object - arrival_time = request_data.loc[i, "EntryDateTime"] # datetime object - departure_time = request_data.loc[i, "ExitDateTime"] # datetime object - arrival_period = request_data.loc[ - i, "EntryMinutesFromSimStart" - ] # minutes from start of sim - departure_period = request_data.loc[ - i, "ExitMinutesFromSimStart" - ] # minutes from start of sim - if self.benchmarking: - arrival_period = ( - int(arrival_period / 60) * 60 - ) # Activate it only when we use perfect info - departure_period = ( - int(min(departure_period, self.sim_time) / 60) * 60 - ) # Activate it only when we use perfect info - # departure_period = arrival_period + 4 - ev = request_data.loc[i, "EV_yn"] # EV yes or no - energy_requested = ( - request_data.loc[i, "final_kWhRequested_updated"] * 2 - ) # kwh - energy_charged = 0 # initialize to 0 - battery_size = request_data.loc[i, "BatterySize"] # kwh - - vehicle_i = Vehicle( - self.env, - id=id, - user_type=user_type, - facility=facility, - arrival_date=arrival_date, - departure_date=departure_date, - arrival_time=arrival_time, - departure_time=departure_time, - arrival_period=arrival_period, - departure_period=departure_period, - sim_time=self.sim_time, - ev=ev, - energy_requested_input=energy_requested, - energy_charged=energy_charged, - battery_size=battery_size, - ) - - requests.append(vehicle_i) - # if self.planning is True: - requests = [i for i in requests if i.ev == 1] + vehicle = self._create_vehicle_from_request(request_data, i) + requests.append(vehicle) + return requests + def _create_vehicle_from_request(self, request_data: pd.DataFrame, index: int) -> Any: + """ + Create a vehicle object from request data. + + Args: + request_data: DataFrame containing request data + index: Index of the request in the DataFrame + + Returns: + Vehicle object + """ + # Extract basic request information + request_info = self._extract_request_info(request_data, index) + + # Create vehicle object + vehicle = Vehicle( + env=self.env, + id=request_info["id"], + facility=request_info["facility"], + user_type=request_info["user_type"], + arrival_date=request_info["arrival_date"], + departure_date=request_info["departure_date"], + arrival_time=request_info["arrival_time"], + departure_time=request_info["departure_time"], + arrival_period=request_info["arrival_period"], + departure_period=request_info["departure_period"], + ev=request_info["ev"], + energy_requested_input=request_info["energy_requested"], + sim_time=self.sim_time, + energy_charged=0, # Initialize to 0 + battery_size=request_data.loc[index, "BatterySize"] + ) + + return vehicle + + def _extract_request_info(self, request_data: pd.DataFrame, index: int) -> Dict[str, Any]: + """ + Extract request information from DataFrame. + + Args: + request_data: DataFrame containing request data + index: Index of the request + + Returns: + Dictionary containing extracted request information + """ + return { + "id": index, + "facility": request_data.loc[index, "SiteID"], + "user_type": request_data.loc[index, "ClusterName"], + "arrival_date": request_data.loc[index, "EntryDate"], + "departure_date": request_data.loc[index, "ExitDate"], + "arrival_time": request_data.loc[index, "EntryDateTime"], + "departure_time": request_data.loc[index, "ExitDateTime"], + "arrival_period": request_data.loc[index, "EntryMinutesFromSimStart"], + "departure_period": request_data.loc[index, "ExitMinutesFromSimStart"], + "ev": self._determine_ev_status(request_data, index), + "energy_requested": self._get_energy_requested(request_data, index), + "park_duration": self._calculate_park_duration(request_data, index), + "assigned_charger": None # Will be assigned during routing + } + + def _determine_ev_status(self, request_data: pd.DataFrame, index: int) -> bool: + """Determine if the request is for an electric vehicle.""" + return bool(request_data.loc[index, "EV_yn"]) + + def _get_energy_requested(self, request_data: pd.DataFrame, index: int) -> float: + """Get the energy requested for the vehicle.""" + return request_data.loc[index, "final_kWhRequested_updated"] * 2 + + def _calculate_park_duration(self, request_data: pd.DataFrame, index: int) -> int: + """Calculate the parking duration for the vehicle.""" + arrival_period = request_data.loc[index, "EntryMinutesFromSimStart"] + departure_period = request_data.loc[index, "ExitMinutesFromSimStart"] + + if self.benchmarking: + arrival_period = int(arrival_period / 60) * 60 + departure_period = int(min(departure_period, self.sim_time) / 60) * 60 + + return departure_period - arrival_period + ############################################################## # RUN SIMULATION diff --git a/Utilities/sim_input_processing.py b/Utilities/sim_input_processing.py index 4d31a44..58985e9 100644 --- a/Utilities/sim_input_processing.py +++ b/Utilities/sim_input_processing.py @@ -136,7 +136,7 @@ def get_sim_charging_requests( day_types=["Workday", "Saturday", "Sunday"], limit_requests_to_capa=False, data_source = 'ACN', - random_demand = True + random_demand = False ): """ Combined processing and sampling routine diff --git a/data/output/actor_pricing_double_capa_500_2_average_power_m_200_m_post_tuning b/data/output/actor_pricing_double_capa_500_2_average_power_m_200_m_post_tuning index 2eff911..a48a8c8 100644 Binary files a/data/output/actor_pricing_double_capa_500_2_average_power_m_200_m_post_tuning and b/data/output/actor_pricing_double_capa_500_2_average_power_m_200_m_post_tuning differ diff --git a/main.py b/main.py index 088e204..91e6042 100644 --- a/main.py +++ b/main.py @@ -33,7 +33,7 @@ def run_experiments(): "slow_four": 0, } - df = run_single_simulation( + run_single_simulation( charging_agent=None, storage_agent=None, pricing_agent=None, @@ -45,8 +45,7 @@ def run_experiments(): storage_capa=STORAGE_CAPA, pv_capa=PV_CAPA, year=9, - start_day=START, - ) - return df + start_day=START) + run_experiments() \ No newline at end of file diff --git a/resources/configuration/configuration.py b/resources/configuration/configuration.py index 6d77a10..9e0ee9f 100644 --- a/resources/configuration/configuration.py +++ b/resources/configuration/configuration.py @@ -38,10 +38,10 @@ def __init__(self): self.B2G = False self.benchmarking = False self.random_demand = False - self.data_source = 'ACN' + self.data_source = 'ARKINVEST' # from ['ACN', 'ARKINVEST'] # if self.benchmarking: # self.peak_cost = 0 - self.remove_low_request_EVs = True + self.remove_low_request_EVs = False self.evaluation_after_training = False self.demand_threshold = 0 self.duration_threshold = 1000000 @@ -68,7 +68,7 @@ def __init__(self): prices = [1, 0.2] power = [11, 50] parking_price = 0 - price_parameters = [0.5, 0] + price_parameters = [1.5, 0] self.max_price_ToU = 1.5 self.degree_of_power_in_price_function = 1 # Don't change this :D # self.pricing_agent_name = 'pricing_single_22' diff --git a/Learning_experiments/Learning_Pricing.py b/resources/experiments/Learning_experiments/Learning_Pricing.py similarity index 100% rename from Learning_experiments/Learning_Pricing.py rename to resources/experiments/Learning_experiments/Learning_Pricing.py diff --git a/Learning_experiments/RL_main_discrete.py b/resources/experiments/Learning_experiments/RL_main_discrete.py similarity index 100% rename from Learning_experiments/RL_main_discrete.py rename to resources/experiments/Learning_experiments/RL_main_discrete.py diff --git a/Planning/ECIS.py b/resources/experiments/Planning_experiments/ECIS.py similarity index 100% rename from Planning/ECIS.py rename to resources/experiments/Planning_experiments/ECIS.py diff --git a/Planning/Single_plug.py b/resources/experiments/Planning_experiments/Single_plug.py similarity index 100% rename from Planning/Single_plug.py rename to resources/experiments/Planning_experiments/Single_plug.py diff --git a/Planning/Visualization_new.py b/resources/experiments/Planning_experiments/Visualization_new.py similarity index 100% rename from Planning/Visualization_new.py rename to resources/experiments/Planning_experiments/Visualization_new.py diff --git a/Planning/__init__.py b/resources/experiments/Planning_experiments/__init__.py similarity index 100% rename from Planning/__init__.py rename to resources/experiments/Planning_experiments/__init__.py diff --git a/Planning/benchmark.py b/resources/experiments/Planning_experiments/benchmark.py similarity index 100% rename from Planning/benchmark.py rename to resources/experiments/Planning_experiments/benchmark.py diff --git a/Planning/data.py b/resources/experiments/Planning_experiments/data.py similarity index 100% rename from Planning/data.py rename to resources/experiments/Planning_experiments/data.py diff --git a/Planning/log.py b/resources/experiments/Planning_experiments/log.py similarity index 100% rename from Planning/log.py rename to resources/experiments/Planning_experiments/log.py diff --git a/Planning/multi-period.py b/resources/experiments/Planning_experiments/multi-period.py similarity index 100% rename from Planning/multi-period.py rename to resources/experiments/Planning_experiments/multi-period.py diff --git a/Planning/multi-period_heterogenous-chargers.py b/resources/experiments/Planning_experiments/multi-period_heterogenous-chargers.py similarity index 100% rename from Planning/multi-period_heterogenous-chargers.py rename to resources/experiments/Planning_experiments/multi-period_heterogenous-chargers.py diff --git a/Sizing/Automated_GA.py b/resources/experiments/Sizing_experiments/Automated_GA.py similarity index 100% rename from Sizing/Automated_GA.py rename to resources/experiments/Sizing_experiments/Automated_GA.py diff --git a/Sizing/Automated_GA_Heterogenous_Chargers.py b/resources/experiments/Sizing_experiments/Automated_GA_Heterogenous_Chargers.py similarity index 100% rename from Sizing/Automated_GA_Heterogenous_Chargers.py rename to resources/experiments/Sizing_experiments/Automated_GA_Heterogenous_Chargers.py diff --git a/Sizing/Genetic_algorithm.py b/resources/experiments/Sizing_experiments/Genetic_algorithm.py similarity index 100% rename from Sizing/Genetic_algorithm.py rename to resources/experiments/Sizing_experiments/Genetic_algorithm.py diff --git a/Sizing/Grid_search.py b/resources/experiments/Sizing_experiments/Grid_search.py similarity index 100% rename from Sizing/Grid_search.py rename to resources/experiments/Sizing_experiments/Grid_search.py diff --git a/Sizing/__init__.py b/resources/experiments/Sizing_experiments/__init__.py similarity index 100% rename from Sizing/__init__.py rename to resources/experiments/Sizing_experiments/__init__.py diff --git a/Sizing/ga.py b/resources/experiments/Sizing_experiments/ga.py similarity index 100% rename from Sizing/ga.py rename to resources/experiments/Sizing_experiments/ga.py diff --git a/Sizing/multi-period_heterogenous-chargers.py b/resources/experiments/Sizing_experiments/multi-period_heterogenous-chargers.py similarity index 100% rename from Sizing/multi-period_heterogenous-chargers.py rename to resources/experiments/Sizing_experiments/multi-period_heterogenous-chargers.py diff --git a/Sizing/test.py b/resources/experiments/Sizing_experiments/test.py similarity index 100% rename from Sizing/test.py rename to resources/experiments/Sizing_experiments/test.py diff --git a/resources/experiments/__init__.py b/resources/experiments/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/resources/logging/log.py b/resources/logging/log.py index 10e5746..67fa89d 100644 --- a/resources/logging/log.py +++ b/resources/logging/log.py @@ -2,24 +2,23 @@ from resources.logging.simulation_context_filter import SimulationContextFilter -logging.basicConfig(format='%(asctime)s [%(levelname)s] [Time %(env_time)10s] [%(clazz)30s %(oid)3s]: %(message)s', - datefmt='%m/%d/%Y %I:%M:%S %p') - lg = logging.getLogger() lg.setLevel(logging.ERROR) -logging.getLogger("fiona").setLevel(logging.ERROR) -formatter = logging.Formatter('%(asctime)s [%(levelname)s] [Time %(env_time)10s] [%(clazz)30s %(oid)3s]: %(message)s') -file_handler = logging.FileHandler("report.log") -file_handler.setFormatter(formatter) -file_handler.setLevel(logging.ERROR) +# Avoid adding duplicate handlers if this module is imported multiple times +if not lg.handlers: + logging.getLogger("fiona").setLevel(logging.ERROR) + formatter = logging.Formatter('%(asctime)s [%(levelname)s] [Time %(env_time)10s] [%(clazz)30s %(oid)3s]: %(message)s') + file_handler = logging.FileHandler("report.log") + file_handler.setFormatter(formatter) + file_handler.setLevel(logging.ERROR) -stream_handler = logging.StreamHandler() -stream_handler.setFormatter(formatter) -stream_handler.setLevel(logging.ERROR) + stream_handler = logging.StreamHandler() + stream_handler.setFormatter(formatter) + stream_handler.setLevel(logging.ERROR) -lg.addHandler(file_handler) -lg.addHandler(stream_handler) + lg.addHandler(file_handler) + lg.addHandler(stream_handler) cf_init = SimulationContextFilter(filter_name='add_env', extra=[]) lg.addFilter(cf_init)