Files
ihk-dijkstra/graph.py
2022-07-27 17:01:59 +02:00

134 lines
5.0 KiB
Python

"""
Module, which creates a graph
"""
from classes import DataSet, LocationType, TransportMethod, TransportKind
def calc_co2(distance: float, kind: TransportKind) -> float:
"""
Return co2 emission in kg
"""
match kind:
case TransportKind.INDIVIDUAL:
if distance <= 1:
return 0
else:
# TODO: CITY == AUTOBAHN
return (distance - 1) * TransportMethod.CITY.value.co2
case TransportKind.TRAIN:
# TODO: OPENV == ICE
return distance * TransportMethod.ICE.value.co2
case TransportKind.FLYING:
return distance * TransportMethod.AIRPLANE.value.co2
def calc_time(
distance: float,
kind: TransportKind,
flights: dict = None,
frm: dict = None,
) -> float:
"""
distance: distance without penalty
kind: kind of transport
flights: all flights (optional)
frm: start location (need for flights, optional)
"""
match kind:
case TransportKind.INDIVIDUAL:
if distance <= 1:
return distance / TransportMethod.WALK.value.speed
elif distance <= 10 + 1:
speed = 1 / TransportMethod.WALK.value.speed
return speed + ((distance - 1) / TransportMethod.CITY.value.speed)
elif distance < 2000 + 10 + 1:
speed = 1 / TransportMethod.WALK.value.speed
speed += 10 / TransportMethod.CITY.value.speed
return speed + ((distance - 1 - 10) / TransportMethod.AUTOBAHN.value.speed)
case TransportKind.TRAIN:
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)
assert(frm != None)
stops = flights[frm]["stops"]
domestic = flights[frm]["domestic"]
if domestic:
time = 2
else:
time = 3
waittime = (stops + 1) * time
return waittime + (distance / TransportMethod.AIRPLANE.value.speed)
def create_graph(dataset: DataSet) -> dict:
"""
Creates the initial graph, with all edges
"""
locations = dataset.locations
graph: dict = {}
print("Creating graph...")
# add nodes with no edges
for start in locations:
graph.update({start: []})
# add edges
for start in locations:
for dest in locations:
# skip, if we wouldnt go anywhere
if start == dest:
continue
print(f"Searching for nodes from {start} to {dest}...")
distance = locations[start].distance(locations[dest])
# Individualtransport
if distance <= 2000 + 10 + 1:
dist = distance + distance * TransportKind.INDIVIDUAL.value
time = calc_time(dist, TransportKind.INDIVIDUAL)
co2 = calc_co2(dist, TransportKind.INDIVIDUAL)
new_connection: dict = {dest:
{"kind": TransportKind.INDIVIDUAL,
"co2": co2,
"time": time}}
graph[start].append(new_connection)
print(f"Added new INDIVIDUAL connection from {start} to {dest}")
# Train
if locations[start].type == LocationType.HALTESTELLE:
dest_type = locations[dest].type
# there are only trains between haltestellen or airports
if dest_type == LocationType.HALTESTELLE or dest_type == LocationType.FLUGHAFEN:
dist = distance + distance * TransportKind.TRAIN.value
time = calc_time(dist, TransportKind.TRAIN)
co2 = calc_co2(dist, TransportKind.TRAIN)
new_connection: dict = {dest:
{"kind": TransportKind.TRAIN,
"co2": co2,
"time": time}}
graph[start].append(new_connection)
print(f"Added new TRAIN connection from {start} to {dest}")
# Flying
print("Adding flights...")
flights = dataset.flights
for flight in flights:
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)
new_connection: dict = {dest:
{"kind": TransportKind.TRAIN,
"co2": co2,
"time": time}}
graph[start].append(new_connection)
print(f"Added new FLYING connection from {start} to {dest}")
return graph