当前位置: 首页 > 面试题库 >

在Python中表示图(数据结构)

甘学潞
2023-03-14
问题内容

如何用Python巧妙地表示图形?(从头开始,即没有库!)什么数据结构(例如dicts
/ tuples /
dict(tuples))既快速又具有存储效率?一个必须能够对它执行各种图形操作。
如前所述,各种图形表示可能会有所帮助。如何在Python中实现它们?至于图书馆,这个问题有很好的答案。


问题答案:

即使这是一个有点老的问题,我还是想为遇到问题的任何人提供一个切实可行的答案。

假设您以如下的元组列表的形式获取连接的输入数据:

[('A', 'B'), ('B', 'C'), ('B', 'D'), ('C', 'D'), ('E', 'F'), ('F', 'C')]

我发现对Python中的图形最有用和最有效的数据结构是 集合的决定
。这将是我们Graph班级的基础结构。您还必须知道这些连接是弧形(定向,以一种方式连接)还是边缘(无定向,以两种方式连接)。我们将通过directed向该Graph.__init__方法添加参数来处理该问题。我们还将添加一些其他有用的方法。

import pprint
from collections import defaultdict


class Graph(object):
    """ Graph data structure, undirected by default. """

    def __init__(self, connections, directed=False):
        self._graph = defaultdict(set)
        self._directed = directed
        self.add_connections(connections)

    def add_connections(self, connections):
        """ Add connections (list of tuple pairs) to graph """

        for node1, node2 in connections:
            self.add(node1, node2)

    def add(self, node1, node2):
        """ Add connection between node1 and node2 """

        self._graph[node1].add(node2)
        if not self._directed:
            self._graph[node2].add(node1)

    def remove(self, node):
        """ Remove all references to node """

        for n, cxns in self._graph.items():  # python3: items(); python2: iteritems()
            try:
                cxns.remove(node)
            except KeyError:
                pass
        try:
            del self._graph[node]
        except KeyError:
            pass

    def is_connected(self, node1, node2):
        """ Is node1 directly connected to node2 """

        return node1 in self._graph and node2 in self._graph[node1]

    def find_path(self, node1, node2, path=[]):
        """ Find any path between node1 and node2 (may not be shortest) """

        path = path + [node1]
        if node1 == node2:
            return path
        if node1 not in self._graph:
            return None
        for node in self._graph[node1]:
            if node not in path:
                new_path = self.find_path(node, node2, path)
                if new_path:
                    return new_path
        return None

    def __str__(self):
        return '{}({})'.format(self.__class__.__name__, dict(self._graph))

我将其作为创建读者find_shortest_path和其他方法的“读者练习” 。

让我们来看看实际情况…

>>> connections = [('A', 'B'), ('B', 'C'), ('B', 'D'),
                   ('C', 'D'), ('E', 'F'), ('F', 'C')]
>>> g = Graph(connections, directed=True)
>>> pretty_print = pprint.PrettyPrinter()
>>> pretty_print.pprint(g._graph)
{'A': {'B'},
 'B': {'D', 'C'},
 'C': {'D'},
 'E': {'F'},
 'F': {'C'}}

>>> g = Graph(connections)  # undirected
>>> pretty_print = pprint.PrettyPrinter()
>>> pretty_print.pprint(g._graph)
{'A': {'B'},
 'B': {'D', 'A', 'C'},
 'C': {'D', 'F', 'B'},
 'D': {'C', 'B'},
 'E': {'F'},
 'F': {'E', 'C'}}

>>> g.add('E', 'D')
>>> pretty_print.pprint(g._graph)
{'A': {'B'},
 'B': {'D', 'A', 'C'},
 'C': {'D', 'F', 'B'},
 'D': {'C', 'E', 'B'},
 'E': {'D', 'F'},
 'F': {'E', 'C'}}

>>> g.remove('A')
>>> pretty_print.pprint(g._graph)
{'B': {'D', 'C'},
 'C': {'D', 'F', 'B'},
 'D': {'C', 'E', 'B'},
 'E': {'D', 'F'},
 'F': {'E', 'C'}}

>>> g.add('G', 'B')
>>> pretty_print.pprint(g._graph)
{'B': {'D', 'G', 'C'},
 'C': {'D', 'F', 'B'},
 'D': {'C', 'E', 'B'},
 'E': {'D', 'F'},
 'F': {'E', 'C'},
 'G': {'B'}}

>>> g.find_path('G', 'E')
['G', 'B', 'D', 'C', 'F', 'E']


 类似资料:
  • 描述无定向多图的最佳数据结构是什么(针对速度和内存进行了优化)? 一个边的列表是不合适的,因为在我的代码中,获取顶点的邻居经常发生。 邻接列表是不好的,因为我必须保留关于已访问边的信息,并且当从1到3的边被访问时(假设我遍历1的邻居,发现一条边通向3并且具有weight),我必须在3的邻居列表中找到相同的边以将其标记为已访问,这很慢。 当每个单元格都是时,我考虑过邻接矩阵,其中是表示顶点是否被访问

  • 本文向大家介绍数据结构中的ADT数组表示,包括了数据结构中的ADT数组表示的使用技巧和注意事项,需要的朋友参考一下 基本概念 ADT表示抽象数据类型。 数组被定义为ADT,因为它们能够以相同的顺序保存连续的元素。他们允许 通过索引或位置访问特定元素。 它们是抽象的,因为它们可以是String,int或Person 好处 快速随机访问项目或元素。 内存效率很高,除了存储内容所需的内存很少。 缺点 元

  • 问题内容: 我正在尝试在Python的大草坪地图中显示以下geojson文件,但它仅显示一个空地图,没有任何数据。 这是我尝试的步骤: 我尝试使用下面的python代码,但未显示任何内容。 我使用相同的代码在下面的github存储库中尝试了其他geojson文件,并且数据显示没有问题,所以看起来我的python代码很好 我在github和Mapshaper中打开了“ census_tracts_2

  • 我正在尝试从 Hbase 表中获取数据。其中只有两列,一个是像“US”等国家鳕鱼,另一个是一些具有整数值的分析字段,它可以被认为是计数数。 现在,当我在Jaspersoft中获取这些行以创建图表时,Jaspersft将创建“number_of_chart=number_ of_rows”,并且所有图表都是相似的。例如,如果我的表中有15行,它将在报告中创建15个类似的图表。尽管图表中创建的条形图采

  • 有了水果列表,我想检查它们是否存在于数据帧中(不管是哪个列),并指明它们。 这些守则的问题包括: 它显示的不是水果,而是整个内容。例如,14805行,应仅为“Blackberry”,而不是整个原始内容 我怎样才能做到呢?非常感谢。 这是当前输出和所需输出的屏幕截图。

  • 我需要在数据表列中动态显示图像,我在本地文件夹中有图像,如何在Bootsface数据表中这样做? 谢谢你的帮助!