From 68885ff5603e565083b6255e810081c4be469249 Mon Sep 17 00:00:00 2001 From: Marco Thomas Date: Wed, 27 Jul 2022 17:35:49 +0200 Subject: [PATCH] dijkstra: add statistics for time and co2 --- classes.py | 3 +++ dijsktra.py | 39 ++++++++++++++++++++++++++++----------- graph.py | 17 +++++++++++------ main.py | 3 +-- 4 files changed, 43 insertions(+), 19 deletions(-) diff --git a/classes.py b/classes.py index 2a1af40..ad036f4 100644 --- a/classes.py +++ b/classes.py @@ -83,6 +83,9 @@ class Location: math.cos(lat1) * math.cos(lat2) * math.cos(long2 - long1) return rErde * math.acos(inner) + def is_same_continent(self, loc2) -> bool: + return self.continent == loc2.continent + class DataSet: def __init__(self, locations: dict, flights: dict, connection: tuple): diff --git a/dijsktra.py b/dijsktra.py index b2c2ff6..19f9961 100644 --- a/dijsktra.py +++ b/dijsktra.py @@ -12,10 +12,12 @@ class Dijkstra(): self.graph = graph self.table = {} for vertex in graph: - self.table.update({vertex: {"distance": 9999999, "prev": None}}) - self.table[connection[0]]["distance"] = 0 + self.table.update({vertex: {"distance": (9999999, 999999), "prev": None}}) + self.table[connection[0]]["distance"] = (0, 0) + + def algorithm(self, switch: str): + assert(switch == "time" or switch == "co2") - def algorithm(self): print("Performing Dijkstra on the following graph...") for vertex in self.graph: print(f"{vertex}: {self.graph[vertex]}") @@ -24,12 +26,20 @@ class Dijkstra(): neighbors = self.graph[v1] for n in neighbors: key = [elem for elem in n.keys()][0] # name of neighbor node - # NOTE: change time or co2 here - edge = n[key]["time"] - dist = self.table[v1]["distance"] + edge - if dist < self.table[key]["distance"]: - self.table[key]["distance"] = dist - self.table[key]["prev"] = v1 + edge = (n[key]["time"], n[key]["co2"]) + + # update both time and co2 + time = self.table[v1]["distance"][0] + edge[0] + co2 = self.table[v1]["distance"][1] + edge[1] + # but only eval the one we want + if switch == "time": + if time < self.table[key]["distance"][0]: + self.table[key]["distance"] = (time, co2) + self.table[key]["prev"] = v1 + elif switch == "co2": + if co2 < self.table[key]["distance"][1]: + self.table[key]["distance"] = (time, co2) + self.table[key]["prev"] = v1 print("self.table:", self.table) @@ -39,10 +49,17 @@ class Dijkstra(): # start at destination sequence.append(dest) + total_time = 0 + total_co2 = 0 + while start not in sequence: - # previous jump - prev = self.table[sequence[-1]]["prev"] + current = self.table[sequence[-1]] # last element of list + prev = current["prev"] + total_time += current["distance"][0] + total_co2 += current["distance"][1] sequence.append(prev) sequence.reverse() print(sequence) + print("Total Time:", total_time) + print("Total CO2:", total_co2) diff --git a/graph.py b/graph.py index ff6c2a8..d68a68e 100644 --- a/graph.py +++ b/graph.py @@ -50,7 +50,6 @@ def calc_time( if distance <= 25: return distance / TransportMethod.OEPNV.value.speed else: - # NOTE: should we subtract here? return (distance / TransportMethod.ICE.value.speed) case TransportKind.FLYING: assert(flights != None) @@ -100,10 +99,15 @@ def create_graph(dataset: DataSet) -> dict: print(f"Added new INDIVIDUAL connection from {start} to {dest}") # Train - if locations[start].type == LocationType.HALTESTELLE: + is_haltestelle = locations[start].type == LocationType.HALTESTELLE + is_same_continent = locations[start].is_same_continent(locations[dest]) + # trains only drive from haltestelle and same continent + if is_haltestelle and is_same_continent: dest_type = locations[dest].type # there are only trains between haltestellen or airports - if dest_type == LocationType.HALTESTELLE or dest_type == LocationType.FLUGHAFEN: + is_dest_haltestelle = dest_type == LocationType.HALTESTELLE + is_dest_flughafen = dest_type == LocationType.FLUGHAFEN + if is_dest_haltestelle or is_dest_flughafen: dist = distance + distance * TransportKind.TRAIN.value time = calc_time(dist, TransportKind.TRAIN) co2 = calc_co2(dist, TransportKind.TRAIN) @@ -121,10 +125,11 @@ def create_graph(dataset: DataSet) -> dict: start = flight dest = flights[flight]["to"] distance = locations[start].distance(locations[dest]) - time = calc_time(distance * TransportKind.FLYING.value, TransportKind.FLYING, flights, start) - co2 = calc_co2(distance * TransportKind.FLYING.value, TransportKind.FLYING) + dist = distance + distance * TransportKind.FLYING.value + time = calc_time(dist, TransportKind.FLYING, flights, start) + co2 = calc_co2(dist, TransportKind.FLYING) new_connection: dict = {dest: - {"kind": TransportKind.TRAIN, + {"kind": TransportKind.FLYING, "co2": co2, "time": time}} graph[start].append(new_connection) diff --git a/main.py b/main.py index a8205a1..1e4d5e6 100644 --- a/main.py +++ b/main.py @@ -15,11 +15,10 @@ def main(): # parse inputfile dataset: dict = parse(INPUTFILE) # create graph - # TODO: train only on same continent graph: dict = create_graph(dataset) # solve dijkstra = Dijkstra(graph, dataset.connection) - dijkstra.algorithm() + dijkstra.algorithm("time") dijkstra.print_result(dataset.connection)