def add_trips(self, trip=None): if trip == None: self.trips.append(Trip(shopper_id=self.shopper_id)) else: self.trips.append(trip)
def __init__(self): self.neighbourClass = trip.Trip()
def trip_assessment(self, top_ten, customers, graph, stores, trip_size=3): """ :top_ten: top ten target customers for generating the trips :customers: list of all customers with their data attributes :graph: underlying network structure :stores: list of all stores :trip_size: 1,2 or 3 return: list of customers with updated data """ curr_store = self.get_current_location() stores = np.array(stores) # ** Check whether current location is a Store, if not, send the shopper to a nearby store. if np.sum(np.isin(stores, curr_store)) > 0: self.go_to_store(stores, graph, distance='randomize') visited_customers = Customer.find_visited_customers(customers) if visited_customers.size == len(customers): print("All Customers have been visited") return customers if visited_customers.size > len(customers) - trip_size: trip_size = len(customers) - visited_customers.size all_trp = list(combinations(top_ten, trip_size)) all_trp2 = [list(c) for c in all_trp] all_trp2_2 = [list(set(permutations(c))) for c in all_trp2] all_trp2_2_1 = [y for x in all_trp2_2 for y in x] all_trp22 = [list(t) for t in all_trp2_2_1] all_trp3 = [np.array([curr_store] + c) for c in all_trp22] if trip_size == 3: all_trp4 = list( map( lambda x: np.array([[x[0], x[1]], [x[1], x[2]], [x[2], x[3]]]), all_trp3)) elif trip_size == 2: all_trp4 = list( map(lambda x: np.array([[x[0], x[1]], [x[1], x[2]]]), all_trp3)) elif trip_size == 1: all_trp4 = list(map(lambda x: np.array([[x[0], x[1]]]), all_trp3)) else: print("Trip size must be either 1,2 or 3!") return del (all_trp, all_trp2, all_trp22, all_trp3) # clear up memory travel_time = [graph.find_trip_time(c) for c in all_trp4] customer_table = defaultdict(int) for c in customers: customer_table[c.get_id()] = c cust_list = [list(c[:, 0]) for c in travel_time] items = [[customer_table[c].get_item_count() for c in t] for t in cust_list] node_due_time = [[customer_table[c].get_due_time() for c in t] for t in cust_list] store_time = [sum(c) + 5 for c in items] trv_time = [list(c[:, 1]) for c in travel_time ] # travel time to each individual node from the store assert (len(store_time) == len(trv_time)) node_arr_time = [accumulate(s) for s in trv_time] node_arrival_time = [] for i in range(len(store_time)): node_arrival_time.append([ store_time[i] + self.current_time + s for s in node_arr_time[i] ]) arrv_vec = np.array(node_arrival_time) due_vec = np.array(node_due_time) violations = [ list(s) for s in list(abs(np.subtract(arrv_vec, due_vec))) ] #violations of each node in a trip total_viol = [sum(s) for s in violations] # total violations of each trip min_idx = np.argmin( np.array(total_viol)) # index of the minimum violations trip = cust_list[min_idx] trip_nodes = [self.get_current_location()] + trip # store + customers trip_arr_times = [self.get_current_time()] + node_arrival_time[ min_idx] # current time & arrv times of customers trip_violations = [0] + violations[min_idx] curr_trip = Trip(self.get_shopper_id(), trip_nodes, trip_arr_times, trip_violations) self.add_trips(curr_trip) # ** Update the visit customers data: for i in range(len(trip)): customer_table[trip[i]].set_visit_time( node_arrival_time[min_idx][i]) customer_table[trip[i]].set_shopper(self.get_shopper_id()) self.set_current_time( node_arrival_time[min_idx][-1]) # Set the current time for shopper self.set_current_location(trip[-1]) return customers
def exchange_route(self, other, customers, graph, stores): """ """ if not isinstance(other, Shopper): print("Argument must be a Shopper Object!") return customer_table = defaultdict(int) for c in customers: customer_table[c.get_id()] = c # ** Get the list of trips for both shoppers: self_trips = self.get_trips() other_trips = other.get_trips() # ** Get the last trip generated for both shoppers: self_trip = self_trips[-1] other_trip = other_trips[-1] self_t = self_trip.get_customers() other_t = other_trip.get_customers() # *** Get the total violations of each trip before swap: curr_total_viol = self_trip.get_total_violations( ) + other_trip.get_total_violations() switch_nodes_idx = self_trip.nodes_to_switch( other_trip) # indices of the nodes that can be switched! if len(switch_nodes_idx) == 0: return elif len(switch_nodes_idx) == 1: n = switch_nodes_idx[ 0] # pick the first node (for both trips) to be exchanged elif len(switch_nodes_idx) > 1: n = switch_nodes_idx[1] # *** new trips with exchanged routes: new_self_t = self_t[0:n] + other_t[n:len(other_t)] new_other_t = other_t[0:n] + self_t[n:len(self_t)] new_self_trip = copy.deepcopy(new_self_t) new_other_trip = copy.deepcopy(new_other_t) new_trip_list = [] new_trip_list.extend((new_self_trip, new_other_trip)) # ** Start-Time at stores: self_start = self_trip.get_visit_time()[0] other_start = other_trip.get_visit_time()[0] start_time_list = [] start_time_list.extend((self_start, other_start)) new_total_viol,new_trip_nodes,new_trip_arrv_times,new_total_viol = \ Shopper.evaluate_trips(new_trip_list,start_time_list,customers,graph,stores) # *** If violations didn't improve stop if sum(new_total_viol) >= curr_total_viol: return customers print(" $$$$$----- USEFUL SWAP -----$$$$$") # *** If violations improved Update customers and shoppers data: self_trip_new = Trip(self.get_shopper_id(), new_trip_nodes[0], new_trip_arrv_times[0], list(new_total_viol[0])) other_trip_new = Trip(other.get_shopper_id(), new_trip_nodes[1], new_trip_arrv_times[1], list(new_total_viol[1])) # ** Drop the last trips of both shoppers to be able to swap some customers self.drop_last_trip() other.drop_last_trip() # *** Add new trips: self.add_trips(self_trip_new) other.add_trips(other_trip_new) # #** Update the visit customers data: # ** self shopper: for i in range(len(new_self_trip)): customer_table[new_self_trip[i]].set_visit_time( new_trip_arrv_times[0][i]) customer_table[new_self_trip[i]].set_shopper(self.get_shopper_id()) # ** other shopper: for i in range(len(new_other_trip)): customer_table[new_other_trip[i]].set_visit_time( new_trip_arrv_times[1][i]) customer_table[new_other_trip[i]].set_shopper( other.get_shopper_id()) # self.set_current_time( new_trip_arrv_times[0][-1]) # Set the current time for shopper self.set_current_location(new_self_trip[-1]) other.set_current_time( new_trip_arrv_times[1][-1]) # Set the current time for shopper other.set_current_location(new_other_trip[-1]) return customers
def generateFeatures(driversDataPath, driverLimit=10000): import os import glob driverIndex = 0 tripIndex = 0 ''' read drivers directory ''' for dId in sorted(os.listdir(driversDataPath)): print " driver: index %s name %s " % (driverIndex, dId) driver = Driver(driverIndex, dId) tripIndex = 0 ''' for each driver read the trip files, one file at a time and compute the features and stores them in the Trip object ''' folder = '%s/%s/*.csv' % (driversDataPath, dId) for f in sorted(glob.glob(folder)): #print " f: ", f fileName = os.path.basename(f) [name, ext] = os.path.splitext(fileName) tripMatrix = [] features = [] ''' data sample rate is 1 sec ''' tripMatrix = np.loadtxt(f, delimiter=',', skiprows=1) ''' distances ''' distances = getDistances(tripMatrix) medianDist = np.median(distances) meanDist = np.mean(distances) stdDist = np.std(distances) maxDist = distances.max() tripTime = len(tripMatrix) tripDist = distances.sum() #np.sum(distances) ''' distance features ''' features.append(tripDist) features.append(tripTime) features.append(maxDist) features.append(stdDist) features.append(meanDist) features.append(medianDist) variances = getPCAVariance(tripMatrix) xVariance = variances[0] yVariance = variances[1] ''' xy variance features ''' features.append(xVariance) features.append(yVariance) ''' stops ''' stopCount = getStops(tripMatrix) dataJumpCount = getDataJumps(distances) ''' stops and jumps features ''' features.append(stopCount) features.append(dataJumpCount) '''speeds ''' speeds = distances medianSpeed = np.median(speeds) meanSpeed = np.mean(speeds) maxSpeed = speeds.max() mimSpeed = speeds.min() stdSpeed = np.std(speeds) '''speeds features ''' features.append(maxSpeed) features.append(mimSpeed) features.append(stdSpeed) features.append(meanSpeed) features.append(medianSpeed) ''' accelerations - derivative of speed''' accels = np.diff(speeds) [minAccel, maxAccel, totalAccel] = getMinMaxPos(accels) [minDecel, maxDecel, totalDecel] = getMinMaxNeg(accels) ''' accelerations features ''' features.append(maxAccel) features.append(minAccel) features.append(totalAccel) features.append(maxDecel) features.append(minDecel) features.append(totalDecel) ''' jerks - derivative of acceleration''' jerks = np.diff(accels) [minAccelJerk, maxAccelJerk, totalAccelJerck] = getMinMaxPos(jerks) [minDecelJerk, maxDecelJerk, totalDecelJerck] = getMinMaxNeg(jerks) ''' jerk features ''' features.append(maxAccelJerk) features.append(minAccelJerk) features.append(totalAccelJerck) features.append(maxDecelJerk) features.append(minDecelJerk) features.append(totalDecelJerck) ''' angles ''' angles, originAngles = getAngles(tripMatrix) maxAngle = angles.max() minAngle = angles.min() totalAngle = angles.sum() meanAngle = np.mean(angles) medianAngle = np.median(angles) ''' angles features ''' features.append(maxAngle) features.append(minAngle) features.append(meanAngle) features.append(medianAngle) features.append(totalAngle) ''' angularVelocity ''' angularSpeeds = angles * speeds maxAngularSpeed = angularSpeeds.max() minAngularSpeed = angularSpeeds.min() medianAngularSpeed = np.median(angularSpeeds) meanAngularSpeed = np.mean(angularSpeeds) features.append(maxAngularSpeed) features.append(minAngularSpeed) features.append(meanAngularSpeed) features.append(medianAngularSpeed) ''' instantiate Trip object ''' trip = Trip(tripIndex, name, tripTime, tripDist) ''' add the feature list to the current trip''' trip.setFeatureList(features) ''' add the trip to the driver ''' driver.addTrip(trip) del trip #the local trip should be dealocated every loop tripIndex += 1 ''' add driver to the manager. At this point the driver has all the trips with the corresponding features ''' driverMgr.addDriver(driver) del driver #the local driver should be dealocated every loop driverIndex += 1 ''' to get out of the drivers loop - for testing only ''' if driverIndex > driverLimit: break
def MITSpeedAlgorithm(read_from, start_time, kill_time, fileName): ##################################### # # # PART 1: # # CONDENSE DUPLICATES # # # ##################################### # We will be using a NxN Grid, where each region has a set of nodes # to make it easier to seek out nodes max_speed = 5 # meters per second n = 20 # Gets all of the nodes grid_of_nodes = get_correct_nodes(n, None, None) node_info = get_node_range() trip_file = csv.reader(open(read_from, 'rb')) t_agg = [] # Each keeps track of distinct trips, so we can filter out duplicates and # replace them with a great average trip dictionary_cab = dict() dictionary_time_agg = dict() dictionary_counter = dict() dictionary_distance = dict() header = True for row in trip_file: if not header: if row[5] > str(kill_time): print row[5] break if row[5] >= str(start_time): try: beginnode = find_nodes(float(row[10]), float(row[11]), grid_of_nodes, node_info, n) end_node = find_nodes(float(row[12]), float(row[13]), grid_of_nodes, node_info, n) except (ValueError): continue if beginnode is None or end_node is None: continue newEntry = (beginnode.node_id, end_node.node_id) dictionary_cab[newEntry] = row if newEntry in dictionary_time_agg: dictionary_time_agg[newEntry] += float( (create_datetime(row[6]) - create_datetime(row[5])).seconds) dictionary_distance[newEntry] += float(row[9]) dictionary_counter[newEntry] += 1 else: dictionary_time_agg[newEntry] = float( (create_datetime(row[6]) - create_datetime(row[5])).seconds) dictionary_distance[newEntry] = float(row[9]) dictionary_counter[newEntry] = 1 header = False # Replaces the single trip with a trip object and adds it to our set of # all trips for key in dictionary_time_agg: # The current trip row t = dictionary_cab[key] new_time = dictionary_time_agg[key] / dictionary_counter[key] new_dist = dictionary_distance[key] / dictionary_counter[key] # The new trip array that initializes a trip object new_tripList = [ t[0], new_time, new_dist, t[10], t[11], t[12], t[13], key[0], key[1], dictionary_counter[key] ] new_trip = Trip(new_tripList) t_agg.append(new_trip) print len(t_agg) ##################################### # # # PART 2: # # REMOVE SHORT/longitude # # # ##################################### # This removes any trip that starts and ends at the same node, as long as # extremely short or extremely long trips t_agg = remove_loop_trips(t_agg) t_agg = remove_extreme_trips(t_agg) ##################################### # # # PART 3: # # COMPUTE tripS # # # ##################################### for trip in t_agg: path = AStar(trip.start_long, trip.start_lat, trip.end_long, trip.end_lat, grid_of_nodes, node_info, n, max_speed) trip.nodeList = path ##################################### # # # PART 4: # # REMOVE FAST/SLOW # # # ##################################### t_agg = remove_speed_trips(t_agg) print len(t_agg) ############################################# ############################################# # # # PART 5: # # ITERATIVE PART # # # ############################################# ############################################# # MIRROR OF PSUEDO CODE: PART 5.1, SET AGAIN = TRUE again = True # This is a dictionary of sets - give it a streetID (start_node.node_id, # end_node.node_id) and it will return the set of trips that include that # street and O_s dict_of_streets = dict() time_outer_loop = 0 time_inner_loop = 0 iter_outer_loop = 0 iter_inner_loop = 0 ########################################## # # # PART 5.3: # # OUTTER LOOP # # # ########################################## while again: # Now the we are out of the Inner Loop, we must reset the times # associated with each trip print "Outer Loop!" start = timeit.default_timer() for _id in dict_of_streets: tripsWithStreet = dict_of_streets[_id][0] # All the streets have the street, so we can pick any one random_trip = next(iter(tripsWithStreet)) # node_tuple[0] = start_node, node_tuple[1] = end_node node_tuple = random_trip.node_dict[_id] new_time = node_tuple[0].distance_connections[node_tuple[1]] / ( node_tuple[0].speed_connections[node_tuple[1]]) node_tuple[0].time_connections[node_tuple[1]] = new_time print "End of resetting times" # We now have an entirely new set of streets used # so we must reset the old dictionary dict_of_streets = dict() again = False rel_error = 0 # We find new paths based off of the new times we got for trip in t_agg: path = AStar(trip.start_long, trip.start_lat, trip.end_long, trip.end_lat, grid_of_nodes, node_info, n, max_speed) trip.nodeList = path trip.node_dict = build_dictionary(path) for _id in trip.node_dict: if _id in dict_of_streets: dict_of_streets[_id][0].add(trip) else: dict_of_streets[_id] = (set(), 0) dict_of_streets[_id][0].add(trip) trip.est_time = find_time(path) rel_error += abs(trip.est_time - trip.trip_time) / trip.trip_time print "End of getting rel_error, finding paths, " + ( "filling dictionaryand getting streetIDs") # Offset Computation for _id in dict_of_streets: offSet = 0 for trip in dict_of_streets[_id][0]: offSet += (trip.est_time - trip.trip_time) * trip.numtrips dict_of_streets[_id] = (dict_of_streets[_id][0], offSet) print "End of calculating offset coefficients" k = 1.2 stop = timeit.default_timer() time_outer_loop += (stop - start) iter_outer_loop += 1 print stop - start ########################################## # # # PART 5.3: # # INNER LOOP # # # ########################################## print "Inner Loop!" # MIRROR OF PSUEDO CODE: PART 5.3, INNER LOOP # (KEEP TRACK OF FASTEST SPEED HERE) while True: start = timeit.default_timer() # Recalculates the time with a different ratio for _id in dict_of_streets: tripsWithStreet = dict_of_streets[_id][0] # It doesn't matter what trip we take from this set, as they # all include this street random_trip = next(iter(tripsWithStreet)) node_tuple = random_trip.node_dict[_id] if dict_of_streets[_id][1] < 0: node_tuple[0].time_connections[node_tuple[1]] = ( node_tuple[0].time_connections[node_tuple[1]] * k) else: node_tuple[0].time_connections[node_tuple[1]] = ( node_tuple[0].time_connections[node_tuple[1]] / k) # Figures out what the error would be under these new time # constraints new_rel_error = 0 for trip in t_agg: etPrime = find_time(trip.nodeList) new_rel_error += abs(etPrime - trip.trip_time) / (trip.trip_time) # Our new times are more accurate - time to redo everything if new_rel_error < rel_error: # We are going to have a new fastest speed max_speed = -1 rel_error = new_rel_error # Since our new times are better, we ReUpdate the speed based # off these new times for _id in dict_of_streets: tripsWithStreet = dict_of_streets[_id][0] # It doesn't matter what trip we take from this set # as they all include this street random_trip = next(iter(tripsWithStreet)) node_tuple = random_trip.node_dict[_id] new_speed = ( node_tuple[0].distance_connections[node_tuple[1]] / node_tuple[0].time_connections[node_tuple[1]]) if new_speed > max_speed: max_speed = new_speed node_tuple[0].speed_connections[node_tuple[1]] = new_speed again = True else: # Continue reducing k iter_inner_loop += 1 k = 1 + (k - 1) * .75 if k < 1.0001: stop = timeit.default_timer() time_inner_loop += (stop - start) print stop - start break # TODO: TEST TO MAKE SURE TIMES ARE UP-TO-DATE for column in grid_of_nodes: for region in column: for node in region.nodes: for connection in node.time_connections: node.time_connections[connection] = ( node.distance_connections[connection] / (node.speed_connections[connection])) ########################################## # # # PART 6: # # UNUSED STREETS # # # ########################################## print "Outer loop time:" print time_outer_loop print "Inner loop time:" print time_inner_loop print "Iterations outer:" print iter_outer_loop print "Iterations inner:" print iter_inner_loop # A set of pairs of nodes (start_node, end_node) all_streets = get_all_streets(grid_of_nodes) unused_streets = get_sorted_unused_streets(all_streets, dict_of_streets) prev_len = -1 # We now set every street in order, averaging the velocity along each # street and the times, then assigning it to the usedStreet set while True: if prev_len == len(unused_streets): print prev_len for street in unused_streets: curr_pair = street[1] curr_pair[0].speed_connections[curr_pair[1]] = -1 curr_pair[0].time_connections[curr_pair[1]] = -1 break prev_len = len(unused_streets) for street in unused_streets: if street[0] == 0: unused_streets = get_sorted_unused_streets( all_streets, dict_of_streets) break curr_pair = street[1] all_adjacent = find_adjacent(curr_pair, dict_of_streets) all_velocities = 0 for node_tuple in all_adjacent: all_velocities += node_tuple[0].speed_connections[ node_tuple[1]] if len(all_adjacent) != 0: all_velocities /= len(all_adjacent) else: all_velocities = -1 curr_pair[0].speed_connections[curr_pair[1]] = all_velocities if all_velocities != 0: curr_pair[0].time_connections[curr_pair[1]] = ( curr_pair[0].distance_connections[curr_pair[1]] / (all_velocities)) else: curr_pair[0].time_connections[curr_pair[1]] = -1 dict_of_streets[(curr_pair[0].node_id, curr_pair[1].node_id)] = (curr_pair[0], curr_pair[1]) ########################################## # # # PART 7: # # WRITE LINK FILE # # # ########################################## # Writes all of the pertinent information to a file, so that we can compare # it to the link file later and add the time/speed link_file = csv.writer(open(fileName, 'wb')) headers = ["begin_node_id", "end_node_id", "length", "speed", "time"] link_file.writerow(headers) for node_tuple in all_streets: new_arr = [ node_tuple[0].node_id, node_tuple[1].node_id, node_tuple[0].distance_connections[node_tuple[1]], node_tuple[0].speed_connections[node_tuple[1]], node_tuple[0].time_connections[node_tuple[1]] ] link_file.writerow(new_arr)
def set_trip_data(self, trip_data): self.trip_data = trip_data self.trip_object_list = [ tripSrc.Trip(id, data) for id, data in zip(self.trip_ids, self.trip_data) ]
def get_all_trips(self): return Trip.Trip().get_all_trips()
def search_trip(self, search): return Trip.Trip().search_trip(search)