Source code for pm4py.objects.heuristics_net.obj

'''
    PM4Py – A Process Mining Library for Python
Copyright (C) 2024 Process Intelligence Solutions UG (haftungsbeschränkt)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see this software project's root or
visit <https://www.gnu.org/licenses/>.

Website: https://processintelligence.solutions
Contact: info@processintelligence.solutions
'''
from copy import deepcopy

from pm4py.objects.dfg.utils import dfg_utils

DEFAULT_NET_NAME = ""


[docs] class HeuristicsNet: def __init__( self, frequency_dfg, activities=None, start_activities=None, end_activities=None, activities_occurrences=None, default_edges_color="#000000", performance_dfg=None, dfg_window_2=None, freq_triples=None, net_name=DEFAULT_NET_NAME, ): """ Initialize an Hueristics Net The implementation is based on the original paper on Heuristics Miner, namely: Weijters, A. J. M. M., Wil MP van Der Aalst, and AK Alves De Medeiros. "Process mining with the heuristics miner-algorithm." Technische Universiteit Eindhoven, Tech. Rep. WP 166 (2006): 1-34. and it manages to calculate the dependency matrix, the loops of length one and two, and the AND measure Parameters ------------- frequency_dfg Directly-Follows graph (frequency) activities Activities start_activities Start activities end_activities End activities activities_occurrences Activities occurrences default_edges_color (If provided) Default edges color performance_dfg Performance DFG dfg_window_2 DFG window 2 freq_triples Frequency triples net_name (If provided) name of the heuristics net """ self.net_name = [net_name] self.nodes = {} self.dependency_matrix = {} self.dfg_matrix = {} self.dfg = frequency_dfg self.performance_dfg = performance_dfg self.node_type = ( "frequency" if self.performance_dfg is None else "performance" ) self.activities = activities if self.activities is None: self.activities = dfg_utils.get_activities_from_dfg(frequency_dfg) if start_activities is None: self.start_activities = [ dfg_utils.infer_start_activities(frequency_dfg) ] else: self.start_activities = [start_activities] if end_activities is None: self.end_activities = [ dfg_utils.infer_end_activities(frequency_dfg) ] else: self.end_activities = [end_activities] self.activities_occurrences = activities_occurrences if self.activities_occurrences is None: self.activities_occurrences = {} for act in self.activities: self.activities_occurrences[act] = ( dfg_utils.sum_activities_count(frequency_dfg, [act]) ) self.default_edges_color = [default_edges_color] self.dfg_window_2 = dfg_window_2 self.dfg_window_2_matrix = {} self.freq_triples = freq_triples self.freq_triples_matrix = {} self.concurrent_activities = {} self.sojourn_times = {} def __add__(self, other_net): copied_self = deepcopy(self) for node_name in copied_self.nodes: if node_name in other_net.nodes: node1 = copied_self.nodes[node_name] node2 = other_net.nodes[node_name] n1n = {x.node_name: x for x in node1.output_connections} n2n = {x.node_name: x for x in node2.output_connections} for out_node1 in node1.output_connections: if out_node1.node_name in n2n: node1.output_connections[out_node1] = ( node1.output_connections[out_node1] + node2.output_connections[ n2n[out_node1.node_name] ] ) for out_node2 in node2.output_connections: if out_node2.node_name not in n1n: if out_node2.node_name in copied_self.nodes: nn = copied_self.nodes[out_node2.node_name] node1.output_connections[nn] = ( node2.output_connections[out_node2] ) else: node1.output_connections[out_node2] = ( node2.output_connections[out_node2] ) diffext = [ other_net.nodes[node] for node in other_net.nodes if node not in copied_self.nodes ] for node in diffext: copied_self.nodes[node.node_name] = node copied_self.start_activities = ( copied_self.start_activities + other_net.start_activities ) copied_self.end_activities = ( copied_self.end_activities + other_net.end_activities ) copied_self.default_edges_color = ( copied_self.default_edges_color + other_net.default_edges_color ) copied_self.net_name = copied_self.net_name + other_net.net_name return copied_self def __repr__(self): return str(self.nodes) def __str__(self): return str(self.nodes)