示例#1
0
 def add_trips(self, trip=None):
     if trip == None:
         self.trips.append(Trip(shopper_id=self.shopper_id))
     else:
         self.trips.append(trip)
示例#2
0
 def __init__(self):
     self.neighbourClass = trip.Trip()
示例#3
0
    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
示例#4
0
    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
示例#5
0
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
示例#6
0
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)
示例#7
0
文件: Driver.py 项目: ardgal/pymlaxa
 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)
     ]
示例#8
0
 def get_all_trips(self):
     return Trip.Trip().get_all_trips()
示例#9
0
 def search_trip(self, search):
     return Trip.Trip().search_trip(search)