【问题标题】:Finding list of edges in graphviz in Python在 Python 中的 graphviz 中查找边列表
【发布时间】:2022-01-29 03:56:07
【问题描述】:

有什么方法可以在 python 中获取 graphviz 中的边列表。在我的程序中,我想在有向图中添加边之前检查节点之间是否已经存在边。我在 python 的 grahviz 中找不到像 get_edge()has_connected() 这样的函数。有没有其他方法可以完成上述任务?任何帮助将不胜感激。

【问题讨论】:

    标签: python python-3.x python-2.7 graphviz


    【解决方案1】:

    如果您的目标是避免重复边缘,请使用 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 是代表节点和边的字符串列表。

      【讨论】:

        【解决方案3】:

        这里是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')]
        )
        

        【讨论】:

          猜你喜欢
          • 2021-04-07
          • 1970-01-01
          • 2012-03-21
          • 2021-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-28
          相关资源
          最近更新 更多