-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathalgorithmInterface.py
More file actions
114 lines (90 loc) · 3.7 KB
/
algorithmInterface.py
File metadata and controls
114 lines (90 loc) · 3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from typing import TYPE_CHECKING
from functools import reduce
from collections import defaultdict
from compositeTrack import CompositeTrack
if TYPE_CHECKING:
from network import City
class TrainSchedule:
isIntercity: bool
route: list["CompositeTrack"]
cities: dict["City", dict["City", list[tuple[int, int]]]]
totalLength: int
def __init__(self, isIntercity: bool, route: list["CompositeTrack"]):
self.isIntercity = isIntercity
self.route = route
self.totalLength: int = reduce(
lambda x, y: x + 10 + y, map(lambda x: x.totalDistance, route)
)
self.__init_cities()
def __init_cities(self):
self.cities = dict()
total = 0
for track in self.route:
dist = track.totalDistance
if track.start not in self.cities:
self.cities[track.start] = dict()
if track.end not in self.cities:
self.cities[track.end] = dict()
if track.start not in self.cities[track.end]:
self.cities[track.end][track.start] = []
if track.end not in self.cities[track.start]:
self.cities[track.start][track.end] = []
self.cities[track.start][track.end].append((total, dist + total))
self.cities[track.end][track.start].append(
(
(self.totalLength - total) * 2 + 10 - dist,
(self.totalLength - total) * 2 + 10,
)
)
total += 10 + dist
def __str__(self) -> str:
return "IsIntercity: {}, route: {}".format(self.isIntercity, self.route)
def __repr__(self) -> str:
return self.__str__()
nodeId = 0
class Node:
tValue: int
cValue: int
canGoTo: list["Node"]
isPartOf: "City"
id: int
def __init__(self, tValue: int, scheduleLength: int, isPartOf: "City"):
global nodeId
self.tValue = tValue
self.cValue = 2 * (scheduleLength + 10)
self.canGoTo = []
self.isPartOf = isPartOf
self.id = nodeId
nodeId += 1
def __eq__(self, value: "Node") -> bool:
return self.id == value.id
def __hash__(self) -> int:
return id(self)
class Schedule:
trainSchedules: list[TrainSchedule]
def traveler_network(self) -> dict[int, tuple[list[Node], list[Node]]]:
nodes: dict[int, tuple[list[Node], list[Node]]] = defaultdict(lambda: ([], []))
for schedule in self.trainSchedules:
for start, outGoingTracks in schedule.cities.items():
for end, tracks in outGoingTracks.items():
for dep, arr in tracks:
startNode = Node(dep, schedule.totalLength, start)
endNode = Node(arr, schedule.totalLength, end)
startNode.canGoTo.append(endNode)
nodes[start.id][0].append(startNode)
nodes[end.id][1].append(endNode)
for outgoingNodes, incommingNodes in nodes.values():
# one node is actualy many nodes with t-values equal to t0 + 0c ... t0 + xc where xc <= lastTrainTime
# each such node ni has connections to all nodes of opposite types nj
# such tj - cj <= ti < tj
# the cost is tj - ti
for node in incommingNodes:
node.canGoTo.extend(outgoingNodes)
return nodes
def __str__(self) -> str:
return "Schedules: {}".format("\n".join([str(x) for x in self.trainSchedules]))
def __repr__(self) -> str:
return self.__str__()
class NoAlgorithmSchedule(Schedule):
def __init__(self, trainSchedules: list[TrainSchedule]):
self.trainSchedules = trainSchedules