-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSystem.py
More file actions
146 lines (130 loc) · 4.7 KB
/
System.py
File metadata and controls
146 lines (130 loc) · 4.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
from collections import defaultdict
from copy import deepcopy
from typing import List, Dict, Tuple
from BusLine import BusLine
from Bus import Bus
from Passenger import Passenger
from SizeAdviser import SizeAdviser
class System:
"""
class of the system we try to optimize
"""
def __init__(self) -> None:
"""
create new instance of system
"""
self.times_between = {}
self.bus_lines: Dict[int, BusLine] = {}
# tuple of station id: travel time
self.map = {}
# create Passenger list\
# id -> bus
self.cur_buses = defaultdict(list)
self.wait_times = defaultdict(list)
self.sizes_to_cost = {15: 200, 30: 350, 50: 550}
self.changed_cur = True
# self.wait_by_line
self.cached_cur = []
self.start_day = 60 * 5
self.end_day = 60 * 2
# create bus instance of line
def create_bus(self, bus_line: BusLine, minute: int, size: int, size_adviser: SizeAdviser) -> Bus:
"""
create new bus of specific line
:param bus_line: the line the new bus belong to
:param minute: the exit time of the new bus
:param size: the max amount of passengers can be on the bus at the same time
:param size_adviser: listener to the bus max use (None if not used)
:return: new Bus with the parameters above
"""
b = Bus(self.bus_lines[bus_line.id], minute, size)
if size_adviser:
b.add_size_adviser(size_adviser)
self.cur_buses[bus_line].append(b)
self.changed_cur = True
return b
def get_current_buses(self) -> List[Bus]:
"""
:return: list of the buses that currently drive
"""
if not self.changed_cur:
return self.cached_cur
lis = []
for val in self.cur_buses.values():
for bus in val:
lis.append(bus)
self.cached_cur = lis
self.changed_cur = False
return lis
def remove_bus(self, bus_line: BusLine, bus: Bus) -> None:
"""
remove bus that arrive to least station
:param bus_line: the bus line of the bus
:param bus: the bus that arrived to least station
"""
self.cur_buses[bus_line].remove(bus)
self.changed_cur = True
def add_bus_lines(self, bus_lines: List[BusLine]) -> None:
"""
add list of bus_lines to the system
:param bus_lines: list of bus lines to add
"""
for bs in bus_lines:
self.bus_lines[bs.id] = bs
def add_passengers(self, passengers: List[Passenger]) -> None:
"""
add list of passengers to the system
:param passengers: list of passengers
"""
for ps in passengers:
self.wait_times[ps.arrival_time].append(ps)
self.bus_lines[ps.wanted_bus].wait_times[ps.arrival_time].append(ps)
def sizes(self) -> List[int]:
"""
:return: list of possible sizes of busses
"""
return list(self.sizes_to_cost.keys())
def lines(self) -> List[int]:
"""
:return: list of the bus lines ids in the system
"""
return list(self.bus_lines.keys())
def deepcopy(self) -> 'System':
"""
:return: deep copy of the system
"""
copy_system = deepcopy(self)
return copy_system
def passengers(self) -> List[Passenger]:
"""
:return: list of passengers in the system
"""
ps = []
for passengers in self.wait_times.values():
ps += passengers
return ps
def get_system_of_line(self, line_id: int) -> 'System':
"""
return new system that relevant only to the specific line
:param line_id: the line id
:return: the system for this line
"""
new_sys = System()
bus_line = self.bus_lines[line_id]
new_bus_line = BusLine(bus_line.station_ids, new_sys, line_id)
new_sys.add_bus_lines([new_bus_line])
new_sys.add_distance_map(self.distance_map())
passengers = self.passengers()
new_sys.add_passengers([ps for ps in passengers if ps.wanted_bus == line_id])
return new_sys
def add_distance_map(self, times_between: Dict[Tuple[int, int], int]) -> None:
"""
set the distance between stations
:param times_between: distance map
"""
self.times_between = times_between
def distance_map(self) -> Dict[Tuple[int, int], int]:
"""
:return: the distance map
"""
return self.times_between