图、节点和边的表示

DGL通过其核心数据结构 DGLGraph 提供了一个以为中心的编程抽象。
DGLGraph 提供了接口以处理图的结构、节点/边 的特征,以及使用这些组件可以执行的计算。

DGL使用一个唯一的整数来表示一个节点,称为点ID;并用对应的两个端点ID表示一条边。
同时,DGL也会根据边被添加的顺序, 给每条边分配一个唯一的整数编号,称为边ID。
节点和边的ID都是从0开始构建的。在DGL的图里,所有的边都是有方向的, 即边 (u,v) 表示它是从节点 u 指向节点 v 的。

对于多个节点,DGL使用一个一维的整型张量(PyTorch的Tensor类)来保存图的点ID, DGL称之为”节点张量”。
为了指代多条边,DGL使用一个包含2个节点张量的元组 (U, V) ,其中,用 (U[i],V[i]) 指代一条 U[i] 到V[i] 的边

创建一个 DGLGraph 对象的一种方法是使用 dgl.graph() 函数。它接受一个边的集合作为输入
下面的代码段使用了 dgl.graph() 函数来构建一个 DGLGraph 对象,对应着下图所示的包含4个节点的图。 其中一些代码演示了查询图结构的部分API的使用方法。
DGL - 图1
image.png

由于Tensor类内部使用C来存储,且显性定义了数据类型以及存储的设备信息,DGL推荐使用Tensor作为DGL API的输入。

image.png

节点和边的特征

DGLGraph 对象的节点和边可具有多个用户定义的、可命名的特征,以储存图的节点和边的属性。
通过 ndataedata 接口可访问这些特征。 例如,以下代码创建了2个节点特征(分别在第8、15行命名为 ‘x’ 、 ‘y’ )和1个边特征(在第9行命名为 ‘x’ )。
image.png
关于 ndataedata 接口的重要说明:

  • 仅允许使用数值类型(如单精度浮点型、双精度浮点型和整型)的特征。

这些特征可以是标量、向量或多维张量。

  • 每个节点特征具有唯一名称,每个边特征也具有唯一名称。

节点和边的特征可以具有相同的名称(如上述示例代码中的 ‘x’ )。

  • 通过张量分配创建特征时,DGL会将特征赋给图中的每个节点和每条边。该张量的第一维必须与图中节点或边的数量一致。 不能将特征赋给图中节点或边的子集。

异构图

image.png

在DGL中,一个异构图由一系列子图构成,一个子图对应一种关系。每个关系由一个字符串三元组 定义 (源节点类型, 边类型, 目标节点类型) 。由于这里的关系定义消除了边类型的歧义,DGL称它们为规范边类型。
下面的代码是一个在DGL中创建异构图的示例。
image.png
同构图只是一种特殊的异构图,它只包括一种关系。
image.png

与异构图相关联的 metagraph 就是图的模式,它指定节点集和节点之间的边的类型约束。
metagraph 中的一个节点 u 对应于相关异构图中的一个节点类型。 metagraph 中的边 (u,v) 表示在相关异构图中存在从 u 型节点到 v 型节点的边。
image.png

当引入多种节点和边类型后,用户在调用DGLGraph API以获取特定类型的信息时,需要指定具体的节点和边类型。此外,不同类型的节点和边具有单独的ID。
image.png
为了设置/获取特定节点和边类型的特征,DGL提供了两种新类型的语法: g.nodes[‘node_type’].data[‘feat_name’]和g.edges[‘edge_type’].data[‘feat_name’]
image.png
如果图里只有一种节点或边类型,则不需要指定节点或边的类型。
image.png

将异构体转化为同构图

异构图为管理不同类型的节点和边及其相关特征提供了一个清晰的接口。这在以下情况下尤其有用

  1. 不同类型的节点和边的特征具有不同的数据类型或大小。
  2. 用户希望对不同类型的节点和边应用不同的操作。

如果上述情况不适用,并且用户不希望在建模中区分节点和边的类型,则DGL允许使用 **dgl.DGLGraph.to_homogeneous()** API将异构图转换为同构图。 具体行为如下:

  1. 用从0开始的连续整数重新标记所有类型的节点和边。
  2. 对所有的节点和边合并用户指定的特征。

image.png
image.png