为什么图形视图会忽略第0个顶点?

2024-09-24 22:31:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用安装在自己的conda环境中的graph_工具的最新版本,如installation guide

我最近在这个图书馆遇到了一些令人困惑的行为。当我运行以下代码时:

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_工具中的一个bug,如果我想处理包含第0个顶点的子图,那么解决它的好方法是什么


Tags: 工具代码版本get环境installationtoolconda
2条回答

所以我找到了一个解决办法。从GraphView的文档中:

The argument g must be an instance of a Graph class. If specified, vfilt and efilt select which vertices and edges are filtered, respectively. These parameters can either be a boolean-valued PropertyMap or a ndarray, which specify which vertices/edges are selected, or an unary function that returns True if a given vertex/edge is to be selected, or False otherwise.

因此,顶点遮罩也可以由一元函数指定,该函数表示顶点是否是子图的一部分:

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)

您在回答中发布了文档,但似乎您没有仔细阅读(重点补充):

The argument g must be an instance of a Graph class. If specified, vfilt and efilt select which vertices and edges are filtered, respectively. These parameters can either be a boolean-valued PropertyMap or a ndarray, which specify which vertices/edges are selected, or an unary function that returns True if a given vertex/edge is to be selected, or False otherwise.

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

相关问题 更多 >