在物理科学中,熵是衡量一个系统的无序程度。同样,在图论中,熵是描述网络结构和功能的指标。熵与存储在图中的信息量有关。这在计算机科学领域被用来检查数据的压缩,因为压缩后的数据更加随机,因此具有更高的熵值。
图的熵是一个信息论的函数,它被定义在一个具有顶点集概率密度的图上。
这个函数最初是由J.Korner在1973年提出的,用于研究表示一个信息源所需的最小码字数。
图的熵的一个最重要的特性是它对图的联合是次加性的。这导致了它在图覆盖问题以及完美散列问题中的应用。
对于无向图和有向图,有各种计算图的熵的方法,我们现在将详细了解这些方法和它们的用途。
图的熵
图的熵起源于信息论,最早的估计之一是由Shanon给出的,它一般描述了编码一个特定的概率分布所需的最小比特数。如果一个结果的概率是π
,那么编码该结果所需的比特数是

所需的比特数是每个结果所需的比特数乘以该事件发生的概率,得出的结果是

这也是Shanon的熵。当在图上应用这个方法时,事件通常被假定为图的节点。J.Korner在他1973年关于图熵的论文中引用了这一点。
设 G = (V,E)是一个无向图。G的图熵,表示为H(G),定义为

如果从G的独立集合中均匀地选择XV,YG的独立集合上的范围,则X的联合分布为 X和 Y的联合分布是:X∈Y,概率为1,而I是X和Y的相互信息。
图熵的基本属性
图熵的主要属性是单调性、次可加性和顶点替换的可加性。
- 单调性
- 对于任何概率密度P,我们有H(F,P)<= H(G,P)
- 一个子图的熵总是小于或等于超图的熵。
- 对于上述图F和G,我们有VP(G)⊆VP(F)。这立即意味着上面的陈述。
- **副加性
- 给定两个图形G1=(V,E1)和G2=(V,E2)在同一个顶点集V上,图形联盟G1U G2=(V,E1 U E2)满足H(G1 U G2) <= H(G1) + H(G2)
- 两个图的联盟的熵小于或等于各个图的熵之和。
- 分别有n1, n2..., nk个顶点的互不相交的图G1, G2..., Gk的算术平均值 那么。
一些特殊图形的熵
- 一个没有边的图的熵是0。
- 一个有n个顶点的完整图形的熵为log2n。
- 一个完整的平衡k-partite图的熵为log2k。
- 从上面我们可以看出,完整的两边形图的熵为1。
- 一个分区有n个顶点,另一个分区有m个顶点的完整二方图有熵H(n/m+n)。其中H是二元熵函数。
有向图的熵
在观察网络时,熵是一个重要的方面,但主要是早先所做的所有研究都是以无向图为中心的,有向图的熵是最近的进展。
与无向图相比,有向图涉及特殊的非对称转移。
然而,对于有向图,我们使用Chung的概括或von Neuman的方法,这是基于图的拉普拉斯,这可以适用于弱定向和强定向图,其简单的形式可以用简单的节点内度外度的统计来表示。
这种对有向网络的研究对于量化整个网络的结构信息是非常重要的。为了量化一个有向图的熵,我们依靠基于度的算法来衡量顶点的重要性,通常比其他指标更敏感。
现在我们已经转向了基于特征值的熵计算,这取决于邻接矩阵。从复杂网络的典型模型中,我们提出了一个考虑到节点连接方向的有向网络模型,并对有向近邻耦合的三个矩阵进行了基于特征值的熵的计算。有向小世界、有向无标度和有向随机网络。
比较
与有向网络相比,无向网络在边数较少的情况下具有较高的熵,这一趋势随着边数的增加而改变。熵主要取决于边的数量,由于非对称转移,有向网络又是一个特殊的例子。
例子
现在我们来看看如何利用上述知识来计算图的熵。

在上图中,我们计算熵如下
使用发生率矩阵并使用上面的Shanon熵公式
熵=-[0.6 x log2(0.6) + 0.2 x log2(0.2) + 0.1 x log2(0.1) + 0.1 x log2(0.1) ] = 1.5710
现在我们有另一个类似的图

与我们上面的做法类似
熵 = -[0.4 x log2(0.4) + 0.4 x log2(0.4) + 0.2 x log2(0.2) ] = 1.5230
利用这两个图形,我们注意到了图形的熵是如何计算的
执行
现在我们将尝试用一个简单的C++代码来实现简单无定向图的熵。
伪代码
- 将图的入射矩阵作为输入,并将其存储在一个二维向量中
- 遍历上三角矩阵,以便对每条边只考虑一次,对于每一个非零值,将函数p*log2p的输出增加到和变量中。
- 总和将始终为零,这个总和的大小将是熵。
- 向用户输出熵值
代码
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main(){
int n;
cout << "Enter number of vertices" << endl;
cin >> n;
// we take a 2D vector to store the incidence matrix of the graph
vector<vector<float>> mat( n , vector<float> (n, 0));
cout << "Enter the incidence matrix of the graph : " << endl;
for(int i = 0 ; i < n ; i++){
for(int j = 0; j < n; j++) {
float x;
cin >> x;
mat[i][j] = x;
}
}
// sum stores the sum for shanon entropy
float sum = 0.0;
for(int i = 0 ; i < n ; i++){
for(int j = i; j < n; j++) {
if(mat[i][j] != 0){
sum += mat[i][j]*log2(mat[i][j]);
}
}
}
cout << "The entropy of the graph is : " << endl;
cout << -sum << endl;
}
现在让我们尝试通过执行上述代码找到图G2的熵值

我们看到程序的输出是在我们上面计算的误差范围内的。
