dijkstra: add statistics for time and co2

This commit is contained in:
Marco Thomas
2022-07-27 17:35:49 +02:00
parent de34b3acce
commit 68885ff560
4 changed files with 43 additions and 19 deletions

View File

@@ -83,6 +83,9 @@ class Location:
math.cos(lat1) * math.cos(lat2) * math.cos(long2 - long1) math.cos(lat1) * math.cos(lat2) * math.cos(long2 - long1)
return rErde * math.acos(inner) return rErde * math.acos(inner)
def is_same_continent(self, loc2) -> bool:
return self.continent == loc2.continent
class DataSet: class DataSet:
def __init__(self, locations: dict, flights: dict, connection: tuple): def __init__(self, locations: dict, flights: dict, connection: tuple):

View File

@@ -12,10 +12,12 @@ class Dijkstra():
self.graph = graph self.graph = graph
self.table = {} self.table = {}
for vertex in graph: for vertex in graph:
self.table.update({vertex: {"distance": 9999999, "prev": None}}) self.table.update({vertex: {"distance": (9999999, 999999), "prev": None}})
self.table[connection[0]]["distance"] = 0 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...") print("Performing Dijkstra on the following graph...")
for vertex in self.graph: for vertex in self.graph:
print(f"{vertex}: {self.graph[vertex]}") print(f"{vertex}: {self.graph[vertex]}")
@@ -24,12 +26,20 @@ class Dijkstra():
neighbors = self.graph[v1] neighbors = self.graph[v1]
for n in neighbors: for n in neighbors:
key = [elem for elem in n.keys()][0] # name of neighbor node key = [elem for elem in n.keys()][0] # name of neighbor node
# NOTE: change time or co2 here edge = (n[key]["time"], n[key]["co2"])
edge = n[key]["time"]
dist = self.table[v1]["distance"] + edge # update both time and co2
if dist < self.table[key]["distance"]: time = self.table[v1]["distance"][0] + edge[0]
self.table[key]["distance"] = dist co2 = self.table[v1]["distance"][1] + edge[1]
self.table[key]["prev"] = v1 # 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) print("self.table:", self.table)
@@ -39,10 +49,17 @@ class Dijkstra():
# start at destination # start at destination
sequence.append(dest) sequence.append(dest)
total_time = 0
total_co2 = 0
while start not in sequence: while start not in sequence:
# previous jump current = self.table[sequence[-1]] # last element of list
prev = self.table[sequence[-1]]["prev"] prev = current["prev"]
total_time += current["distance"][0]
total_co2 += current["distance"][1]
sequence.append(prev) sequence.append(prev)
sequence.reverse() sequence.reverse()
print(sequence) print(sequence)
print("Total Time:", total_time)
print("Total CO2:", total_co2)

View File

@@ -50,7 +50,6 @@ def calc_time(
if distance <= 25: if distance <= 25:
return distance / TransportMethod.OEPNV.value.speed return distance / TransportMethod.OEPNV.value.speed
else: else:
# NOTE: should we subtract here?
return (distance / TransportMethod.ICE.value.speed) return (distance / TransportMethod.ICE.value.speed)
case TransportKind.FLYING: case TransportKind.FLYING:
assert(flights != None) assert(flights != None)
@@ -100,10 +99,15 @@ def create_graph(dataset: DataSet) -> dict:
print(f"Added new INDIVIDUAL connection from {start} to {dest}") print(f"Added new INDIVIDUAL connection from {start} to {dest}")
# Train # 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 dest_type = locations[dest].type
# there are only trains between haltestellen or airports # 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 dist = distance + distance * TransportKind.TRAIN.value
time = calc_time(dist, TransportKind.TRAIN) time = calc_time(dist, TransportKind.TRAIN)
co2 = calc_co2(dist, TransportKind.TRAIN) co2 = calc_co2(dist, TransportKind.TRAIN)
@@ -121,10 +125,11 @@ def create_graph(dataset: DataSet) -> dict:
start = flight start = flight
dest = flights[flight]["to"] dest = flights[flight]["to"]
distance = locations[start].distance(locations[dest]) distance = locations[start].distance(locations[dest])
time = calc_time(distance * TransportKind.FLYING.value, TransportKind.FLYING, flights, start) dist = distance + distance * TransportKind.FLYING.value
co2 = calc_co2(distance * TransportKind.FLYING.value, TransportKind.FLYING) time = calc_time(dist, TransportKind.FLYING, flights, start)
co2 = calc_co2(dist, TransportKind.FLYING)
new_connection: dict = {dest: new_connection: dict = {dest:
{"kind": TransportKind.TRAIN, {"kind": TransportKind.FLYING,
"co2": co2, "co2": co2,
"time": time}} "time": time}}
graph[start].append(new_connection) graph[start].append(new_connection)

View File

@@ -15,11 +15,10 @@ def main():
# parse inputfile # parse inputfile
dataset: dict = parse(INPUTFILE) dataset: dict = parse(INPUTFILE)
# create graph # create graph
# TODO: train only on same continent
graph: dict = create_graph(dataset) graph: dict = create_graph(dataset)
# solve # solve
dijkstra = Dijkstra(graph, dataset.connection) dijkstra = Dijkstra(graph, dataset.connection)
dijkstra.algorithm() dijkstra.algorithm("time")
dijkstra.print_result(dataset.connection) dijkstra.print_result(dataset.connection)