def build_joint_tour_timetables(joint_tours, joint_tour_participants, persons_timetable, alts): # timetable with a window for each joint tour joint_tour_windows_df = tt.create_timetable_windows(joint_tours, alts) joint_tour_timetable = tt.TimeTable(joint_tour_windows_df, alts) for participant_num, nth_participants in \ joint_tour_participants.groupby('participant_num', sort=True): # nth_participant windows from persons_timetable participant_windows = persons_timetable.slice_windows_by_row_id( nth_participants.person_id) # assign them joint_tour_timetable joint_tour_timetable.assign_footprints(nth_participants.tour_id, participant_windows) return joint_tour_timetable
def timetable(person_windows, tdd_alts): logging.debug('@inject timetable') return tt.TimeTable(person_windows.to_frame(), tdd_alts, person_windows.name)
def vectorize_subtour_scheduling(parent_tours, subtours, persons_merged, alts, spec, model_settings, estimator, chunk_size=0, trace_label=None): """ Like vectorize_tour_scheduling but specifically for atwork subtours subtours have a few peculiarities necessitating separate treatment: Timetable has to be initialized to set all timeperiods outside parent tour footprint as unavailable. So atwork subtour timewindows are limited to the footprint of the parent work tour. And parent_tour_id' column of tours is used instead of parent_id as timetable row_id. Parameters ---------- parent_tours : DataFrame parent tours of the subtours (because we need to know the tdd of the parent tour to assign_subtour_mask of timetable indexed by parent_tour id subtours : DataFrame atwork subtours to schedule persons_merged : DataFrame DataFrame of persons containing attributes referenced by expressions in spec alts : DataFrame DataFrame of alternatives which represent time slots. Will be passed to interaction_simulate in batches for each nth tour. spec : DataFrame The spec which will be passed to interaction_simulate. (all subtours share same spec regardless of subtour type) model_settings : dict chunk_size trace_label Returns ------- choices : Series A Series of choices where the index is the index of the subtours DataFrame and the values are the index of the alts DataFrame. """ if not trace_label: trace_label = 'vectorize_non_mandatory_tour_scheduling' assert len(subtours.index) > 0 assert 'tour_num' in subtours.columns assert 'tour_type' in subtours.columns timetable_window_id_col = 'parent_tour_id' tour_owner_id_col = 'parent_tour_id' logsum_tour_purpose = None # FIXME logsums not currently supported # timetable with a window for each parent tour parent_tour_windows = tt.create_timetable_windows(parent_tours, alts) timetable = tt.TimeTable(parent_tour_windows, alts) # mask the periods outside parent tour footprint timetable.assign_subtour_mask(parent_tours.tour_id, parent_tours.tdd) # print timetable.windows """ [[7 7 7 0 0 0 0 0 0 0 0 7 7 7 7 7 7 7 7 7 7] [7 0 0 0 0 0 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7] [7 7 7 7 7 0 0 0 0 0 0 0 0 0 0 7 7 7 7 7 7] [7 7 0 0 0 0 0 0 0 7 7 7 7 7 7 7 7 7 7 7 7]] """ choice_list = [] # keep a series of the the most recent tours for each person # initialize with first trip from alts previous_tour_by_parent_tour_id = \ pd.Series(alts.index[0], index=subtours['parent_tour_id'].unique()) # tours must be scheduled in increasing trip_num order # second trip of type must be in group immediately following first # this ought to have been ensured when tours are created (tour_frequency.process_tours) for tour_num, nth_tours in subtours.groupby('tour_num', sort=True): tour_trace_label = tracing.extend_trace_label(trace_label, 'tour_%s' % (tour_num, )) # no more than one tour per timetable window per call to schedule_tours assert not nth_tours.parent_tour_id.duplicated().any() choices = \ schedule_tours(nth_tours, persons_merged, alts, spec, logsum_tour_purpose, model_settings, timetable, timetable_window_id_col, previous_tour_by_parent_tour_id, tour_owner_id_col, estimator, chunk_size, tour_trace_label) choice_list.append(choices) choices = pd.concat(choice_list) # print "\nfinal timetable.windows\n%s" % timetable.windows """ [[7 7 7 0 0 0 0 2 7 7 4 7 7 7 7 7 7 7 7 7 7] [7 0 2 7 4 0 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7] [7 7 7 7 7 2 4 0 0 0 0 0 0 0 0 7 7 7 7 7 7] [7 7 0 2 7 7 4 0 0 7 7 7 7 7 7 7 7 7 7 7 7]] """ # we dont need to call replace_table() for this nonce timetable # because subtours are occuring during persons timetable scheduled time return choices
def vectorize_subtour_scheduling(parent_tours, subtours, persons_merged, alts, spec, constants, chunk_size=0, trace_label=None): """ Like vectorize_tour_scheduling but specifically for atwork subtours subtours have a few peculiarities necessitating separate treatment: Timetable has to be initialized to set all timeperiods outside parent tour footprint as unavailable. So atwork subtour timewindows are limited to the foorprint of the parent work tour. And parent_tour_id' column of tours is used instead of parent_id as timetable row_id. Parameters ---------- parent_tours : DataFrame parent tours of the subtours (because we need to know the tdd of the parent tour to assign_subtour_mask of timetable indexed by parent_tour id subtours : DataFrame atwork subtours to schedule persons_merged : DataFrame DataFrame of persons containing attributes referenced by expressions in spec alts : DataFrame DataFrame of alternatives which represent time slots. Will be passed to interaction_simulate in batches for each nth tour. spec : DataFrame The spec which will be passed to interaction_simulate. (all subtours share same spec regardless of subtour type) constants : dict dict of model-specific constants for eval chunk_size trace_label Returns ------- choices : Series A Series of choices where the index is the index of the subtours DataFrame and the values are the index of the alts DataFrame. """ if not trace_label: trace_label = 'vectorize_non_mandatory_tour_scheduling' assert len(subtours.index) > 0 assert 'tour_num' in subtours.columns assert 'tour_type' in subtours.columns # timetable with a window for each parent tour parent_tour_windows = tt.create_timetable_windows(parent_tours, alts) timetable = tt.TimeTable(parent_tour_windows, alts) # mask the periods outside parent tour footprint timetable.assign_subtour_mask(parent_tours.tour_id, parent_tours.tdd) # print timetable.windows """ [[7 7 7 0 0 0 0 0 0 0 0 7 7 7 7 7 7 7 7 7 7] [7 0 0 0 0 0 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7] [7 7 7 7 7 0 0 0 0 0 0 0 0 0 0 7 7 7 7 7 7] [7 7 0 0 0 0 0 0 0 7 7 7 7 7 7 7 7 7 7 7 7]] """ choice_list = [] # keep a series of the the most recent tours for each person # initialize with first trip from alts previous_tour_by_parent_tour_id = \ pd.Series(alts.index[0], index=subtours['parent_tour_id'].unique()) # no more than one tour per person per call to schedule_tours # tours must be scheduled in increasing trip_num order # second trip of type must be in group immediately following first # segregate scheduling by tour_type if multiple specs passed in dict keyed by tour_type for tour_num, nth_tours in subtours.groupby('tour_num', sort=True): tour_trace_label = tracing.extend_trace_label(trace_label, 'tour_%s' % (tour_num,)) choices = \ schedule_tours(nth_tours, persons_merged, alts, spec, constants, timetable, previous_tour_by_parent_tour_id, 'parent_tour_id', chunk_size, tour_trace_label) choice_list.append(choices) choices = pd.concat(choice_list) # add the start, end, and duration from tdd_alts tdd = alts.loc[choices] tdd.index = choices.index # include the index of the choice in the tdd alts table tdd['tdd'] = choices # print "\nfinal timetable.windows\n", timetable.windows """ [[7 7 7 0 0 0 0 2 7 7 4 7 7 7 7 7 7 7 7 7 7] [7 0 2 7 4 0 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7] [7 7 7 7 7 2 4 0 0 0 0 0 0 0 0 7 7 7 7 7 7] [7 7 0 2 7 7 4 0 0 7 7 7 7 7 7 7 7 7 7 7 7]] """ return tdd
def timetable(person_windows, tdd_alts): return tt.TimeTable(person_windows.to_frame(), tdd_alts, person_windows.name)