-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrideshare.py
109 lines (96 loc) · 4.88 KB
/
rideshare.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
import sys
import ast
import itertools
import argparse
import json
from operator import itemgetter
from operator import attrgetter
from sklearn.cluster import DBSCAN
from sklearn import preprocessing
from utils import Utils
from car import Car
from passenger import Passenger
from destination import Destination
from cluster import Cluster
class CityState:
PERFORMANCE_CAP = 2000
def __init__(self, x, y):
self.max_rows = x
self.max_columns = y
self.car = Car(0,0)
self.enqueued_requests = []
def get_locations_to_go(self):
dropoffs = [passenger.dropoff for passenger in self.car.passengers]
pickups = [person.pickup for person in self.car.pickup_requests]
destinations = dropoffs + pickups
return destinations
def build_clusters(self, locations_to_go):
avg_map_size = (self.max_rows + self.max_columns)/2
ten_percent_of_map_size = round(.10 * avg_map_size)
epsilon = int(ten_percent_of_map_size if ten_percent_of_map_size > 0 else 1)
clustering = DBSCAN(eps=epsilon, min_samples=2).fit(locations_to_go)
locations_with_cluster_labels = []
for index, location in enumerate(locations_to_go):
if index in clustering.core_sample_indices_:
labeled_location = (location, clustering.labels_[index])
else:
labeled_location = (location, None)
locations_with_cluster_labels.append(labeled_location)
groups = itertools.groupby(locations_with_cluster_labels, itemgetter(1))
clusters = [Cluster(key, self.build_destinations(list(value))) for key, value in groups]
normalized_cluster_sizes = preprocessing.scale([cluster.size for cluster in clusters])
normalized_cluster_distances = preprocessing.scale([cluster.destination_closest_to_car.distance_from_car for cluster in clusters])
for index, cluster in enumerate(clusters):
cluster.set_weight(normalized_cluster_sizes[index], normalized_cluster_distances[index])
return clusters
def build_destinations(self, clustered_locations):
destinations = [Destination(clustered_location[0], Utils.get_taxicab_distance(clustered_location[0], self.car.get_location()), clustered_location[1]) for clustered_location in clustered_locations]
return destinations
def get_next_destination(self):
locations_to_go = self.get_locations_to_go()
if locations_to_go:
clusters = self.build_clusters(locations_to_go)
selected_cluster = max(clusters, key=attrgetter('weight'))
return selected_cluster.destination_closest_to_car
return Destination(self.car.get_location(), 0, None)
def get_requests_to_process(self, request_list):
if not self.enqueued_requests:
return request_list
else:
if len(self.enqueued_requests) > PERFORMANCE_CAP:
self.enqueued_requests = self.enqueued_requests[PERFORMANCE_CAP + 1:] + request_list
return self.enqueued_requests[0:PERFORMANCE_CAP + 1]
pending_requests = self.enqueued_requests + request_list
if len(pending_requests) < PERFORMANCE_CAP:
number_of_new_requests_to_execute = PERFORMANCE_CAP - len(self.enqueued_requests)
self.enqueued_requests = request_list[number_of_new_requests_to_execute + 1:]
return self.enqueued_requests + request_list[0:number_of_new_requests_to_execute + 1]
else:
return self.enqued_requests + request_list
def increment_time(self, request_json):
requests_to_process = self.get_requests_to_process(request_json)
new_pickups = [Passenger(person) for person in requests_to_process]
self.car.pickup_requests.extend(new_pickups)
next_destination = self.get_next_destination()
self.car.move(next_destination.location)
self.car.do_pickups()
self.car.do_dropoffs()
self.car.print_status()
if __name__ == '__main__':
parser = argparse.ArgumentParser(description = "Instantiate a city with an x and y argument")
parser.add_argument("city_x", type=int, help="rows in the city")
parser.add_argument("city_y", type=int, help="columns in the city")
args = parser.parse_args()
city = CityState(args.city_x, args.city_y)
print("City instantiated.")
request = input("Please input your request json, in quotes. EG \"[{'name':'joe','start':(1,2), 'end':(3,4)}]\": ")
jsonified_request = json.loads(request)
city.increment_time(ast.literal_eval(jsonified_request))
end = False
while not end:
request = input("Please input any more requests, or an empty list. Type 'end' to terminate. ")
if request == 'end':
end = True
else:
jsonified_request = json.loads(request)
city.increment_time(ast.literal_eval(jsonified_request))