dgl.compact_graphs

dgl.compact_graphs(graphs, always_preserve=None, copy_ndata=True, copy_edata=True)[source]

给定一组具有相同节点集的图,找到并消除所有图中共同的孤立节点。

此函数要求图具有相同的节点集(即节点类型必须相同,且每种节点类型的节点数量必须相同)。元图不必相同。

它找到所有在给定图中入度和出度均为零的节点,并将它们从所有图中移除。

适用于图采样,当你有一个巨大的图,但你只希望在一个较小的图上执行消息传递,该图只包含(极小的)节点子集。

Parameters:
  • graphs (DGLGraphlist[DGLGraph]) –

    图,或图的列表。

    所有图必须在相同的设备上。

    所有图必须具有相同的节点集。

  • always_preserve (Tensordict[str, Tensor], optional) –

    如果给定了一个节点类型和节点ID张量的字典,那么给定节点类型的节点将不会被移除,无论它们是否孤立。

    如果给定了一个张量,DGL会假设所有图都有一个(相同的)节点类型。

  • copy_ndata (bool, optional) –

    如果为True,返回的图的节点特征将从原始图中复制。

    如果为False,返回的图将没有任何节点特征。

    (默认值:True)

  • copy_edata (bool, optional) –

    如果为True,反转图的边特征将从原始图中复制。

    如果为False,反转图将不会有任何边特征。

    (默认值: True)

Returns:

压缩后的图或压缩后的图列表。

每个返回的图都会有一个特征 dgl.NID,包含从压缩图到原始图的每种类型的节点ID映射。 请注意,所有压缩图的映射都是相同的。

所有返回的图都在CPU上。

Return type:

DGLGraphlist[DGLGraph]

注释

此函数目前要求所有图的相同节点类型应具有相同的节点类型ID,即节点类型的顺序相同。

如果 copy_edata 为 True,生成的图将与输入图共享边特征张量。因此,用户应尽量避免对两个图都可见的原地操作。

This function discards the batch information. Please use dgl.DGLGraph.set_batch_num_nodes() and dgl.DGLGraph.set_batch_num_edges() on the transformed graph to maintain the information.

示例

以下代码构建了一个包含20个用户和10个游戏的双向图,但只有用户#1和#3,以及游戏#3和#5之间有连接:

>>> g = dgl.heterograph({('user', 'plays', 'game'): ([1, 3], [3, 5])},
>>>                      {'user': 20, 'game': 10})

以下将把上面的图压缩成另一个只有两个用户和两个游戏的二分图。

>>> new_g = dgl.compact_graphs(g)
>>> new_g.ndata[dgl.NID]
{'user': tensor([1, 3]), 'game': tensor([3, 5])}

映射告诉我们,只有用户#1和#3以及游戏#3和#5被保留。 此外,压缩图中的第一个用户和第二个用户映射到原始图中的用户#1和#3。游戏的情况类似。

可以验证,在压缩图中,边的连接保持不变。

>>> new_g.edges(form='all', order='eid', etype='plays')
(tensor([0, 1]), tensor([0, 1]), tensor([0, 1]))

在压缩多个图时,任何在给定图中没有任何连接的节点将被移除。因此,如果你压缩g和以下g2图一起:

>>> g2 = dgl.heterograph({('user', 'plays', 'game'): ([1, 6], [6, 8])},
>>>                      {'user': 20, 'game': 10})
>>> new_g, new_g2 = dgl.compact_graphs([g, g2])
>>> new_g.ndata[dgl.NID]
{'user': tensor([1, 3, 6]), 'game': tensor([3, 5, 6, 8])}

然后可以看到,两个图中的用户#1,第一个图中的用户#3,以及第二个图中的用户#6都被保留了。游戏是相似的。

同样,也可以验证连接:

>>> new_g.edges(form='all', order='eid', etype='plays')
(tensor([0, 1]), tensor([0, 1]), tensor([0, 1]))
>>> new_g2.edges(form='all', order='eid', etype='plays')
(tensor([0, 2]), tensor([2, 3]), tensor([0, 1]))