Пример #1
0
def apply_trace(trace, petri_net, initial_marking, final_marking, best_worst, activity_key):
    """
    Performs the basic alignment search, given a trace, a net and the costs of the \"best of the worst\".
    The costs of the best of the worst allows us to deduce the fitness of the trace.
    We compute the fitness by means of 1 - alignment costs / best of worst costs (i.e. costs of 0 => fitness 1)

    Parameters
    ----------
    trace: :class:`list` input trace, assumed to be a list of events (i.e. the code will use the activity key to
    get the attributes)
    petri_net: :class:`pm4py.objects.petri.net.PetriNet` the Petri net to use in the alignment
    initial_marking: :class:`pm4py.objects.petri.net.Marking` initial marking in the Petri net
    final_marking: :class:`pm4py.objects.petri.net.Marking` final marking in the Petri net
    best_worst: cost of the best worst alignment of a trace (empty trace aligned to the model)
    activity_key: :class:`str` (optional) key to use to identify the activity described by the events

    Returns
    -------
    dictionary: `dict` with keys **alignment**, **cost**, **visited_states**, **queued_states** and **traversed_arcs**
    """
    alignment = alignments.apply_trace(trace, petri_net, initial_marking, final_marking,
                                       {Parameters.ACTIVITY_KEY: activity_key})
    fixed_costs = alignment['cost'] // alignments.utils.STD_MODEL_LOG_MOVE_COST
    if best_worst > 0:
        fitness = 1 - (fixed_costs / best_worst)
    else:
        fitness = 1
    return {'trace': trace, 'alignment': alignment['alignment'], 'cost': fixed_costs, 'fitness': fitness,
            'visited_states': alignment['visited_states'], 'queued_states': alignment['queued_states'],
            'traversed_arcs': alignment['traversed_arcs']}
Пример #2
0
    def _process_partition(iterator, heuristic=None, algorithm=None):
        partial_solutions = {}
        estimations = []

        for element in iterator:
            trace = element[0]
            model, initial_marking, final_marking = element[1]

            if heuristic is None:
                estimations.append((element[0], element[1]))  # (trace, model)
            else:
                estimation = heuristic(trace, model)
                estimations.append((element[0], element[1],
                                    estimation))  # (trace, model, estimation)

        if heuristic is not None:
            estimations.sort(key=(lambda x: x[2]))  # sort by estimation

        for element in estimations:
            trace = element[0]
            model, initial_marking, final_marking = element[1]

            trace_name = trace.attributes['concept:name']
            prev_cost = math.inf

            estimation = None
            if heuristic is not None:  # if heuristic is defined, check the estimation value
                estimation = element[2]

            if trace_name in partial_solutions.keys():
                prev_cost = partial_solutions[trace_name]['normalized_cost']
                if estimation is not None:
                    if prev_cost <= estimation:  # if previous cost is better than estimation, skip this iteration
                        continue
                if prev_cost == 0:  # if prev_cost is 0, skip this iteration
                    continue

            alignment = alignment_alg.apply_trace(trace,
                                                  model,
                                                  initial_marking,
                                                  final_marking,
                                                  parameters=algorithm)
            normalized_cost = int(alignment['cost'] / 10000)

            if normalized_cost < prev_cost:
                partial_solutions[trace_name] = {
                    'normalized_cost': normalized_cost,
                    'calculated_alignment': alignment
                }
                if heuristic is not None:
                    partial_solutions[trace_name]['estimation'] = estimation

        return [(k, v) for k, v in partial_solutions.items()]