def apply_from_variant(variant, petri_net, initial_marking, final_marking, parameters=None): """ Apply the alignments from the specification of a single variant Parameters ------------- variant Variant (as string delimited by the "variant_delimiter" parameter) petri_net Petri net initial_marking Initial marking final_marking Final marking parameters Parameters of the algorithm (same as 'apply' method, plus 'variant_delimiter' that is , by default) Returns ------------ dictionary: `dict` with keys **alignment**, **cost**, **visited_states**, **queued_states** and **traversed_arcs** """ if parameters is None: parameters = {} activity_key = DEFAULT_NAME_KEY if parameters is None or PARAMETER_CONSTANT_ACTIVITY_KEY not in parameters else \ parameters[ pm4pyutil.constants.PARAMETER_CONSTANT_ACTIVITY_KEY] trace = log_implementation.Trace() variant_delimiter = exec_utils.get_param_value(Parameters.PARAMETER_VARIANT_DELIMITER, parameters, pm4pyutil.constants.DEFAULT_VARIANT_SEP) variant_split = variant.split(variant_delimiter) if type(variant) is str else variant for i in range(len(variant_split)): trace.append(log_implementation.Event({activity_key: variant_split[i]})) return apply(trace, petri_net, initial_marking, final_marking, parameters=parameters)
def apply_playout(net, initial_marking, no_traces=100, max_trace_length=100, case_id_key=xes_constants.DEFAULT_TRACEID_KEY, activity_key=xes_constants.DEFAULT_NAME_KEY, timestamp_key=xes_constants.DEFAULT_TIMESTAMP_KEY, final_marking=None, smap=None, log=None, return_visited_elements=False): """ Do the playout of a Petrinet generating a log Parameters ---------- net Petri net to play-out initial_marking Initial marking of the Petri net no_traces Number of traces to generate max_trace_length Maximum number of events per trace (do break) case_id_key Trace attribute that is the case ID activity_key Event attribute that corresponds to the activity timestamp_key Event attribute that corresponds to the timestamp final_marking If provided, the final marking of the Petri net smap Stochastic map log Log """ if final_marking is None: # infer the final marking from the net final_marking = final_marking_discovery.discover_final_marking(net) if smap is None: if log is None: raise Exception( "please provide at least one between stochastic map and log") smap = replay.get_map_from_log_and_net(log, net, initial_marking, final_marking, parameters={ Parameters.ACTIVITY_KEY: activity_key, Parameters.TIMESTAMP_KEY: timestamp_key }) # assigns to each event an increased timestamp from 1970 curr_timestamp = 10000000 all_visited_elements = [] for i in range(no_traces): visited_elements = [] visible_transitions_visited = [] marking = copy(initial_marking) while len(visible_transitions_visited) < max_trace_length: visited_elements.append(marking) if not semantics.enabled_transitions( net, marking): # supports nets with possible deadlocks break all_enabled_trans = semantics.enabled_transitions(net, marking) if final_marking is not None and marking == final_marking: en_t_list = list(all_enabled_trans.union({None})) else: en_t_list = list(all_enabled_trans) trans = stochastic_utils.pick_transition(en_t_list, smap) if trans is None: break visited_elements.append(trans) if trans.label is not None: visible_transitions_visited.append(trans) marking = semantics.execute(trans, net, marking) all_visited_elements.append(tuple(visited_elements)) if return_visited_elements: return all_visited_elements log = log_instance.EventLog() for index, visited_elements in enumerate(all_visited_elements): trace = log_instance.Trace() trace.attributes[case_id_key] = str(index) for element in visited_elements: if type(element ) is PetriNet.Transition and element.label is not None: event = log_instance.Event() event[activity_key] = element.label event[timestamp_key] = datetime.datetime.fromtimestamp( curr_timestamp) trace.append(event) # increases by 1 second curr_timestamp += 1 log.append(trace) return log
def apply(net: PetriNet, initial_marking: Marking, final_marking: Marking = None, parameters: Optional[Dict[Union[str, Parameters], Any]] = None) -> EventLog: """ Do the playout of a Petrinet generating a log (extensive search; stop at the maximum trace length specified Parameters ----------- net Petri net to play-out initial_marking Initial marking of the Petri net final_marking If provided, the final marking of the Petri net parameters Parameters of the algorithm: Parameters.MAX_TRACE_LENGTH -> Maximum trace length Parameters.PETRI_SEMANTICS -> Petri net semantics """ if parameters is None: parameters = {} case_id_key = exec_utils.get_param_value(Parameters.CASE_ID_KEY, parameters, xes_constants.DEFAULT_TRACEID_KEY) activity_key = exec_utils.get_param_value(Parameters.ACTIVITY_KEY, parameters, xes_constants.DEFAULT_NAME_KEY) timestamp_key = exec_utils.get_param_value(Parameters.TIMESTAMP_KEY, parameters, xes_constants.DEFAULT_TIMESTAMP_KEY) max_trace_length = exec_utils.get_param_value(Parameters.MAX_TRACE_LENGTH, parameters, 10) return_elements = exec_utils.get_param_value(Parameters.RETURN_ELEMENTS, parameters, False) max_marking_occ = exec_utils.get_param_value(Parameters.MAX_MARKING_OCC, parameters, sys.maxsize) semantics = exec_utils.get_param_value(Parameters.PETRI_SEMANTICS, parameters, petri_net.semantics.ClassicSemantics()) # assigns to each event an increased timestamp from 1970 curr_timestamp = 10000000 feasible_elements = [] to_visit = [(initial_marking, (), ())] visited = set() while len(to_visit) > 0: state = to_visit.pop(0) m = state[POSITION_MARKING] trace = state[POSITION_TRACE] elements = state[POSITION_ELEMENTS] if (m, trace) in visited: continue visited.add((m, trace)) en_t = semantics.enabled_transitions(net, m) if (final_marking is not None and m == final_marking) or (final_marking is None and len(en_t) == 0): if len(trace) <= max_trace_length: feasible_elements.append(elements) for t in en_t: new_elements = elements + (m,) new_elements = new_elements + (t,) counter_elements = Counter(new_elements) if counter_elements[m] > max_marking_occ: continue new_m = semantics.weak_execute(t, net, m) if t.label is not None: new_trace = trace + (t.label,) else: new_trace = trace new_state = (new_m, new_trace, new_elements) if new_state in visited or len(new_trace) > max_trace_length: continue to_visit.append(new_state) if return_elements: return feasible_elements log = log_instance.EventLog() for elements in feasible_elements: log_trace = log_instance.Trace() log_trace.attributes[case_id_key] = str(len(log)) activities = [x.label for x in elements if type(x) is PetriNet.Transition and x.label is not None] for act in activities: curr_timestamp = curr_timestamp + 1 log_trace.append( log_instance.Event({activity_key: act, timestamp_key: datetime.datetime.fromtimestamp(curr_timestamp)})) log.append(log_trace) return log
def apply_playout(net, initial_marking, no_traces=100, max_trace_length=100, initial_timestamp=10000000, initial_case_id=0, case_id_key=xes_constants.DEFAULT_TRACEID_KEY, activity_key=xes_constants.DEFAULT_NAME_KEY, timestamp_key=xes_constants.DEFAULT_TIMESTAMP_KEY, final_marking=None, return_visited_elements=False, semantics=petri_net.semantics.ClassicSemantics()): """ Do the playout of a Petrinet generating a log Parameters ---------- net Petri net to play-out initial_marking Initial marking of the Petri net no_traces Number of traces to generate max_trace_length Maximum number of events per trace (do break) initial_timestamp Increased timestamp from 1970 for the first event initial_case_id Case id of the first event case_id_key Trace attribute that is the case ID activity_key Event attribute that corresponds to the activity timestamp_key Event attribute that corresponds to the timestamp final_marking If provided, the final marking of the Petri net semantics Semantics of the Petri net to be used (default: petri_net.semantics.ClassicSemantics()) """ # assigns to each event an increased timestamp from 1970 curr_timestamp = initial_timestamp all_visited_elements = [] for i in range(no_traces): visited_elements = [] visible_transitions_visited = [] marking = copy(initial_marking) while len(visible_transitions_visited) < max_trace_length: visited_elements.append(marking) if not semantics.enabled_transitions(net, marking): # supports nets with possible deadlocks break all_enabled_trans = semantics.enabled_transitions(net, marking) if final_marking is not None and marking == final_marking: trans = choice(list(all_enabled_trans.union({None}))) else: trans = choice(list(all_enabled_trans)) if trans is None: break visited_elements.append(trans) if trans.label is not None: visible_transitions_visited.append(trans) marking = semantics.execute(trans, net, marking) all_visited_elements.append(tuple(visited_elements)) if return_visited_elements: return all_visited_elements log = log_instance.EventLog() for index, visited_elements in enumerate(all_visited_elements): trace = log_instance.Trace() trace.attributes[case_id_key] = str(index+initial_case_id) for element in visited_elements: if type(element) is PetriNet.Transition and element.label is not None: event = log_instance.Event() event[activity_key] = element.label event[timestamp_key] = datetime.datetime.fromtimestamp(curr_timestamp) trace.append(event) # increases by 1 second curr_timestamp += 1 log.append(trace) return log