-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdriver_script_dynamic.py
346 lines (228 loc) · 11.5 KB
/
driver_script_dynamic.py
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
from datetime import datetime
from graph import parse_nyc_data as nyc
import networkx as nx
import random
import string
all_vehicles = {}
all_passengers = {}
all_ids = []
def generate_random_id():
global all_ids
while True:
random = ''.join([random.choice(string.digits) for n in range(5)])
if random not in all_ids:
all_ids.append(random)
return int(random)
def query_specific_route(vehicle_id):
global all_vehicles
global all_passengers
vehicle_object = all_vehicles[vehicle_id]
starting_point_id = vehicle_object.route[vehicle_object.route_flag]
def update_positions_of_active_vehicles(minutes, global_timer):
global all_vehicles
global all_passengers
vehicle_items = all_vehicles.items()
passenger_items = all_passengers.items()
id_to_index_passenger_mapping = [passenger[0] for passenger in passenger_items if passenger.is_active == 1]
vehicles_requiring_position_updates = [vehicle[1] for vehicle in vehicle_items if vehicle[1].is_active == 1]
source_time_data, destination_time_data, source_destination_time_data = get_time_matrices()
source_distance_data, destination_distance_data, source_destination_distance_data = get_distance_matrices()
for vehicle_object in vehicles_requiring_position_updates:
previous_route_flag = vehicle_object.route_flag
current_position_id = int(vehicle_object.route[route_flag])
update_iteration_timer = 0
marker = previous_route_flag + 1
#First get to nearest pair of nodes in the route
while update_iteration_timer < minutes*60 and marker < len(vehicle_object.route):
time_for_this_stop = 0
if marker >= len(vehicle_object.route):
#End of route
else:
passenger_id_for_current_waypoint = vehicle_object.route[marker-1]
passenger_id_for_next_waypoint = vehicle_object.route[marker]
current_position_type = vehicle_object.waypoint_type[marker-1]
next_position_type = vehicle_object.waypoint_type[marker]
if current_position_type == 'S' and next_position_type == 'S':
time_for_this_stop = source_time_data[][]
global_timer = global_timer + datetime.timedelta(seconds=time_for_this_stop)
vehicle_object.distance_traveled += source_distance_data[][]
all_passengers[passenger_id_for_current_waypoint].distance_traveled += source_distance_data[][]
all_passengers[passenger_id_for_next_waypoint].pickup_time = global_timer
all_passengers[passenger_id_for_next_waypoint].is_active = 1
all_passengers[passenger_id_for_next_waypoint].car_status = 1
elif current_position_type == 'S' and next_position_type == 'D':
time_for_this_stop = source_destination_time_data[][]
global_timer = global_timer + datetime.timedelta(seconds=time_for_this_stop)
vehicle_object.distance_traveled += source_destination_distance_data[][]
all_passengers[passenger_id_for_current_waypoint].distance_traveled += source_destination_distance_data[][]
all_passengers[passenger_id_for_next_waypoint].dropoff_time = global_timer
all_passengers[passenger_id_for_next_waypoint].is_active = 0
elif current_position_type == 'D' and next_position_type == 'S':
time_for_this_stop = source_destination_time_data[][]
global_timer = global_timer + datetime.timedelta(seconds=time_for_this_stop)
vehicle_object.distance_traveled += source_destination_distance_data[][]
all_passengers[passenger_id_for_current_waypoint].distance_traveled += source_destination_distance_data[][]
all_passengers[passenger_id_for_next_waypoint].pickup_time = global_timer
all_passengers[passenger_id_for_next_waypoint].is_active = 1
all_passengers[passenger_id_for_next_waypoint].car_status = 1
else:
time_for_this_stop = destination_time_data[][]
global_timer = global_timer = datetime.timedelta(seconds=time_for_this_stop)
vehicle_object.distance_traveled += destination_distance_data[][]
all_passengers[passenger_id_for_current_waypoint].distance_traveled += destination_distance_data[][]
all_passengers[passenger_id_for_next_waypoint].dropoff_time = global_timer
all_passengers[passenger_id_for_next_waypoint].is_active = 0
marker += 1
update_iteration_timer += time_for_this_stop
global_timer = global_timer - datetime.timedelta(seconds=time_for_this_stop)
update_iteration_timer -= time_for_this_stop
vehicle_object.route_flag = marker-2
distances, times, locations = query_specific_route(vehicle_object.vehicle_id)
time_left = minutes*60 - update_iteration_timer
specific_location_timer = 0
iterator = 0
while specific_location_timer <= time_left:
specific_location_timer += times[iterator]
iterator += 1
vehicle_object.current_position = locations[iterator-1]
for passenger_object in vehicle_object.passengers:
if passenger_object.is_active == 1 and passenger_object.car_status == 1:
passenger_object.current_position = vehicle_object.current_position
def set_routes_for_vehicles(text_output):
global all_vehicles
global all_passengers
vehicle_items = all_vehicles.items()
vehicles_requiring_route_updates = [vehicle[1] for vehicle in vehicle_items if vehicle[1].is_active == 1 and vehicle[1].update_required == 1]
for vehicle_object in vehicles_requiring_route_updates:
file_contents = []
file_contents.append(str(len(vehicle_object.passengers))+'\n')
file_contents.append(str(vehicle_object.capacity)+'\n')
occupants_string = ""
for user in vehicle.passengers:
occupants_string = occupants_string + str(user.passenger_id) +','
occupants_string = occupants_string[:len(occupants_string)-1]
file_contents.append(occupants_string+'\n')
file_contents.append(",".join(vehicle_object.current_position))
#First put sources of passengers
for user in vehicle_object.passengers:
if user.car_status == 1:
file_contents.append(",".join(vehicle_object.current_position))
else:
file_contents.append(",".join(user.source_location))
#Then put destination of passengers
for user in vehicle_object.passengers:
file_contents.append(",".join(user.destination_location))
file = open(text_output,"w+")
file.writelines(file_contents)
file.close()
query_string = 'java -jar vehicle_routing.jar ' + text_output
route = os.popen(query_string).read()
vehicle_object.route = route.split(" ")
def add_new_vehicles(vehicle_allocation, graph):
global all_vehicles
global all_passengers
information = nx.get_node_attributes(graph, 'information')
for car in vehicle_allocation:
#First see if there are any idle vehicles available of same capcity
vehicle_items = all_vehicles.items()
inactive_vehicles_of_same_capacity = [vehicle[1] for vehicle in vehicle_items if vehicle[1].is_active == 0 and vehicle[1].capacity == car.capacity]
#If available, add passengers to that vehicle and make it active
if len(inactive_vehicles_of_same_capacity) > 0:
vehicle_object = inactive_vehicles_of_same_capacity[0]
vehicle_object.is_active = 1
vehicle_object.update_required = 1
#Else create a new vehicle object required to do the computation and add to all vehicles
else:
vehicle_object = Cab(generate_random_id(), car.capacity, car.cost, [], [], 0, [], 1, 1, 0, [])
all_vehicles[vehicle_object.unique_id] = vehicle_object
#Create the passenger list from the obtained index from the allocation
passengers_list = []
for passenger in car.passengers:
passenger_id = information[passenger][1]
passenger_object = all_passengers[passenger_id]
passenger_object.alloted_vehicle = vehicle_object.unique_id
passenger_object.is_active = 1
passengers_list.append(passenger_object)
#Add passengers to the vehicle
vehicle_object.passengers = passengers_list
def allot_vehicles_to_color_classes(color_classes, graph):
global all_vehicles
global all_passengers
for color_class in color_classes:
#Get information about the graph nodes
information = nx.get_node_attributes(graph, 'information')
#Initiate all the vehicles and passengers in the given color class.
class_vehicles = []
class_passengers = []
#Find all passengers and vehicles and fill the lists.
for node in color_class:
if information[node][0] == 1:
class_vehicles.append(node)
else:
class_passengers.append(node)
class_passengers_iterator = 0
class_vehicles_iterator = 0
#First fill all vehicles, so iterate over all vehicles
while class_vehicles_iterator != len(class_vehicles):
#Find the vehicle object for current iteration
vehicle_index = class_vehicles[class_vehicles_iterator]
vehicle_id = information[vehicle_index][1]
vehicle_object = all_vehicles[vehicle_id]
#If the vehicle has space then till the time it can be filled, add passengers.
if len(vehicle_object.passengers) < vehicle_object.capacity:
while len(vehicle_object.passengers) != vehicle_object.capacity:
#If passengers are available to fill, fill them.
if class_passengers_iterator < len(class_passengers):
#Find the passenger object for current index
passenger_index = class_passengers[class_passengers_iterator]
passenger_id = information[passenger_index][1]
passenger_object = all_passengers[passenger_id]
#Add passenger object as passenger to the vehicle and increment to next passenger.
vehicle_object.passengers.append(passenger_object)
passenger_object.alloted_vehicle = vehicle_id
passenger_object.is_active = 1
class_passengers_iterator += 1
#Update flag of route update required to indicate vehicle route needs to be updated.
vehicle_object.update_required = 1
class_vehicles_iterator += 1
if class_passengers_iterator < len(class_passengers):
remaining_passengers = class_passengers[class_passengers_iterator:]
cost, vehicle_allocation = iva.allot_vehicles(remaining_passengers, vehicle_list)
add_new_vehicles(vehicle_allocation)
def get_first_requests(filepath, start_time, end_time, first_number):
data = nyc.read_dataset(filepath, start_time, end_time)
requests = nyc.create_request_objects(data, first_number)
return requests
def runner(filepath, start_time, end_time, initial_number, iteration_number, goal_number, delta, minutes):
global all_vehicles
global all_passengers
#Get first requests
requests = get_first_requests(filepath, start_time, end_time, initial_number)
vehicles = []
#Create admissibility matrix from the data
source_distance_data, destination_distance_data, source_destination_distance_data = get_distance_matrices(requests, vehicles)
admissibility_matrix = create_admissibility_matrix(source_distance_data, destination_distance_data, source_destination_distance_data, delta, requests, vehicles)
#Create properties for nodes (Weights, type and ID)
node_type_properties = create_node_properties(requests, vehicles)
weights = create_weights(requests, vehicles, source_distance_data, destination_distance_data, source_destination_distance_data)
#Create graph and color it
graph = create_graph_from_admissibility_matrix(admissibility_matrix, node_properties, weights)
color_classes = weighted_vertex_coloring(graph)
#Allot vehicles to color classes
allot_vehicles_to_color_classes(color_classes, graph)
#Allot routes to vehicles
set_routes_for_vehicles(text_output)
request_counter = len(requests)
global_timer = end_time
while request_counter >= goal_number:
#Update positions since last x minutes
update_positions_of_active_vehicles(minutes)
#Get new requests
requests = get_new_requests(global_timer, iteration_number)
#Create graph
#Call coloring routine
#Calculate routes
set_routes_for_vehicles(text_output)
request_counter += iteration_number
if __name__ == '__main__':
runner()