Пример #1
0
def get_graph(
    heu_net: HeuristicsNet,
    parameters: Optional[Dict[Union[str, Parameters], Any]] = None
) -> pydotplus.graphviz.Dot:
    """
    Gets a representation of an Heuristics Net

    Parameters
    -------------
    heu_net
        Heuristics net
    parameters
        Possible parameters of the algorithm, including:
            - Parameters.FORMAT

    Returns
    ------------
    graph
        Pydotplus graph
    """
    if parameters is None:
        parameters = {}

    graph = pydotplus.Dot(strict=True)
    graph.obj_dict['attributes']['bgcolor'] = 'transparent'

    corr_nodes = {}
    corr_nodes_names = {}
    is_frequency = False

    for node_name in heu_net.nodes:
        node = heu_net.nodes[node_name]
        node_occ = node.node_occ
        graycolor = transform_to_hex_2(max(255 - math.log(node_occ) * 9, 0))
        if node.node_type == "frequency":
            is_frequency = True
            n = pydotplus.Node(name=node_name,
                               shape="box",
                               style="filled",
                               label=node_name + " (" + str(node_occ) + ")",
                               fillcolor=node.get_fill_color(graycolor),
                               fontcolor=node.get_font_color())
        else:
            n = pydotplus.Node(
                name=node_name,
                shape="box",
                style="filled",
                label=node_name + " (" +
                human_readable_stat(heu_net.sojourn_times[node_name]) +
                ")" if node_name in heu_net.sojourn_times else node_name +
                " (0s)",
                fillcolor=node.get_fill_color(graycolor),
                fontcolor=node.get_font_color())
        corr_nodes[node] = n
        corr_nodes_names[node_name] = n
        graph.add_node(n)

    # gets max arc value
    max_arc_value = -1
    for node_name in heu_net.nodes:
        node = heu_net.nodes[node_name]
        for other_node in node.output_connections:
            if other_node in corr_nodes:
                for edge in node.output_connections[other_node]:
                    max_arc_value = max(max_arc_value, edge.repr_value)

    for node_name in heu_net.nodes:
        node = heu_net.nodes[node_name]
        for other_node in node.output_connections:
            if other_node in corr_nodes:
                for edge in node.output_connections[other_node]:
                    this_pen_width = 1.0 + math.log(1 + edge.repr_value) / 11.0
                    repr_value = str(edge.repr_value)
                    if edge.net_name:
                        if node.node_type == "frequency":
                            e = pydotplus.Edge(
                                src=corr_nodes[node],
                                dst=corr_nodes[other_node],
                                label=edge.net_name + " (" + repr_value + ")",
                                color=edge.get_color(),
                                fontcolor=edge.get_font_color(),
                                penwidth=edge.get_penwidth(this_pen_width))
                        else:
                            e = pydotplus.Edge(
                                src=corr_nodes[node],
                                dst=corr_nodes[other_node],
                                label=edge.net_name + " (" +
                                human_readable_stat(repr_value) + ")",
                                color=edge.get_color(),
                                fontcolor=edge.get_font_color(),
                                penwidth=edge.get_penwidth(this_pen_width))
                    else:
                        if node.node_type == "frequency":
                            e = pydotplus.Edge(
                                src=corr_nodes[node],
                                dst=corr_nodes[other_node],
                                label=repr_value,
                                color=edge.get_color(),
                                fontcolor=edge.get_font_color(),
                                penwidth=edge.get_penwidth(this_pen_width))
                        else:
                            e = pydotplus.Edge(
                                src=corr_nodes[node],
                                dst=corr_nodes[other_node],
                                label=human_readable_stat(repr_value),
                                color=edge.get_color(),
                                fontcolor=edge.get_font_color(),
                                penwidth=edge.get_penwidth(this_pen_width))

                    graph.add_edge(e)

    for index, sa_list in enumerate(heu_net.start_activities):
        effective_sa_list = [n for n in sa_list if n in corr_nodes_names]
        if effective_sa_list:
            start_i = pydotplus.Node(name="start_" + str(index),
                                     label="@@S",
                                     color=heu_net.default_edges_color[index],
                                     fontsize="8",
                                     fontcolor="#32CD32",
                                     fillcolor="#32CD32",
                                     style="filled")
            graph.add_node(start_i)
            for node_name in effective_sa_list:
                sa = corr_nodes_names[node_name]
                if type(heu_net.start_activities[index]) is dict:
                    occ = heu_net.start_activities[index][node_name]
                    if occ >= heu_net.min_dfg_occurrences:
                        if is_frequency:
                            this_pen_width = 1.0 + math.log(1 + occ) / 11.0
                            if heu_net.net_name[index]:
                                e = pydotplus.Edge(
                                    src=start_i,
                                    dst=sa,
                                    label=heu_net.net_name[index] + " (" +
                                    str(occ) + ")",
                                    color=heu_net.default_edges_color[index],
                                    fontcolor=heu_net.
                                    default_edges_color[index],
                                    penwidth=this_pen_width)
                            else:
                                e = pydotplus.Edge(
                                    src=start_i,
                                    dst=sa,
                                    label=str(occ),
                                    color=heu_net.default_edges_color[index],
                                    fontcolor=heu_net.
                                    default_edges_color[index],
                                    penwidth=this_pen_width)
                        else:
                            e = pydotplus.Edge(
                                src=start_i,
                                dst=sa,
                                label=heu_net.net_name[index],
                                color=heu_net.default_edges_color[index],
                                fontcolor=heu_net.default_edges_color[index])
                else:
                    e = pydotplus.Edge(
                        src=start_i,
                        dst=sa,
                        label=heu_net.net_name[index],
                        color=heu_net.default_edges_color[index],
                        fontcolor=heu_net.default_edges_color[index])
                graph.add_edge(e)

    for index, ea_list in enumerate(heu_net.end_activities):
        effective_ea_list = [n for n in ea_list if n in corr_nodes_names]
        if effective_ea_list:
            end_i = pydotplus.Node(name="end_" + str(index),
                                   label="@@E",
                                   color="#FFA500",
                                   fillcolor="#FFA500",
                                   fontcolor="#FFA500",
                                   fontsize="8",
                                   style="filled")
            graph.add_node(end_i)
            for node_name in effective_ea_list:
                ea = corr_nodes_names[node_name]
                if type(heu_net.end_activities[index]) is dict:
                    occ = heu_net.end_activities[index][node_name]
                    if occ >= heu_net.min_dfg_occurrences:
                        if is_frequency:
                            this_pen_width = 1.0 + math.log(1 + occ) / 11.0
                            if heu_net.net_name[index]:
                                e = pydotplus.Edge(
                                    src=ea,
                                    dst=end_i,
                                    label=heu_net.net_name[index] + " (" +
                                    str(occ) + ")",
                                    color=heu_net.default_edges_color[index],
                                    fontcolor=heu_net.
                                    default_edges_color[index],
                                    penwidth=this_pen_width)
                            else:
                                e = pydotplus.Edge(
                                    src=ea,
                                    dst=end_i,
                                    label=str(occ),
                                    color=heu_net.default_edges_color[index],
                                    fontcolor=heu_net.
                                    default_edges_color[index],
                                    penwidth=this_pen_width)
                        else:
                            e = pydotplus.Edge(
                                src=ea,
                                dst=end_i,
                                label=heu_net.net_name[index],
                                color=heu_net.default_edges_color[index],
                                fontcolor=heu_net.default_edges_color[index])
                else:
                    e = pydotplus.Edge(
                        src=ea,
                        dst=end_i,
                        label=heu_net.net_name[index],
                        color=heu_net.default_edges_color[index],
                        fontcolor=heu_net.default_edges_color[index])
                graph.add_edge(e)

    return graph
Пример #2
0
def apply(heu_net, parameters=None):
    """
    Gets a representation of an Heuristics Net

    Parameters
    -------------
    heu_net
        Heuristics net
    parameters
        Possible parameters of the algorithm, including:
            - Parameters.FORMAT

    Returns
    ------------
    gviz
        Representation of the Heuristics Net
    """
    if parameters is None:
        parameters = {}

    image_format = exec_utils.get_param_value(Parameters.FORMAT, parameters,
                                              "png")

    graph = pydotplus.Dot(strict=True)
    graph.obj_dict['attributes']['bgcolor'] = 'transparent'

    corr_nodes = {}
    corr_nodes_names = {}
    is_frequency = False

    for node_name in heu_net.nodes:
        node = heu_net.nodes[node_name]
        node_occ = node.node_occ
        graycolor = transform_to_hex_2(max(255 - math.log(node_occ) * 9, 0))
        if node.node_type == "frequency":
            is_frequency = True
            n = pydotplus.Node(name=node_name,
                               shape="box",
                               style="filled",
                               label=node_name + " (" + str(node_occ) + ")",
                               fillcolor=node.get_fill_color(graycolor),
                               fontcolor=node.get_font_color())
        else:
            n = pydotplus.Node(name=node_name,
                               shape="box",
                               style="filled",
                               label=node_name,
                               fillcolor=node.get_fill_color(graycolor),
                               fontcolor=node.get_font_color())
        corr_nodes[node] = n
        corr_nodes_names[node_name] = n
        graph.add_node(n)

    # gets max arc value
    max_arc_value = -1
    for node_name in heu_net.nodes:
        node = heu_net.nodes[node_name]
        for other_node in node.output_connections:
            if other_node in corr_nodes:
                for edge in node.output_connections[other_node]:
                    max_arc_value = max(max_arc_value, edge.repr_value)

    for node_name in heu_net.nodes:
        node = heu_net.nodes[node_name]
        for other_node in node.output_connections:
            if other_node in corr_nodes:
                for edge in node.output_connections[other_node]:
                    this_pen_width = 1.0 + math.log(1 + edge.repr_value) / 11.0
                    repr_value = str(edge.repr_value)
                    if edge.net_name:
                        if node.node_type == "frequency":
                            e = pydotplus.Edge(
                                src=corr_nodes[node],
                                dst=corr_nodes[other_node],
                                label=edge.net_name + " (" + repr_value + ")",
                                color=edge.get_color(),
                                fontcolor=edge.get_font_color(),
                                penwidth=edge.get_penwidth(this_pen_width))
                        else:
                            e = pydotplus.Edge(
                                src=corr_nodes[node],
                                dst=corr_nodes[other_node],
                                label=edge.net_name + " (" +
                                human_readable_stat(repr_value) + ")",
                                color=edge.get_color(),
                                fontcolor=edge.get_font_color(),
                                penwidth=edge.get_penwidth(this_pen_width))
                    else:
                        if node.node_type == "frequency":
                            e = pydotplus.Edge(
                                src=corr_nodes[node],
                                dst=corr_nodes[other_node],
                                label=repr_value,
                                color=edge.get_color(),
                                fontcolor=edge.get_font_color(),
                                penwidth=edge.get_penwidth(this_pen_width))
                        else:
                            e = pydotplus.Edge(
                                src=corr_nodes[node],
                                dst=corr_nodes[other_node],
                                label=human_readable_stat(repr_value),
                                color=edge.get_color(),
                                fontcolor=edge.get_font_color(),
                                penwidth=edge.get_penwidth(this_pen_width))

                    graph.add_edge(e)

    for index, sa_list in enumerate(heu_net.start_activities):
        effective_sa_list = [n for n in sa_list if n in corr_nodes_names]
        if effective_sa_list:
            start_i = pydotplus.Node(name="start_" + str(index),
                                     label="@@S",
                                     color=heu_net.default_edges_color[index],
                                     fontsize="8",
                                     fontcolor="#32CD32",
                                     fillcolor="#32CD32",
                                     style="filled")
            graph.add_node(start_i)
            for node_name in effective_sa_list:
                sa = corr_nodes_names[node_name]
                if type(heu_net.start_activities[index]) is dict:
                    if is_frequency:
                        occ = heu_net.start_activities[index][node_name]
                        this_pen_width = 1.0 + math.log(1 + occ) / 11.0
                        if heu_net.net_name[index]:
                            e = pydotplus.Edge(
                                src=start_i,
                                dst=sa,
                                label=heu_net.net_name[index] + " (" +
                                str(occ) + ")",
                                color=heu_net.default_edges_color[index],
                                fontcolor=heu_net.default_edges_color[index],
                                penwidth=this_pen_width)
                        else:
                            e = pydotplus.Edge(
                                src=start_i,
                                dst=sa,
                                label=str(occ),
                                color=heu_net.default_edges_color[index],
                                fontcolor=heu_net.default_edges_color[index],
                                penwidth=this_pen_width)
                    else:
                        e = pydotplus.Edge(
                            src=start_i,
                            dst=sa,
                            label=heu_net.net_name[index],
                            color=heu_net.default_edges_color[index],
                            fontcolor=heu_net.default_edges_color[index])
                else:
                    e = pydotplus.Edge(
                        src=start_i,
                        dst=sa,
                        label=heu_net.net_name[index],
                        color=heu_net.default_edges_color[index],
                        fontcolor=heu_net.default_edges_color[index])
                graph.add_edge(e)

    for index, ea_list in enumerate(heu_net.end_activities):
        effective_ea_list = [n for n in ea_list if n in corr_nodes_names]
        if effective_ea_list:
            end_i = pydotplus.Node(name="end_" + str(index),
                                   label="@@E",
                                   color="#",
                                   fillcolor="#FFA500",
                                   fontcolor="#FFA500",
                                   fontsize="8",
                                   style="filled")
            graph.add_node(end_i)
            for node_name in effective_ea_list:
                ea = corr_nodes_names[node_name]
                if type(heu_net.end_activities[index]) is dict:
                    if is_frequency:
                        occ = heu_net.end_activities[index][node_name]
                        this_pen_width = 1.0 + math.log(1 + occ) / 11.0
                        if heu_net.net_name[index]:
                            e = pydotplus.Edge(
                                src=ea,
                                dst=end_i,
                                label=heu_net.net_name[index] + " (" +
                                str(occ) + ")",
                                color=heu_net.default_edges_color[index],
                                fontcolor=heu_net.default_edges_color[index],
                                penwidth=this_pen_width)
                        else:
                            e = pydotplus.Edge(
                                src=ea,
                                dst=end_i,
                                label=str(occ),
                                color=heu_net.default_edges_color[index],
                                fontcolor=heu_net.default_edges_color[index],
                                penwidth=this_pen_width)
                    else:
                        e = pydotplus.Edge(
                            src=ea,
                            dst=end_i,
                            label=heu_net.net_name[index],
                            color=heu_net.default_edges_color[index],
                            fontcolor=heu_net.default_edges_color[index])
                else:
                    e = pydotplus.Edge(
                        src=ea,
                        dst=end_i,
                        label=heu_net.net_name[index],
                        color=heu_net.default_edges_color[index],
                        fontcolor=heu_net.default_edges_color[index])
                graph.add_edge(e)

    file_name = tempfile.NamedTemporaryFile(suffix='.' + image_format)
    file_name.close()
    graph.write(file_name.name, format=image_format)
    return file_name
Пример #3
0
def graphviz_visualization(
    activities_count,
    dfg,
    measure="frequency",
    max_no_of_edges_in_diagram=170,
    start_activities=None,
    end_activities=None,
):
    """
    Do GraphViz visualization of a DFG graph

    Parameters
    -----------
    activities_count
        Count of attributes in the log (may include attributes that are not in the DFG graph)
    dfg
        DFG graph
    image_format
        GraphViz should be represented in this format
    measure
        Describes which measure is assigned to edges in direcly follows graph (frequency/performance)
    max_no_of_edges_in_diagram
        Maximum number of edges in the diagram allowed for visualization

    Returns
    -----------
    node_edge_data
        node and edge dict data
    """
    if start_activities is None:
        start_activities = []
    if end_activities is None:
        end_activities = []

    # first, remove edges in diagram that exceeds the maximum number of edges in the diagram
    dfg_key_value_list = []
    for edge in dfg:
        dfg_key_value_list.append([edge, dfg[edge]])
    dfg_key_value_list = sorted(dfg_key_value_list, key=lambda x: x[1], reverse=True)
    dfg_key_value_list = dfg_key_value_list[
        0 : min(len(dfg_key_value_list), max_no_of_edges_in_diagram)
    ]
    dfg_allowed_keys = [x[0] for x in dfg_key_value_list]
    dfg_keys = list(dfg.keys())
    for edge in dfg_keys:
        if edge not in dfg_allowed_keys:
            del dfg[edge]

    activities_in_dfg = set()
    activities_count_int = copy(activities_count)

    for edge in dfg:
        activities_in_dfg.add(edge[0])
        activities_in_dfg.add(edge[1])

    if len(activities_in_dfg) == 0:
        activities_to_include = set(activities_count_int)
    else:
        activities_to_include = set(activities_in_dfg)

    node_edge_data = {"nodes": [], "edges": []}
    activities_map = {}

    for act in activities_to_include:
        if act in activities_count_int:
            node_edge_data["nodes"].append(
                {"data": {"id": act, "label": str(activities_count_int[act])}}
            )
            activities_map[act] = str(hash(act))
        else:
            node_edge_data["nodes"].append({"data": {"id": act, "label": None}})
            activities_map[act] = str(hash(act))

    # represent edges
    for edge in dfg:
        if "frequency" in measure:
            label = str(dfg[edge])
        else:
            label = human_readable_stat(dfg[edge])
        node_edge_data["edges"].append(
            {"data": {"source": edge[0], "target": edge[1], "id": label}}
        )

    start_activities_to_include = [
        act for act in start_activities if act in activities_map
    ]
    end_activities_to_include = [act for act in end_activities if act in activities_map]

    if start_activities_to_include:
        node_edge_data["nodes"].append(
            {"data": {"id": "start", "label": str(activities_count_int["start"])}}
        )
        for act in start_activities_to_include:
            if "frequency" in measure:
                node_edge_data["edges"].append(
                    {
                        "data": {
                            "source": "start",
                            "target": act,
                            "id": str(activities_count_int[act]),
                        }
                    }
                )
            else:
                node_edge_data["edges"].append(
                    {"data": {"source": "start", "target": act, "id": None,}}
                )

    if end_activities_to_include:
        node_edge_data["nodes"].append(
            {"data": {"id": "end", "label": str(activities_count_int["start"])}}
        )
        for act in end_activities_to_include:
            if "frequency" in measure:
                node_edge_data["edges"].append(
                    {
                        "data": {
                            "source": act,
                            "target": "end",
                            "id": str(activities_count_int[act]),
                        }
                    }
                )
            else:
                node_edge_data["edges"].append(
                    {"data": {"source": act, "target": "end", "id": None,}}
                )

    return node_edge_data