DGL的Blitz ---- Blitz的如何用DGL建图 (v9.0 版DGL)

直接上代码吧:

import dgl
import numpy as np
import torch


'''
我不知道为啥,这篇代码中所有的输出都会返回一个 报Process finished with exit code -1073740791 (0xC0000409) 的错误 ,而且要等好久才会停止运行
'''


'''
dgl是一个有向图。
所以,源点到目的点发送的消息 与 目的点发给源点的消息 可以不同 ; 
对于无向图,可以将图转换为双向图来处理:

构建DGL图: 可以通过给出两个参数: ①源节点和目标节点的列表 和 ②图中的节点数(参数num_nodes=) 来构建图。 
           当所有节点都包含在 源节点和目标节点的列表 中时,可以省略参数①图中的节点数
           
DGL图中,节点具有从 0 开始的连续 ID ; 边具有从 0 开始的连续 ID,并且边的ID与在创建过程中的源节点和目标节点列表的顺序相同
可以通过:print(g1.nodes()) ; print(g1.edges()) 来查看节点的编号信息,边的源点和目的顶点的对应向量

DGL的节点和边的属性(attribute,也叫做feature) 的 数据类型应该是:tenor 类型 ; 节点和边的属性(feature,attribute)应具有相同的形状.           # In the context of deep learning, those attributes are often called features.
将节点和边feature分配给图形: 可以通过ndata和edata两个属性接口,来设置(assign)和获取(retrieve)边和节点 :
                         ndata 和 edata 是字典类型,所以相当于在往字典中添加键值对,给各个节点或者边分配的feature可以是多维的。
                         但是记得feature的tensor的第一维的值一定是节点或边的个数。因为给节点或边赋其feature时,是要一起全部赋值的,不能说就给一般的节点赋值feature,另一半扔下不管了
                         【查询】可以使用 g.ndata 来获得节点的feature(获得节点对应的feature字典),g.edata来获得边的feature(获得边对应的feature字典)

DGL图结构查询:分别是节点个数、边的个数、某一特定节点的出度、入度 : g.num_nodes() ; g.num_edges() ; g.out_degrees(节点ID) ; g.in_degrees(节点ID)

构造生成子图 : 两种方式 : ①通过选择节点构造:g = g.subgraph([0, 1, 3])     ②通过选择边构造:g = g.edge_subgraph([0, 1, 3])

保存和加载Graph : <保存>: dgl.save_graphs('C:\\Users\\ZCH\\Desktop\\graph.dgl', g)
                <加载>: (load_g,), _ = dgl.load_graphs('graph.dgl')      #加载到load_g中,load_g就是一个DGL类型的图,正常使用就可
                        
'''

'''构造图'''
g1 = dgl.graph(([0, 0, 0, 0, 0], [1, 2, 3, 4, 5]), num_nodes=6)
# Equivalently, PyTorch LongTensors also work.
g2 = dgl.graph((torch.LongTensor([0, 0, 0, 0, 0]), torch.LongTensor([1, 2, 3, 4, 5])), num_nodes=6)
# You can omit the number of nodes argument if you can tell the number of nodes from the edge list alone.
g = dgl.graph(([0, 0, 0, 0, 0], [1, 2, 3, 4, 5]))
# Print the source and destination nodes of every edge.
print("图g1中节点有几个,编号情况:",g1.nodes())
print("图g1中边有几条,源点和目的点是啥:",g1.edges())

print("===============================================================================================================")

'''将节点和边特征分配给图形'''
#通过ndata和edata两个属性接口,来设置(assign)和获取(retrieve)边和节点
# 【注意】:这个feature的名字 'x' 和 'n' 好像是随便啥都行,然后节点的特征好像也可以有多个,(毕竟是自己建造图嘛,想在搞就咋搞)
# 因为g.ndata是个字典类型,“g.ndata['x'] = torch.randn(6, 3)”语句就相当于是向字典里面加了一组键值对
g.ndata['x'] = torch.randn(6, 3)    #向图中的所有节点(6个节点),为每个节点匹配一个一维3列的特征feature,并且这个特征的名称(key值)是: 'x' (Assign a 3-dimensional node feature vector for each node.)
# DGL中节点和边的feature可以是多维的
g.ndata['n'] = torch.randn(6, 5, 4) # Assign a 5x4 node feature matrix for each node.
g.edata['a'] = torch.randn(5, 4)    # Assign a 4-dimensional edge feature vector for each edge.

print("节点的类型:", type(g.ndata) )
print("节点的内容:",g.ndata)
print("边的内容:",g.edata)
#当然也可以指定查看对应的feature的字典下,key对应的值
# print(g.edata['a'])

print("===============================================================================================================")

'''查询图结构'''
print(g.num_nodes())        #得到图中节点个数
print(g.num_edges())        #得到图中边个数
print(g.out_degrees(1))     #查询某一特定节点(节点1)的出度
print(g.in_degrees(0))      # 查询某一特定节点(节点0)的入度

print("===============================================================================================================")

'''DGL通过选取节点或边来 构造 生成子图'''

# 【注意】: 再生成子图的时候,也会把对应的边和节点的特征复制到生成的子图中(因此,生成子图是包括节点和边的特症、出入度方向信息的)
# Induce a subgraph from node 0, node 1 and node 3 from the original graph.
sg1 = g.subgraph([0, 1, 3])
# Induce a subgraph from edge 0, edge 1 and edge 3 from the original graph.
sg2 = g.edge_subgraph([0, 1, 3])

# 您可以通过查看新图中的节点特征 dgl.NID 或边特征 dgl.EID 来获取从子图到原始图的节点/边映射
# The original IDs of each node in sg1
print("子图sg1中,各个节点的ID和orign图的节点ID的对照",sg1.ndata[dgl.NID])
# The original IDs of each edge in sg1
print("子图sg1中,各个边的ID和orign图的边ID的对照",sg1.edata[dgl.EID])
#查看生成的子图中的边和节点信息
# The original node feature of each node in sg1
print("生成的子图中,节点的'x'特征内容:",sg1.ndata['x'])
print("生成的子图中,节点的'n'特征内容:",sg1.ndata['n'])
# The original edge feature of each node in sg1
print(sg1.edata['a'])

print("通过指定边来构造的生成子图,其子图节点的特征:",sg2.ndata)
print("通过指定边来构造的生成子图,其子图边的特征:",sg2.edata)

print("===============================================================================================================")

'''构造无向图'''

#为原始图中的每条边添加反向边 ----这是DGL推荐的构建无向图的方法
undirected_g = dgl.add_reverse_edges(g)
undirected_g.edges()        #我不知道为啥这个东西没有输出,但是加上print ,如下行代码,那就有对应的输出了
print(undirected_g.edges())

print("===============================================================================================================")

'''加载和保存Graph'''

# Save graphs (如下方代码所示,会将对应的图文键存储在当前代码所属的文件夹下,命名为graoh.dgl,说白了图的存储位置就是第一个参数)
dgl.save_graphs('C:\\Users\\ZCH\\Desktop\\graph.dgl', g)
dgl.save_graphs('graphs.dgl', [g, sg1, sg2])

# Load graphs
(load_g,), _ = dgl.load_graphs('graph.dgl')
# print(load_g)
print("加载到本地的图 的边:",load_g.edges())
# (load_g, load_sg1, load_sg2), _ = dgl.load_graphs('graphs.dgl')
# print(load_g)
# print(load_sg1)
# print(load_sg2)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值