在Python中查找Graphviz的边列表

4
有没有办法在Python中获取Graphviz图中边的列表。在我的程序中,我想在向有向图添加边之前检查节点之间是否已经存在边。我在Python的Grahviz中找不到像get_edge()has_connected()函数这样的函数。有其他做上述任务的方法吗?感谢您的帮助。
3个回答

5

如果您的目标是避免重复的边,则使用Digraph(strict=True)Graph(strict=True)


2

我刚遇到了这个问题。在源代码中没有发现任何方便的方法来检查图中是否存在边。

如果你正在处理一个非常简单的图,那么也许这个方法会有所帮助。

def has_edge(graph, v1, v2):
    tail_name = graph._quote_edge(v1)
    head_name = graph._quote_edge(v2)
    return (graph._edge % (tail_name, head_name, '')) in graph.body

我从graphviz/dot.py中的'edge()'方法进行了改编,但它不处理任何属性。
据我所见,graph.body是表示节点和边的字符串列表。

0
这里是get_edges函数,用于获取给定graphviz有向图(或无向图)的边缘列表。 该图可以表示为BaseGraphSource对象,或者仅为源字符串。默认情况下,它将返回节点ID(字符串)对,但您可以告诉get_edges函数给您任何东西(包括pydot.Edge对象本身,其中包含其所有属性)。
from typing import Tuple, List, Iterable
from pydot import Dot, graph_from_dot_data, Edge
from graphviz.graphs import BaseGraph
from graphviz import Source


def edge_to_node_ids(edge: Edge) -> Tuple[str, str]:
    """Returns the node id pair for the edge object"""
    return (edge.get_source(), edge.get_destination())


def get_graph_dot_obj(graph_spec) -> List[Dot]:
    """Get a dot (graphs) object list from a variety of possible sources (postelizing inputs here)"""
    _original_graph_spec = graph_spec
    if isinstance(graph_spec, (BaseGraph, Source)):
        # get the source (str) from a graph object
        graph_spec = graph_spec.source
    if isinstance(graph_spec, str):
        # get a dot-graph from dot string data
        graph_spec = graph_from_dot_data(graph_spec)
    # make sure we have a list of Dot objects now
    assert isinstance(graph_spec, list) and all(
        isinstance(x, Dot) for x in graph_spec
    ), (
        f"Couldn't get a proper dot object list from: {_original_graph_spec}. "
        f"At this point, we should have a list of Dot objects, but was: {graph_spec}"
    )
    return graph_spec


def get_edges(graph_spec, postprocess_edges=edge_to_node_ids):
    """Get a list of edges for a given graph (or list of lists thereof).
    If ``postprocess_edges`` is ``None`` the function will return ``pydot.Edge`` objects from
    which you can extract any information you want.
    By default though, it is set to extract the node pairs for the edges, and you can
    replace with any function that takes ``pydot.Edge`` as an input.
    """
    graphs = get_graph_dot_obj(graph_spec)
    n_graphs = len(graphs)

    if n_graphs > 1:
        return [get_edges(graph, postprocess_edges) for graph in graphs]
    elif n_graphs == 0:
        raise ValueError(f"Your input had no graphs")
    else:
        graph = graphs[0]
        edges = graph.get_edges()
        if callable(postprocess_edges):
            edges = list(map(postprocess_edges, edges))
        return edges

测试:

digraph_dot_source = """
DIGRAPH{
    rain -> traffic
    rain -> wet
    traffic, wet -> moody
}
"""

assert (
    get_edges(digraph_dot_source)
    == get_edges(Source(digraph_dot_source))
    == [('rain', 'traffic'), ('rain', 'wet'), ('wet', 'moody')]
)

graph_dot_source = """
GRAPH{
    rain -- traffic
    rain -- wet
    traffic, wet -- moody
}
"""

assert (
    get_edges(graph_dot_source)
    == get_edges(Source(graph_dot_source))
    == [('rain', 'traffic'), ('rain', 'wet'), ('wet', 'moody')]
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接