def apply_log(log, petri_net, initial_marking, final_marking, parameters=None, variant=DEFAULT_VARIANT): """ apply alignments to a log Parameters ----------- log object of the form :class:`pm4py.log.log.EventLog` event log petri_net :class:`pm4py.objects.petri.petrinet.PetriNet` the model to use for the alignment initial_marking :class:`pm4py.objects.petri.petrinet.Marking` initial marking of the net final_marking :class:`pm4py.objects.petri.petrinet.Marking` final marking of the net variant selected variant of the algorithm, possible values: {\'Variants.VERSION_STATE_EQUATION_A_STAR, Variants.VERSION_DIJKSTRA_NO_HEURISTICS \'} parameters :class:`dict` parameters of the algorithm, Returns ----------- alignment :class:`list` of :class:`dict` with keys **alignment**, **cost**, **visited_states**, **queued_states** and **traversed_arcs** The alignment is a sequence of labels of the form (a,t), (a,>>), or (>>,t) representing synchronous/log/model-moves. """ if parameters is None: parameters = dict() if not check_soundness.check_easy_soundness_net_in_fin_marking(petri_net, initial_marking, final_marking): raise Exception("trying to apply alignments on a Petri net that is not a easy sound net!!") start_time = time.time() max_align_time = exec_utils.get_param_value(Parameters.PARAM_MAX_ALIGN_TIME, parameters, sys.maxsize) max_align_time_case = exec_utils.get_param_value(Parameters.PARAM_MAX_ALIGN_TIME_TRACE, parameters, sys.maxsize) best_worst_cost = __get_best_worst_cost(petri_net, initial_marking, final_marking, variant, parameters) variants_idxs, one_tr_per_var = __get_variants_structure(log, parameters) progress = __get_progress_bar(len(one_tr_per_var), parameters) parameters[Parameters.BEST_WORST_COST_INTERNAL] = best_worst_cost all_alignments = [] for trace in one_tr_per_var: this_max_align_time = min(max_align_time_case, (max_align_time - (time.time() - start_time)) * 0.5) parameters[Parameters.PARAM_MAX_ALIGN_TIME_TRACE] = this_max_align_time all_alignments.append(apply_trace(trace, petri_net, initial_marking, final_marking, parameters=copy(parameters), variant=variant)) if progress is not None: progress.update() alignments = __form_alignments(log, variants_idxs, all_alignments) __close_progress_bar(progress) return alignments
def apply(log: Union[EventLog, EventStream, pd.DataFrame], net: PetriNet, marking: Marking, final_marking: Marking, parameters: Optional[Dict[Any, Any]] = None, variant=None) -> float: """ Method to apply ET Conformance Parameters ----------- log Trace log net Petri net marking Initial marking final_marking Final marking parameters Parameters of the algorithm, including: pm4py.util.constants.PARAMETER_CONSTANT_ACTIVITY_KEY -> Activity key variant Variant of the algorithm that should be applied: - Variants.ETCONFORMANCE_TOKEN - Variants.ALIGN_ETCONFORMANCE """ if parameters is None: parameters = {} log = log_conversion.apply(log, parameters, log_conversion.TO_EVENT_LOG) # execute the following part of code when the variant is not specified by the user if variant is None: if not (check_easy_soundness_net_in_fin_marking( net, marking, final_marking)): # in the case the net is not a easy sound workflow net, we must apply token-based replay variant = ETCONFORMANCE_TOKEN else: # otherwise, use the align-etconformance approach (safer, in the case the model contains duplicates) variant = ALIGN_ETCONFORMANCE return exec_utils.get_variant(variant).apply(log, net, marking, final_marking, parameters=parameters)
def apply_log(log, petri_net, initial_marking, final_marking, parameters=None, variant=DEFAULT_VARIANT): """ apply multialignments to a log Parameters ----------- log object of the form :class:`pm4py.log.log.EventLog` event log petri_net :class:`pm4py.objects.petri.petrinet.PetriNet` the model to use for the alignment initial_marking :class:`pm4py.objects.petri.petrinet.Marking` initial marking of the net final_marking :class:`pm4py.objects.petri.petrinet.Marking` final marking of the net variant selected variant of the algorithm parameters :class:`dict` parameters of the algorithm, Returns ----------- """ if parameters is None: parameters = dict() if not check_soundness.check_easy_soundness_net_in_fin_marking( petri_net, initial_marking, final_marking): raise Exception( "Trying to apply multi-alignments on a Petri net that is not an sound net." ) start_time = time.time() multialignments = exec_utils.get_variant(variant).apply(log, petri_net, initial_marking, final_marking, parameters=None) total_time = start_time - time.time() return multialignments
def apply(log, net, marking, final_marking, parameters=None): """ Get Align-ET Conformance precision Parameters ---------- log Trace log net Petri net marking Initial marking final_marking Final marking parameters Parameters of the algorithm, including: Parameters.ACTIVITY_KEY -> Activity key """ if parameters is None: parameters = {} debug_level = parameters["debug_level"] if "debug_level" in parameters else 0 activity_key = exec_utils.get_param_value(Parameters.ACTIVITY_KEY, parameters, log_lib.util.xes.DEFAULT_NAME_KEY) # default value for precision, when no activated transitions (not even by looking at the initial marking) are found precision = 1.0 sum_ee = 0 sum_at = 0 unfit = 0 if not check_soundness.check_easy_soundness_net_in_fin_marking(net, marking, final_marking): raise Exception("trying to apply Align-ETConformance on a Petri net that is not a easy sound net!!") prefixes, prefix_count = precision_utils.get_log_prefixes(log, activity_key=activity_key) prefixes_keys = list(prefixes.keys()) fake_log = precision_utils.form_fake_log(prefixes_keys, activity_key=activity_key) align_stop_marking = align_fake_log_stop_marking(fake_log, net, marking, final_marking, parameters=parameters) all_markings = transform_markings_from_sync_to_original_net(align_stop_marking, net, parameters=parameters) for i in range(len(prefixes)): markings = all_markings[i] if markings is not None: log_transitions = set(prefixes[prefixes_keys[i]]) activated_transitions_labels = set() for m in markings: # add to the set of activated transitions in the model the activated transitions # for each prefix activated_transitions_labels = activated_transitions_labels.union( x.label for x in utils.get_visible_transitions_eventually_enabled_by_marking(net, m) if x.label is not None) escaping_edges = activated_transitions_labels.difference(log_transitions) sum_at += len(activated_transitions_labels) * prefix_count[prefixes_keys[i]] sum_ee += len(escaping_edges) * prefix_count[prefixes_keys[i]] if debug_level > 1: print("") print("prefix=", prefixes_keys[i]) print("log_transitions=", log_transitions) print("activated_transitions=", activated_transitions_labels) print("escaping_edges=", escaping_edges) else: unfit += prefix_count[prefixes_keys[i]] if debug_level > 0: print("\n") print("overall unfit", unfit) print("overall activated transitions", sum_at) print("overall escaping edges", sum_ee) # fix: also the empty prefix should be counted! start_activities = set(get_start_activities(log, parameters=parameters)) trans_en_ini_marking = set([x.label for x in get_visible_transitions_eventually_enabled_by_marking(net, marking)]) diff = trans_en_ini_marking.difference(start_activities) sum_at += len(log) * len(trans_en_ini_marking) sum_ee += len(log) * len(diff) # end fix if sum_at > 0: precision = 1 - float(sum_ee) / float(sum_at) return precision
def apply(log, petri_net, initial_marking, final_marking, parameters=None, variant=None): """ Apply fitness evaluation starting from an event log and a marked Petri net, by using one of the replay techniques provided by PM4Py Parameters ----------- log Trace log object petri_net Petri net initial_marking Initial marking final_marking Final marking parameters Parameters related to the replay algorithm variant Chosen variant: - Variants.ALIGNMENT_BASED - Variants.TOKEN_BASED Returns ---------- fitness_eval Fitness evaluation """ if parameters is None: parameters = {} # execute the following part of code when the variant is not specified by the user if variant is None: if not (check_easy_soundness_net_in_fin_marking( petri_net, initial_marking, final_marking)): # in the case the net is not a easy sound workflow net, we must apply token-based replay variant = TOKEN_BASED else: # otherwise, use the align-etconformance approach (safer, in the case the model contains duplicates) variant = ALIGNMENT_BASED if variant == TOKEN_BASED: # execute the token-based replay variant return exec_utils.get_variant(variant).apply(log_conversion.apply( log, parameters, log_conversion.TO_EVENT_LOG), petri_net, initial_marking, final_marking, parameters=parameters) else: # execute the alignments based variant, with the specification of the alignments variant align_variant = exec_utils.get_param_value( Parameters.ALIGN_VARIANT, parameters, alignments.petri_net.algorithm.DEFAULT_VARIANT) return exec_utils.get_variant(variant).apply( log_conversion.apply(log, parameters, log_conversion.TO_EVENT_LOG), petri_net, initial_marking, final_marking, align_variant=align_variant, parameters=parameters)