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 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)
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)
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!'
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")