【论文阅读】Directed Graph Convolutional Network

论文连接:Directed Graph Convolutional Network

摘要

由于GCN的局限性,本文提出了DGCN(有向 图 卷积 网络),通过一阶和二阶邻居关系的应用,并扩展卷积计算。

介绍

GCN主要存在两个缺点:

  1. 仅适用于无向图。对于有向图只能采用对称的领接矩阵,得到半正定的拉普拉斯矩阵,但同时也失去了有向图的唯一结构。例如,对于一个表明文章引用关系的有向图,将其转换为无向图是不太合理的。可以采用RNN和GCN的组合来学习时间图,但其添加了额外组件。
  2. 仅考虑1跳结点特征。在大多数的基于光谱的GCN中,每个卷积操作中,只捕获了顶点的一阶信息。而没有直接相连的结点也可能存在某些关系,例如社交网络中,拥有共同兴趣的人,不一定相互联系(直接相连)。尽管能够堆叠多层GCN获得更多信息,但多层网络容易导致过拟合。

本文利用二阶邻近点来对现有方法进行扩展,不仅能够保留有向图的方向特征,也能够扩展图卷积的感受域,从而提取更多的特征。本文主要贡献:

  • 提出DGCN,性能优于传统GCNs
  • 在有向图上定义一阶和二阶邻近度,能够扩展卷积感受域

定义

定义有向图 G = ( V , E ) G=(V,E) G=(V,E),顶点集 V = ( v 1 , v 2 , . . . , v n ) V=(v_1,v_2,...,v_n) V=(v1,v2,...,vn),边集 E ⊂ { 1 , . . . , n } × { 1 , . . . , n } E \subset \left\{1,...,n\right\} \times \left\{ 1,...,n \right\} E{ 1,...,n}×{ 1,...,n},如果顶点 i i i到顶点 j j j之间存在一条有向边,则有 e = ( i , j ) e=(i,j) e=(i,j)。有向图中 ( u , v ) ≠ ( v , u ) (u,v)\ne (v,u) (u,v)=(v,u) w i , j ≠ w j , i w_{i,j} \ne w_{j,i} wi,j=wj,i

一阶边:对于顶点 i , j i,j i,j,如果存在 ( i , j ) ∈ E (i,j)\in E (i,j)E,则 ( i , j ) (i,j) (i,j)为一阶边
二阶边:对于顶点 i , j , k i,j,k i,j,k,如果存在 ( i , k ) a n d ( j , k ) ∈ E (i,k) and (j,k) \in E (i,k)and(j,k)E,则 ( i , j ) (i,j) (i,j)为二阶边

Feature Smoothness(特征平滑度):评估获得的信息量大小
λ f = ∣ ∣ ∑ i ∈ V ′ ( ∑ e i , j ∈ E ′ ( x i − x j ) 2 ) ∣ ∣ 1 ∣ E ′ ∣ ⋅ d \lambda_f=\frac{||\sum_{i\in V'}(\sum_{e_{i,j}\in E'}(x_i-x_j)^2)||_1}{|E'|\cdot d} λf=EdiV(ei,jE(xix

  • 2
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
使用C++实现有向图的邻接矩阵,以及可达矩阵的计算算法。 请完成Project05.cpp中DirectedGraph类的成员函数,具体要求如下: DirectedGraph类: 用来表示一个有向图。 成员变量: m_AdjMat:邻接矩阵 m_ReachabilityMat:可达矩阵 成员函数: DirectedGraph():默认构造函数,构造一个空。 ~DirectedGraph():析构函数 DirectedGraph(string filepath):解析文件filepath,构造一个DirectedGraph对象。 filepath文件格式与项目四相同,但本项目的有向图DirectedGraph(const Graph & graph):复制构造函数 operator=(const Graph & graph):赋值运算符 ClearGraph():清空的邻接矩阵和可达矩阵。 OutputGraph():输出的邻接矩阵 operator*(const DirectedGraph & graph): 乘法运算符,用于实现可达矩阵运算中的矩阵逻辑乘 DirectedGraph Pow(int power):邻接矩阵的整数次幂。 用法如下: DirectedGraph a; a = a.Pow(5); 即a的5次幂,相当于a = a * a * a * a * a; 注意要考虑0次幂的情况。 该函数适合以递归实现。 DirectedGraph MatOr(DirectedGraph graph):矩阵逐元素的逻辑或运算。 例如: 1 0 0 1 与 0 1 1 0 运算后的结果为 1 1 1 1 void CalcReachabilityMat():计算可达矩阵,要求该函数基于*运算符和Pow函数实现 void OutputReachabilityMat():输出可达矩阵 IsConnected(int src, int dst):基于可达矩阵判断从节点src与dst之间是否存在通路,如存在返回真,否则返回假
05-30
以下是Project05.cpp的完整代码实现,包括DirectedGraph类的定义和成员函数的实现: ```c++ #include <iostream> #include <fstream> #include <vector> #include <cstring> using namespace std; const int MAXN = 100; // 最大节点数 class DirectedGraph { public: DirectedGraph(); DirectedGraph(string filepath); DirectedGraph(const DirectedGraph & graph); ~DirectedGraph(); DirectedGraph & operator=(const DirectedGraph & graph); void ClearGraph(); void OutputGraph(); DirectedGraph operator*(const DirectedGraph & graph); DirectedGraph Pow(int power); DirectedGraph MatOr(DirectedGraph graph); void CalcReachabilityMat(); void OutputReachabilityMat(); bool IsConnected(int src, int dst); private: int n; // 节点数 int m_AdjMat[MAXN][MAXN]; // 邻接矩阵 int m_ReachabilityMat[MAXN][MAXN]; // 可达矩阵 void ReadGraphFromFile(string filepath); // 从文件中读取 }; DirectedGraph::DirectedGraph() { n = 0; memset(m_AdjMat, 0, sizeof(m_AdjMat)); memset(m_ReachabilityMat, 0, sizeof(m_ReachabilityMat)); } DirectedGraph::DirectedGraph(string filepath) { n = 0; memset(m_AdjMat, 0, sizeof(m_AdjMat)); memset(m_ReachabilityMat, 0, sizeof(m_ReachabilityMat)); ReadGraphFromFile(filepath); } DirectedGraph::DirectedGraph(const DirectedGraph & graph) { n = graph.n; memcpy(m_AdjMat, graph.m_AdjMat, sizeof(m_AdjMat)); memcpy(m_ReachabilityMat, graph.m_ReachabilityMat, sizeof(m_ReachabilityMat)); } DirectedGraph::~DirectedGraph() {} DirectedGraph & DirectedGraph::operator=(const DirectedGraph & graph) { if (this == &graph) { return *this; } n = graph.n; memcpy(m_AdjMat, graph.m_AdjMat, sizeof(m_AdjMat)); memcpy(m_ReachabilityMat, graph.m_ReachabilityMat, sizeof(m_ReachabilityMat)); return *this; } void DirectedGraph::ClearGraph() { n = 0; memset(m_AdjMat, 0, sizeof(m_AdjMat)); memset(m_ReachabilityMat, 0, sizeof(m_ReachabilityMat)); } void DirectedGraph::OutputGraph() { cout << "邻接矩阵:" << endl; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << m_AdjMat[i][j] << " "; } cout << endl; } } DirectedGraph DirectedGraph::operator*(const DirectedGraph & graph) { DirectedGraph ret; ret.n = n; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { for (int k = 0; k < n; k++) { ret.m_ReachabilityMat[i][j] = ret.m_ReachabilityMat[i][j] || (m_ReachabilityMat[i][k] && graph.m_ReachabilityMat[k][j]); } } } return ret; } DirectedGraph DirectedGraph::Pow(int power) { DirectedGraph ret; ret.n = n; if (power == 0) { for (int i = 0; i < n; i++) { ret.m_ReachabilityMat[i][i] = 1; } } else if (power == 1) { memcpy(ret.m_ReachabilityMat, m_ReachabilityMat, sizeof(m_ReachabilityMat)); } else if (power % 2 == 0) { DirectedGraph half = Pow(power / 2); ret = half * half; } else { DirectedGraph half = Pow(power / 2); ret = half * half * (*this); } return ret; } DirectedGraph DirectedGraph::MatOr(DirectedGraph graph) { DirectedGraph ret; ret.n = n; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { ret.m_ReachabilityMat[i][j] = m_ReachabilityMat[i][j] || graph.m_ReachabilityMat[i][j]; } } return ret; } void DirectedGraph::CalcReachabilityMat() { DirectedGraph ret; ret.n = n; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { ret.m_ReachabilityMat[i][j] = m_AdjMat[i][j]; } } for (int i = 1; i < n; i++) { ret = ret + Pow(i); } memcpy(m_ReachabilityMat, ret.m_ReachabilityMat, sizeof(m_ReachabilityMat)); } void DirectedGraph::OutputReachabilityMat() { cout << "可达矩阵:" << endl; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { cout << m_ReachabilityMat[i][j] << " "; } cout << endl; } } bool DirectedGraph::IsConnected(int src, int dst) { return m_ReachabilityMat[src][dst]; } void DirectedGraph::ReadGraphFromFile(string filepath) { ifstream fin(filepath); if (!fin) { cout << "文件不存在!" << endl; return; } fin >> n; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { fin >> m_AdjMat[i][j]; } } fin.close(); } int main() { DirectedGraph graph("input.txt"); graph.OutputGraph(); graph.CalcReachabilityMat(); graph.OutputReachabilityMat(); cout << "0和3是否连通:" << graph.IsConnected(0, 3) << endl; cout << "1和2是否连通:" << graph.IsConnected(1, 2) << endl; return 0; } ``` 在该代码中,我们定义了DirectedGraph类,实现了题目中要求的各种成员函数。我们首先在main函数中创建一个DirectedGraph对象,并读取输入文件中的有向图。然后,我们调用OutputGraph函数输出邻接矩阵。接着,我们调用CalcReachabilityMat函数计算可达矩阵,并使用OutputReachabilityMat函数输出可达矩阵。最后,我们使用IsConnected函数判断一些节点之间是否连通。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值