Пример #1
0
    def reduce_to_time_resolution(list_of_user_info, time_resolution):
        grouped_by_dates_orddict = support.group_by(list_of_user_info, lambda x: x.date)
        result = []

        for _, grouped_by_date in grouped_by_dates_orddict.items():
            time_grid_day = support.to_grid(grouped_by_date, time_resolution, lambda x: support.time_total_seconds(x.time), 0, common_config.SECONDS_IN_A_DAY)
            support.remove_none_from_list(time_grid_day)
            result = result + time_grid_day

        return result
Пример #2
0
    def reduce_to_time_resolution(list_of_user_info, time_resolution):
        grouped_by_dates_orddict = support.group_by(list_of_user_info,
                                                    lambda x: x.date)
        result = []

        for _, grouped_by_date in grouped_by_dates_orddict.items():
            time_grid_day = support.to_grid(
                grouped_by_date, time_resolution,
                lambda x: support.time_total_seconds(x.time), 0,
                common_config.SECONDS_IN_A_DAY)
            support.remove_none_from_list(time_grid_day)
            result = result + time_grid_day

        return result
def prepare_pykov_chain_with_single_user_mobility_states(
    grouped_by_date_grid_by_minute_of_day_mp_fetched, current_day_str, predicted_day_str
):
    list_of_day_str_applicable = support.difference_of_days(current_day_str, predicted_day_str)

    from_to_user_entry_dict = {}
    for date, grid_by_minute_of_day_mp_fetched in grouped_by_date_grid_by_minute_of_day_mp_fetched.items():
        if support.calc_day(date) in list_of_day_str_applicable:

            # It seems this day is a contender in the prediction.
            # For each minute of the day look at the cell id(source) and look at the next because that is the destination
            # Each pair of source and destination should be added to the from_to user_entry_dict (date doesn't matter anymore as link is formed)
            # Using the source as the key and adding the destination to the list

            i = 0
            for source_mp_fetched in grid_by_minute_of_day_mp_fetched:
                if i == common_config.MINUTES_IN_A_DAY - 1:
                    # We have reached the end of the day, must look at the next if possible in the next day

                    next_date = date + support.Range.RESOLUTION_DATETIME_DAY
                    if support.calc_day(next_date) in list_of_day_str_applicable:
                        # It seems the adjoining day is also a contender in the prediction. Configure the destination correctly
                        destination_mp_fetched = grouped_by_date_grid_by_minute_of_day_mp_fetched[next_date][0]
                    else:
                        # There is no connection to the next day
                        destination_mp_fetched = None
                else:
                    # In the middle of the day, destination is next in the grid
                    destination_mp_fetched = grid_by_minute_of_day_mp_fetched[i + 1]

                if destination_mp_fetched:
                    source_user_entry = UserEntry(
                        source_mp_fetched.day, source_mp_fetched.minute_of_day, source_mp_fetched.cell_id
                    )
                    destination_user_entry = UserEntry(
                        destination_mp_fetched.day, destination_mp_fetched.minute_of_day, destination_mp_fetched.cell_id
                    )

                    # Add it to the from to user entry dict but with the source_user_entry as key
                    # Add it as a key if it doesn't exist yet
                    if source_user_entry in from_to_user_entry_dict:
                        from_to_user_entry_dict[source_user_entry].append(destination_user_entry)
                    else:
                        from_to_user_entry_dict[source_user_entry] = [destination_user_entry]

                i += 1

    # Calculate all percentages the same from and to user entry coincide
    pykov_chain_entries = {}
    for starting_user_entry, destinations in from_to_user_entry_dict.items():
        starting_key = starting_user_entry.to_pykov_key()
        total_amount = float(len(destinations))
        grouped_by_cell_id = support.group_by(destinations, lambda user_entry: user_entry.cell_id)

        for destination_cell_id, destinations_with_same_cell_id in grouped_by_cell_id.items():
            destination_key = destinations_with_same_cell_id[0].to_pykov_key()
            amount_of_destinations_with_same_cell_id = len(destinations_with_same_cell_id)
            percentage = float(amount_of_destinations_with_same_cell_id) / total_amount

            pykov_chain_entries[starting_key, destination_key] = percentage

    return pykov.Chain(pykov_chain_entries)
Пример #4
0
def prepare_pykov_chain_with_single_user_mobility_states(
        grouped_by_date_grid_by_minute_of_day_mp_fetched, current_day_str,
        predicted_day_str):
    list_of_day_str_applicable = support.difference_of_days(
        current_day_str, predicted_day_str)

    from_to_user_entry_dict = {}
    for date, grid_by_minute_of_day_mp_fetched in grouped_by_date_grid_by_minute_of_day_mp_fetched.items(
    ):
        if support.calc_day(date) in list_of_day_str_applicable:

            #It seems this day is a contender in the prediction.
            #For each minute of the day look at the cell id(source) and look at the next because that is the destination
            #Each pair of source and destination should be added to the from_to user_entry_dict (date doesn't matter anymore as link is formed)
            #Using the source as the key and adding the destination to the list

            i = 0
            for source_mp_fetched in grid_by_minute_of_day_mp_fetched:
                if i == common_config.MINUTES_IN_A_DAY - 1:
                    #We have reached the end of the day, must look at the next if possible in the next day

                    next_date = date + support.Range.RESOLUTION_DATETIME_DAY
                    if support.calc_day(
                            next_date) in list_of_day_str_applicable:
                        #It seems the adjoining day is also a contender in the prediction. Configure the destination correctly
                        destination_mp_fetched = grouped_by_date_grid_by_minute_of_day_mp_fetched[
                            next_date][0]
                    else:
                        #There is no connection to the next day
                        destination_mp_fetched = None
                else:
                    #In the middle of the day, destination is next in the grid
                    destination_mp_fetched = grid_by_minute_of_day_mp_fetched[
                        i + 1]

                if destination_mp_fetched:
                    source_user_entry = UserEntry(
                        source_mp_fetched.day, source_mp_fetched.minute_of_day,
                        source_mp_fetched.cell_id)
                    destination_user_entry = UserEntry(
                        destination_mp_fetched.day,
                        destination_mp_fetched.minute_of_day,
                        destination_mp_fetched.cell_id)

                    #Add it to the from to user entry dict but with the source_user_entry as key
                    #Add it as a key if it doesn't exist yet
                    if source_user_entry in from_to_user_entry_dict:
                        from_to_user_entry_dict[source_user_entry].append(
                            destination_user_entry)
                    else:
                        from_to_user_entry_dict[source_user_entry] = [
                            destination_user_entry
                        ]

                i += 1

    #Calculate all percentages the same from and to user entry coincide
    pykov_chain_entries = {}
    for starting_user_entry, destinations in from_to_user_entry_dict.items():
        starting_key = starting_user_entry.to_pykov_key()
        total_amount = float(len(destinations))
        grouped_by_cell_id = support.group_by(
            destinations, lambda user_entry: user_entry.cell_id)

        for destination_cell_id, destinations_with_same_cell_id in grouped_by_cell_id.items(
        ):
            destination_key = destinations_with_same_cell_id[0].to_pykov_key()
            amount_of_destinations_with_same_cell_id = len(
                destinations_with_same_cell_id)
            percentage = float(
                amount_of_destinations_with_same_cell_id) / total_amount

            pykov_chain_entries[starting_key, destination_key] = percentage

    return pykov.Chain(pykov_chain_entries)
Пример #5
0
def handle_incoming_mp_single_user_request(frontend, connection, msg):
    err.log_error(err.INFO, "Using MP algorithm")
    predicted_date_time = datetime.datetime.combine(msg.current_date, msg.current_time) + datetime.timedelta(seconds=msg.future_time_delta)
    predicted_date = predicted_date_time.date()
    predicted_time = predicted_date_time.time()

    '''
    if user_id is 0000 (i.e. 0, because it is an integer), we need to use multi-user prediction, not single user prediction
    '''
    if msg.user_id != 0:
        mp_fetched = mp.retrieve_user_mobility_data_single_user(frontend.dbcc, msg.user_id, msg.current_date, predicted_date)
        grouped_by_date_mp_fetched = support.group_by(mp_fetched, lambda x: x.date)

        grouped_by_date_grid_by_minute_of_day_mp_fetched = {}
        for date, mp_fetched_list in grouped_by_date_mp_fetched.items():
            minute_of_day_grid = support.to_grid( mp_fetched_list
                                                , 1
                                                , lambda x: x.minute_of_day
                                                , 0
                                                , common_config.MINUTES_IN_A_DAY - 1
                                                )
            grouped_by_date_grid_by_minute_of_day_mp_fetched[date] = minute_of_day_grid

        missing_ranges = mp.check_user_mobility_data_single_user_integrity( grouped_by_date_grid_by_minute_of_day_mp_fetched
                                                                          , msg.current_date
                                                                          )

        if len(missing_ranges) > 0:
            #Missing user information data, queue request and ask data from supplier
            missing_resource = mr.MissingUserInfo(missing_ranges)
            frontend.queue_as_pending_request(connection, msg, [missing_resource])

            err.log_error(err.INFO, "Did not have enough user info data. Asking supplier for: " + str(missing_ranges))

            error_message = mo.Error(102, "MP Request will take longer than expected because user data is missing at MOBaaS")
            connection.add_message(error_message)

            for missing_range in missing_ranges:
                start_time = missing_range.min_range.time()
                start_date = missing_range.min_range.date()
                time_span = int((missing_range.max_range - missing_range.min_range).total_seconds())

                supplier_message = mo.MaaSSingleUserDataRequest(msg.user_id, start_time, start_date, time_span, 60)
                frontend.ask_at_supplier(supplier_message)
        else:
            #There is all the info we need, calculate the spots
            current_day_str = support.calc_day(msg.current_date)
            predicted_day_str = support.calc_day(predicted_date)

            pykov_chain = mp.prepare_pykov_chain_with_single_user_mobility_states(grouped_by_date_grid_by_minute_of_day_mp_fetched
                                                                                 , current_day_str
                                                                                 , predicted_day_str
                                                                                 )
            chance_distribution_dict = mp.mobility_prediction(pykov_chain, msg.current_cell_id, msg.current_date, msg.current_time, predicted_date, predicted_time)

            #Create mobaas_protocol.prediction objects from the answers
            mobaas_protocol_predictions = mp.from_pykov_distribution_dict_to_predictions(chance_distribution_dict)

            answer_message = mo.MPSingleUserAnswer(msg.user_id, predicted_time, predicted_date, mobaas_protocol_predictions)
            connection.add_message(answer_message)
            err.log_error(err.INFO, "Found an answer to the request! Answer:" + str(answer_message))
    else:
        print 'error: should not get here!'
Пример #6
0
def test_group_by():
    l1 = [1, 2, 3, 4, 5] * 2
    answer1 = collections.OrderedDict({1: [1] * 2, 2: [2] * 2, 3: [3] * 2, 4: [4] * 2, 5: [5] * 2})
    run_tests.compare_answer(support.group_by(l1, lambda x:x), answer1, "group_by 1")