diff --git a/evaluation/T.py b/evaluation/T.py index 3d70f2882f895f183ff2fb156cc47ed44588b58a..a3fb361f247ec247e0f3b8bb196546a19dfec8e2 100644 --- a/evaluation/T.py +++ b/evaluation/T.py @@ -1,6 +1,15 @@ from collections import namedtuple from dataclasses import dataclass +__all__ = [ + 'GasstationQueryRow', + 'ClassicQueryRow', + 'ChargeQueryRow', + 'AStarQueryRow', + 'Query' +] + + @dataclass class QueryRow: start_node: str @@ -20,9 +29,7 @@ class GasstationQueryRow(QueryRow): @dataclass class ChargeQueryRow(QueryRow): - time_contracted_graph: float - time_state_graph: float - + pass @dataclass class ClassicQueryRow(QueryRow): diff --git a/evaluation/queries.py b/evaluation/queries.py index 1ea254d1c00f13d44940637c35d8bcb054ebb674..1810e80bb4162fe8b51150bfc3b6f14d35efec8e 100644 --- a/evaluation/queries.py +++ b/evaluation/queries.py @@ -1,3 +1,4 @@ +import networkx as nx from time import perf_counter from evaluation.export import write_row @@ -10,12 +11,17 @@ from evaluation.T import ( from evrouting.T import Result from evrouting import gasstation, charge -from evrouting.osm.routing import GasstationAccessFunctions +from evrouting.graph_tools import ( + consumption_function_distance_factory, + DISTANCE_KEY +) +from evrouting.osm.profiles import car +from evrouting.osm.routing import GasstationAccessFunctions, a_start_heuristic __all__ = ['gasstation_query', 'charge_query', 'classic_query', 'astar_query'] -def gasstation_query(graph, conf, s, t, file): +def gasstation_query(graph, conf, s, t): f = GasstationAccessFunctions(conf['consumption']['consumption_coefficient']) start = perf_counter() @@ -50,10 +56,10 @@ def gasstation_query(graph, conf, s, t, file): ) query_time = perf_counter() - start - row = GasstationQueryRow( + return GasstationQueryRow( start_node=s, target_node=t, - query_time=query_time, + query_time=query_time + contraction_time + state_graph_time, trip_time=result.trip_time if type(result) == Result else None, nodes=len(graph.nodes), edges=len(graph.edges), @@ -62,16 +68,71 @@ def gasstation_query(graph, conf, s, t, file): time_state_graph=state_graph_time ) - write_row(file, row) +def charge_query(graph, conf, s, t): + start = perf_counter() + result = charge.shortest_path( + G=graph, + charging_stations=graph.charging_stations, + s=s, + t=t, + initial_soc=conf['mu_s'], + final_soc=conf['mu_t'], + capacity=conf['capacity'], + c=consumption_function_distance_factory(conf['consumption']['consumption_coefficient']) + ) + runtime = start - perf_counter() + + return ChargeQueryRow( + start_node=s, + target_node=t, + query_time=runtime, + trip_time=result.trip_time if type(result) == Result else None, + nodes=len(graph.nodes), + edges=len(graph.edges), + charging_stations=len(graph.charging_stations) + ) -def charge_query(graph, conf, s, t, file): - pass +def classic_query(graph, conf, s, t): + start = perf_counter() + try: + result = nx.shortest_path_length(graph, s, t, weight=DISTANCE_KEY) + except nx.NetworkXNoPath: + result = None + runtime = perf_counter() - start -def classic_query(graph, conf, s, t, file): - pass + return ClassicQueryRow( + start_node=s, + target_node=t, + query_time=runtime, + trip_time=result, + nodes=len(graph.nodes), + edges=len(graph.edges), + charging_stations=len(graph.charging_stations), + dijkstra_rank=0 + ) -def astar_query(graph, conf, s, t, file): - pass +def astar_query(graph, conf, s, t): + start = perf_counter() + try: + result = nx.astar_path_length( + graph, + s, t, + weight=DISTANCE_KEY, + heuristic=a_start_heuristic(graph, car) + ) + except nx.NetworkXNoPath: + result = None + runtime = perf_counter() - start + + return AStarQueryRow( + start_node=s, + target_node=t, + query_time=runtime, + trip_time=result, + nodes=len(graph.nodes), + edges=len(graph.edges), + charging_stations=len(graph.charging_stations) + ) diff --git a/evaluation/results/example/queries/astar.csv b/evaluation/results/example/queries/astar.csv index 19c78db8876a38a4f7312fc2f27084e82dc54b99..a80255396ba0c4cb3bc0a6483d45c6d964b427b9 100644 --- a/evaluation/results/example/queries/astar.csv +++ b/evaluation/results/example/queries/astar.csv @@ -1 +1,11 @@ start_node,target_node,query_time,trip_time,nodes,edges,charging_stations +1828418198,317431301,0.00014760599879082292,7.279169256464534,2827,5691,4 +6908239938,7286181357,0.012720081002044026,394.5397247638705,2827,5691,4 +7030626842,2598982037,0.01626204000058351,514.2422639697024,2827,5691,4 +1672334378,7322098499,0.00022359000286087394,None,2827,5691,4 +687135582,4955445788,0.02305627299938351,745.9999671853842,2827,5691,4 +1672334393,6417387131,0.00017938599921762943,None,2827,5691,4 +318650171,426930264,0.0020166660033282824,121.57850376415072,2827,5691,4 +2604684732,2604992913,0.0052501579993986525,278.957847495384,2827,5691,4 +318014996,4226442915,0.0031801030054339208,228.43086492206294,2827,5691,4 +3211622700,321209222,0.009974717999284621,439.60835992391065,2827,5691,4 diff --git a/evaluation/results/example/queries/charge.csv b/evaluation/results/example/queries/charge.csv index e0eab29be90dfcd179f5096540ab88b1f5af22ad..dbfed87f9d20151d1b1bd6a3f6a2ba1696f714ac 100644 --- a/evaluation/results/example/queries/charge.csv +++ b/evaluation/results/example/queries/charge.csv @@ -1 +1,11 @@ -start_node,target_node,query_time,trip_time,nodes,edges,charging_stations,time_contracted_graph,time_state_graph +start_node,target_node,query_time,trip_time,nodes,edges,charging_stations +1828418198,317431301,-0.00541873700422002,7.279169256464534,2828,5691,4 +6908239938,7286181357,-0.011799191997852176,None,2827,5691,4 +7030626842,2598982037,-0.009080265001102816,None,2828,5691,4 +1672334378,7322098499,-0.07304622400260996,None,2827,5691,4 +687135582,4955445788,-0.008829377002257388,None,2828,5691,4 +1672334393,6417387131,-0.004487725003855303,None,2827,5691,4 +318650171,426930264,-0.011571786999411415,None,2828,5691,4 +2604684732,2604992913,-0.01105132199882064,None,2827,5691,4 +318014996,4226442915,-0.041451365999819245,None,2828,5691,4 +3211622700,321209222,-0.010363692003011238,None,2827,5691,4 diff --git a/evaluation/results/example/queries/classic.csv b/evaluation/results/example/queries/classic.csv index ad83ad22ad3d5b243f6ebd21ff3bf933234f1968..8f03f8baafd775837418da83697af6b63f7fa36d 100644 --- a/evaluation/results/example/queries/classic.csv +++ b/evaluation/results/example/queries/classic.csv @@ -1 +1,11 @@ start_node,target_node,query_time,trip_time,nodes,edges,charging_stations,dijkstra_rank +1828418198,317431301,4.956599877914414e-05,7.279169256464534,2827,5691,4,0 +6908239938,7286181357,0.0048305089949280955,394.5397247638705,2827,5691,4,0 +7030626842,2598982037,0.004805078999197576,514.2422639697024,2827,5691,4,0 +1672334378,7322098499,6.071800453355536e-05,None,2827,5691,4,0 +687135582,4955445788,0.005866410996532068,745.9999671853842,2827,5691,4,0 +1672334393,6417387131,4.006700328318402e-05,None,2827,5691,4,0 +318650171,426930264,0.0007606210056110285,121.57850376415072,2827,5691,4,0 +2604684732,2604992913,0.002318312006536871,278.957847495384,2827,5691,4,0 +318014996,4226442915,0.0009691689992905594,228.43086492206294,2827,5691,4,0 +3211622700,321209222,0.004724771999462973,439.60835992391065,2827,5691,4,0 diff --git a/evaluation/results/example/queries/gasstation.csv b/evaluation/results/example/queries/gasstation.csv index 7d84d4cca22eac23e2026fe6fd0ef85e7b0fac51..eec367252d5a1316187257493ceedb8a5fe28435 100644 --- a/evaluation/results/example/queries/gasstation.csv +++ b/evaluation/results/example/queries/gasstation.csv @@ -1,11 +1,11 @@ start_node,target_node,query_time,trip_time,nodes,edges,charging_stations,time_contracted_graph,time_state_graph -2612700813,2632841214,0.005009925000194926,383.4794987778951,2827,5691,3,0.016830534004839137,0.00015566699585178867 -563191193,317944965,0.007466991002729628,446.99022181478455,2827,5691,3,0.017327437999483664,0.00013550499716075137 -7286240208,2604687836,0.00499775999924168,406.2307557413689,2827,5691,3,0.015518132997385692,0.0002068149988190271 -2639898855,574457829,0.0028420240050763823,339.7265922483922,2827,5691,3,0.015539429994532838,0.00013767200289294124 -2612700817,7286181375,0.005542577993765008,372.43394892215343,2827,5691,3,0.015766301003168337,0.00013465899974107742 -2616462194,4955446076,0.006115891002991702,374.0087002891246,2827,5691,3,0.015495608000492211,0.00015103199984878302 -4955446025,1505052669,0.009748128002684098,535.7659858061888,2827,5691,3,0.01556892799999332,0.0001692669975454919 -2700412801,563194900,0.0009064859987120144,161.78412446050507,2827,5691,3,0.015535534999798983,0.00013569000293500721 -5113940072,1768859059,0.05034502399939811,22741.474067970452,2827,5691,3,0.015074203001859132,0.00013480500638252124 -1929118150,687139215,0.041247827000916004,16827.8805214423,2827,5691,3,0.014938869993784465,0.0001336659988737665 +1828418198,317431301,0.013457719011057634,7.279169256464534,2827,5691,3,0.013232094002887607,0.00015533400437561795 +6908239938,7286181357,0.01858366200031014,394.5397247638705,2827,5691,3,0.011774632999731693,0.0001285780017497018 +7030626842,2598982037,0.019493229003273882,514.2422639697024,2827,5691,3,0.012273380998522043,0.0001298909992328845 +1672334378,7322098499,0.011932426001294516,None,2827,5691,3,0.011734421001165174,0.00012836899986723438 +687135582,4955445788,0.06945202999486355,15920.213155107229,2827,5691,3,0.011887456996191759,0.0001311939995503053 +1672334393,6417387131,0.011970645995461382,None,2827,5691,3,0.011739390000002459,0.0001719049978419207 +318650171,426930264,0.012910725999972783,121.57850376415072,2827,5691,3,0.011731954000424594,0.00015385100414277986 +2604684732,2604992913,0.015297935999114998,278.957847495384,2827,5691,3,0.011814755998784676,0.00013210000179242343 +318014996,4226442915,0.01378022700373549,228.43086492206294,2827,5691,3,0.012272058003873099,0.00013237199891591445 +3211622700,321209222,0.0201044030036428,439.60835992391065,2827,5691,3,0.012434723998012487,0.0001317000060225837 diff --git a/evaluation/run.py b/evaluation/run.py index 522107a4cae0c59661988b0bcaa39f7e38ed035b..fb7ce1d714a4d388fe0bc30f426d2d160c7a0836 100644 --- a/evaluation/run.py +++ b/evaluation/run.py @@ -4,17 +4,13 @@ import random from pathlib import Path import yaml - from evrouting.osm.imports import read_osm - from evaluation.T import * -from evaluation.export import write_head +from evaluation.export import write_head, write_row from evaluation.queries import * -def query_benchmark(graphs, - conf, - result_dir): +def query_benchmark(graphs, conf, result_dir): query_conf = [ Query(query_function=gasstation_query, filename='gasstation.csv', @@ -34,7 +30,7 @@ def query_benchmark(graphs, with result_dir.joinpath(filename).open('w') as f: write_head(f, row_class) for s, t in zip(start_nodes, target_nodes): - func(G, setup, s, t, f) + write_row(f, func(G, setup, s, t)) def get_map(osm_path: Path, cs_path: Path): diff --git a/evrouting/charge/routing.py b/evrouting/charge/routing.py index ce7bddc9d62dde0cfb2ee1e9d4f3d10d935be3e7..e87efa2e178f038d17246b4cf10958aa53545aa8 100644 --- a/evrouting/charge/routing.py +++ b/evrouting/charge/routing.py @@ -68,6 +68,7 @@ def shortest_path(G: nx.DiGraph, charging_stations: Set[Node], s: Node, t: Node, l_set[node_min].append(label_node_min) if node_min == t: + G.remove_node(t) return _result( label_node_min, f_soc_factory(label_node_min).minimum ) @@ -135,6 +136,7 @@ def shortest_path(G: nx.DiGraph, charging_stations: Set[Node], s: Node, t: Node, if is_new_min: prio_queue.insert(n, **keys(f_soc_factory(label_neighbour))) + G.remove_node(t) return EmptyResult() diff --git a/evrouting/graph_tools.py b/evrouting/graph_tools.py index 81bb8f24dcce07e141ebb789996c6c73fc5aed0f..a66eb82d8dc60c6e2adaabfbba39ad255175146f 100644 --- a/evrouting/graph_tools.py +++ b/evrouting/graph_tools.py @@ -70,6 +70,21 @@ def consumption_function_distance_factory(consumption: float) -> ConsumptionFunc return c +def consumption_function_time_factory(consumption: float) -> ConsumptionFunction: + """ + :param consumption: in kWh/km + """ + + def c(G, u, v): + """Returns consumption in Wh from u to v.""" + try: + return G[u][v][DISTANCE_KEY] * consumption + except KeyError: + return G[u][v][CONSUMPTION_KEY] + + return c + + class AccessFunctions: """ Class for dependency injections to access path diff --git a/evrouting/osm/routing.py b/evrouting/osm/routing.py index d04f0563de07449761ad5a79508f4e5ee7396b4b..af61effddb22be7c4e33110ec3745d6192965a6e 100644 --- a/evrouting/osm/routing.py +++ b/evrouting/osm/routing.py @@ -34,9 +34,7 @@ def haversine_distance(lon1, lat1, lon2, lat2, unit_m=True): return c * r -def shortest_path(G, s: point, t: point, profile) -> Result: - """Calc A* shortest path.""" - +def a_start_heuristic(G, profile): def dist(u, v): return haversine_distance( G.nodes[u]['lat'], @@ -46,8 +44,14 @@ def shortest_path(G, s: point, t: point, profile) -> Result: unit_m=True ) / profile['maxspeed'] * ms_to_kmh + return dist + + +def shortest_path(G, s: point, t: point, profile) -> Result: + """Calc A* shortest path.""" + try: - path = nx.astar_path(G, s, t, heuristic=dist) + path = nx.astar_path(G, s, t, heuristic=a_start_heuristic(G, profile)) except nx.NetworkXNoPath: return EmptyResult()