def apply_log(log, petri_net, initial_marking, final_marking, parameters=None, version=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 version :class:`str` selected variant of the algorithm, possible values: {\'state_equation_a_star\'} parameters :class:`dict` parameters of the algorithm, for key \'state_equation_a_star\': pm4py.util.constants.PARAMETER_CONSTANT_ACTIVITY_KEY -> Attribute in the log that contains the activity pm4py.algo.conformance.alignments.variants.state_equation_a_star.PARAM_MODEL_COST_FUNCTION -> mapping of each transition in the model to corresponding synchronous costs pm4py.algo.conformance.alignments.variants.state_equation_a_star.PARAM_SYNC_COST_FUNCTION -> mapping of each transition in the model to corresponding model cost pm4py.algo.conformance.alignments.variants.state_equation_a_star.PARAM_TRACE_COST_FUNCTION -> mapping of each index of the trace to a positive cost value 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. """ warnings.warn( 'factory methods are deprecated, use algorithm entrypoint instead', DeprecationWarning) if parameters is None: parameters = dict() if not check_soundness.check_relaxed_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 relaxed sound net!!" ) start_time = time.time() activity_key = parameters[ PARAMETER_CONSTANT_ACTIVITY_KEY] if PARAMETER_CONSTANT_ACTIVITY_KEY in parameters else DEFAULT_NAME_KEY model_cost_function = parameters[ PARAM_MODEL_COST_FUNCTION] if PARAM_MODEL_COST_FUNCTION in parameters else None sync_cost_function = parameters[ PARAM_SYNC_COST_FUNCTION] if PARAM_SYNC_COST_FUNCTION in parameters else None max_align_time = parameters[ PARAM_MAX_ALIGN_TIME] if PARAM_MAX_ALIGN_TIME in parameters else DEFAULT_MAX_ALIGN_TIME max_align_time_case = parameters[ PARAM_MAX_ALIGN_TIME_TRACE] if PARAM_MAX_ALIGN_TIME_TRACE in parameters else DEFAULT_MAX_ALIGN_TIME_TRACE if model_cost_function is None or sync_cost_function is None: # reset variables value model_cost_function = dict() sync_cost_function = dict() for t in petri_net.transitions: if t.label is not None: model_cost_function[t] = align_utils.STD_MODEL_LOG_MOVE_COST sync_cost_function[t] = 0 else: model_cost_function[t] = 1 parameters[ pm4py.util.constants.PARAMETER_CONSTANT_ACTIVITY_KEY] = activity_key parameters[PARAM_MODEL_COST_FUNCTION] = model_cost_function parameters[PARAM_SYNC_COST_FUNCTION] = sync_cost_function parameters_best_worst = copy(parameters) if PARAM_MAX_ALIGN_TIME_TRACE in parameters_best_worst: del parameters_best_worst[PARAM_MAX_ALIGN_TIME_TRACE] best_worst_cost = VERSIONS_COST[version](petri_net, initial_marking, final_marking, parameters=parameters_best_worst) variants_idxs = parameters[ VARIANTS_IDX] if VARIANTS_IDX in parameters else None if variants_idxs is None: variants_idxs = variants_module.get_variants_from_log_trace_idx( log, parameters=parameters) one_tr_per_var = [] variants_list = [] for index_variant, variant in enumerate(variants_idxs): variants_list.append(variant) for variant in variants_list: one_tr_per_var.append(log[variants_idxs[variant][0]]) 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[PARAM_MAX_ALIGN_TIME_TRACE] = this_max_align_time all_alignments.append( apply_trace(trace, petri_net, initial_marking, final_marking, parameters=copy(parameters), version=version)) al_idx = {} for index_variant, variant in enumerate(variants_idxs): for trace_idx in variants_idxs[variant]: al_idx[trace_idx] = all_alignments[index_variant] alignments = [] for i in range(len(log)): alignments.append(al_idx[i]) # assign fitness to traces for index, align in enumerate(alignments): if align is not None: unfitness_upper_part = align[ 'cost'] // align_utils.STD_MODEL_LOG_MOVE_COST if unfitness_upper_part == 0: align['fitness'] = 1 elif (len(log[index]) + best_worst_cost) > 0: align['fitness'] = 1 - ( (align['cost'] // align_utils.STD_MODEL_LOG_MOVE_COST) / (len(log[index]) + best_worst_cost)) else: align['fitness'] = 0 return alignments
def apply_log_multiprocessing(log, petri_net, initial_marking, final_marking, parameters=None, version=DEFAULT_VARIANT): warnings.warn( 'factory methods are deprecated, use algorithm entrypoint instead', DeprecationWarning) if parameters is None: parameters = dict() if not check_soundness.check_relaxed_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 relaxed sound net!!" ) activity_key = parameters[ PARAMETER_CONSTANT_ACTIVITY_KEY] if PARAMETER_CONSTANT_ACTIVITY_KEY in parameters else DEFAULT_NAME_KEY model_cost_function = parameters[ PARAM_MODEL_COST_FUNCTION] if PARAM_MODEL_COST_FUNCTION in parameters else None sync_cost_function = parameters[ PARAM_SYNC_COST_FUNCTION] if PARAM_SYNC_COST_FUNCTION in parameters else None if model_cost_function is None or sync_cost_function is None: # reset variables value model_cost_function = dict() sync_cost_function = dict() for t in petri_net.transitions: if t.label is not None: model_cost_function[t] = align_utils.STD_MODEL_LOG_MOVE_COST sync_cost_function[t] = 0 else: model_cost_function[t] = 1 parameters[ pm4py.util.constants.PARAMETER_CONSTANT_ACTIVITY_KEY] = activity_key parameters[PARAM_MODEL_COST_FUNCTION] = model_cost_function parameters[PARAM_SYNC_COST_FUNCTION] = sync_cost_function parameters_best_worst = copy(parameters) if PARAM_MAX_ALIGN_TIME_TRACE in parameters_best_worst: del parameters_best_worst[PARAM_MAX_ALIGN_TIME_TRACE] best_worst_cost = VERSIONS_COST[version](petri_net, initial_marking, final_marking, parameters=parameters_best_worst) variants_idxs = parameters[ VARIANTS_IDX] if VARIANTS_IDX in parameters else None if variants_idxs is None: variants_idxs = variants_module.get_variants_from_log_trace_idx( log, parameters=parameters) variants_list = [[x, len(y)] for x, y in variants_idxs.items()] no_cores = mp.cpu_count() petri_net_string = petri_exporter.export_petri_as_string( petri_net, initial_marking, final_marking) n = math.ceil(len(variants_list) / no_cores) variants_list_split = list(chunks(variants_list, n)) # Define an output queue output = mp.Queue() processes = [ mp.Process(target=VERSIONS_VARIANTS_LIST_MPROCESSING[version]( output, x, petri_net_string, parameters=parameters)) for x in variants_list_split ] # Run processes for p in processes: p.start() results = [] for p in processes: result = output.get() results.append(result) al_idx = {} for index, el in enumerate(variants_list_split): for index2, var_item in enumerate(el): variant = var_item[0] for trace_idx in variants_idxs[variant]: al_idx[trace_idx] = results[index][variant] alignments = [] for i in range(len(log)): alignments.append(al_idx[i]) # assign fitness to traces for index, align in enumerate(alignments): if align is not None: unfitness_upper_part = align[ 'cost'] // align_utils.STD_MODEL_LOG_MOVE_COST if unfitness_upper_part == 0: align['fitness'] = 1 elif (len(log[index]) + best_worst_cost) > 0: align['fitness'] = 1 - ( (align['cost'] // align_utils.STD_MODEL_LOG_MOVE_COST) / (len(log[index]) + best_worst_cost)) else: align['fitness'] = 0 return alignments
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_relaxed_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 relaxed sound net!!" ) start_time = time.time() activity_key = exec_utils.get_param_value(Parameters.ACTIVITY_KEY, parameters, DEFAULT_NAME_KEY) model_cost_function = exec_utils.get_param_value( Parameters.PARAM_MODEL_COST_FUNCTION, parameters, None) sync_cost_function = exec_utils.get_param_value( Parameters.PARAM_SYNC_COST_FUNCTION, parameters, None) 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) if model_cost_function is None or sync_cost_function is None: # reset variables value model_cost_function = dict() sync_cost_function = dict() for t in petri_net.transitions: if t.label is not None: model_cost_function[t] = align_utils.STD_MODEL_LOG_MOVE_COST sync_cost_function[t] = 0 else: model_cost_function[t] = 1 parameters[Parameters.ACTIVITY_KEY] = activity_key parameters[Parameters.PARAM_MODEL_COST_FUNCTION] = model_cost_function parameters[Parameters.PARAM_SYNC_COST_FUNCTION] = sync_cost_function parameters_best_worst = copy(parameters) best_worst_cost = exec_utils.get_variant(variant).get_best_worst_cost( petri_net, initial_marking, final_marking, parameters=parameters_best_worst) variants_idxs = exec_utils.get_param_value(Parameters.VARIANTS_IDX, parameters, None) if variants_idxs is None: variants_idxs = variants_module.get_variants_from_log_trace_idx( log, parameters=parameters) one_tr_per_var = [] variants_list = [] for index_variant, var in enumerate(variants_idxs): variants_list.append(var) for var in variants_list: one_tr_per_var.append(log[variants_idxs[var][0]]) 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)) al_idx = {} for index_variant, variant in enumerate(variants_idxs): for trace_idx in variants_idxs[variant]: al_idx[trace_idx] = all_alignments[index_variant] alignments = [] for i in range(len(log)): alignments.append(al_idx[i]) # assign fitness to traces for index, align in enumerate(alignments): if align is not None: unfitness_upper_part = align[ 'cost'] // align_utils.STD_MODEL_LOG_MOVE_COST if unfitness_upper_part == 0: align['fitness'] = 1 elif (len(log[index]) + best_worst_cost) > 0: align['fitness'] = 1 - ( (align['cost'] // align_utils.STD_MODEL_LOG_MOVE_COST) / (len(log[index]) + best_worst_cost)) else: align['fitness'] = 0 return alignments