【问题标题】:Why does a GraphView omit the 0th vertex?为什么 GraphView 省略了第 0 个顶点?
【发布时间】:2020-06-18 00:46:54
【问题描述】:

根据installation guide,我正在使用安装在它自己的 conda 环境中的最新版本的 graph_tool。

我最近在使用这个库时遇到了一些令人费解的行为。当我运行以下代码时:

import graph_tool

graph = graph_tool.Graph(directed=False)
graph.add_vertex(10)
subgraph = graph_tool.GraphView(graph, graph.get_vertices())

print(graph.get_vertices())
print(subgraph.get_vertices())

输出是:

[0 1 2 3 4 5 6 7 8 9]
[1 2 3 4 5 6 7 8 9]

我认为 GraphView 应该像在指定顶点上诱导的子图一样(所以在我的示例代码的情况下,整个顶点集)。那么为什么 GraphView 会省略第 0 个顶点呢?

或者,如果这实际上是 graph_tool 中的一个错误,如果我想使用包含第 0 个顶点的子图,那么有什么好的方法可以解决它?

【问题讨论】:

    标签: python graph-tool


    【解决方案1】:

    您在答案中发布了文档,但您似乎没有仔细阅读它(强调添加):

    参数 g 必须是 Graph 类的实例。如果指定,vfilt 和 efilt 分别选择过滤哪些顶点和边。这些参数可以是 布尔值 PropertyMap 或 ndarray,它们指定选择哪些顶点/边,或者是一个一元函数,如果要选择给定的顶点/边,则返回 True,或 False否则。

    如果您传递属性映射或数组,它必须是布尔值,而不是顶点列表。这意味着它必须具有[True, False, False, True, ... ] 的形式,其中True 表示保留相应的顶点,否则将被过滤掉。这就是为什么从您的示例中删除索引为 0(即 False)的顶点,并保留所有剩余的顶点的原因。

    【讨论】:

    • 感谢您的澄清。但是,我确实仔细阅读了文档。对所写内容的最正确解释是描述符“布尔值”实际上只适用于“PropertyMap”。如果您希望它同时应用于“PropertyMap”和“ndarray”,则它需要“可以是布尔值的 PropertyMap 或 ndarray”。这是措辞上的微小差异,但它确实改变了含义。我假设它应该是一个整数数组,因为没有指定类型,并且库在我见过的所有其他情况下都将顶点集表示为整数数组。
    • @trevorKirkby 好的,我明白了。我将更新文档以使其更清晰。
    【解决方案2】:

    所以我找到了解决方法。来自 GraphView 的文档:

    参数 g 必须是 Graph 类的实例。如果指定, vfilt 和 efilt 选择过滤哪些顶点和边, 分别。这些参数可以是布尔值 PropertyMap 或 ndarray,指定哪些顶点/边是 选择,或一元函数,如果给定,则返回 True 选择顶点/边,否则为 False。

    所以顶点掩码也可以由一元函数指定,该函数表示顶点是否是子图的一部分:

    def get_subgraph(graph, vertices):
        f = lambda x: x in vertices
        return graph_tool.GraphView(graph, f)
    

    而且,不知何故,这个版本确实有效!

    subgraph = get_subgraph(graph, graph.get_vertices())
    print(graph.get_vertices())
    print(subgraph.get_vertices())
    

    输出:

    [0 1 2 3 4 5 6 7 8 9]
    [0 1 2 3 4 5 6 7 8 9]
    

    所以实际上不可能制作一个包含 0 作为顶点的 GraphView,如果你尝试使用一个 numpy 数组,它显然是行不通的。

    这个答案对我有用,但是如果有人有更好的解决方法(特别是因为这个方法使得返回大图的子图要慢得多),或者如果有人知道为什么会出现这种奇怪的行为,我仍然会感兴趣第一名。

    编辑:

    此实现利用 numpy 来计算顶点掩码,而不是原生 python “in”操作,因此对于较大的图形来说要快得多:

    def get_subgraph(graph, vertices):
        property_map = graph.new_vertex_property("bool")
        property_map.a = np.isin(graph.get_vertices(), vertices)
        return graph_tool.GraphView(graph, property_map)
    

    【讨论】:

      猜你喜欢
      • 2017-02-12
      • 2018-02-04
      • 2018-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多