信息熵
不同的话语包含的信息量是不一样的。一句短小的话可能包含着很大的信息量,而一句冗长的话可能只含有一点点信息量。因此我们想知道一句话所包含的信息量,但看它的长度肯定是不对的,而是应该看它以最好的方式被压缩以后长度是多少。
我们把一句话看作一个二进制串,更一般地,一句话应当是一个随机生成的二进制串,也就是说,一个“随机变量”。一句话所包含的信息量与生成这句话的随即方式有关:假如我们就生成长度为n的二进制串,如果一种方式是始终输出全0串,那么这句话包含的信息量是很小的,因为我们只得到了“全0”以及“长度”这两个信息,我们很容易把这个串压缩成一个很短的串;而另一种方式是每一位都均匀随机的生成0或1,在这种情况下不同随机状态下我们会得到完全不一样的串,我们几乎无法对它进行任何的压缩,因此这句话的信息量是很大的。
香农提出了一个定量描述信息量的方法,称为“信息熵”。假设我们关注的随机变量X是从一个1,⋯,n上的概率分布,Pr[X=i]=pi,那么X的信息熵定义为
H(X)=i=1∑npilog2pi1
事实上,这个表达式是可以被公理化的。通过四条公理我们就能唯一确定信息熵的表达式必须呈现这样的形式。分别是:①对称性, 对X的概率分布做一个permutation不影响信息熵的大小;②连续性,当某个pi发生微小变化时H(X)的变化也是微小的;③单调性,如果分布是均匀随机的,那么n越大信息熵越大;④链式法则,H(X,Y)=H(X)+H(Y∣X),至于它是什么含义,我们之后再来讨论。
我们会看到,用熵方法来解决组合问题时,本质上是在用概率方法,而我们又已经看到概率方法本质上就是计数方法。所以这一切仍然只是计数方法而已。但计数方法是通用的底层的方法,熵方法和概率方法一样,能为我们解决问题提供更高的视角和更巧妙的手段。
压缩编码
现在就来看压缩编码问题。对于一个随机变量,我们可以对它的每种可能的结果来用二进制编码,而二进制编码所需要的位数就是它最好能被压缩的长度。我们将会看到,这个长度就是随机变量的信息熵的大小。
比如我们的随机变量就是在[n]均匀分布的,即恒有Pr[X=i]=n1,那么我们可以计算信息熵H(X)=i=1∑nn1log21/n1=log2n——这很符合我们的直观,因为1,..,n的正整数直接用二进制表示就需要log2n位,不可能做得比这更优了。我们严格地说明这件事。H(X)=i=1∑npilog2pi1可以写作“期望”:H(X)=E[log2pi1](把log2pi1看作一个随机变量而已),根据Jensen不等式,因为log2(x)是上凸函数,所以有E[log2pi1]≤log2(E[pi1]),而根据期望的定义E[pi1]=i=1∑npipi1=n,于是我们证明了H(X)≤log2n恒成立。这印证了“随即均匀分布”是信息量最大的语句。
那么是不是所有的随机变量,我们都能构造出期望长度为H(X)的二进制串呢?我们来给出一种构造方法:首先不妨把p1到pn从大到小排序,为了使二进制串的期望长度为H(X),我们就期待X=i时给出一个长度为ℓi=⌈log2pi1⌉的串,概率高的串就短,概率低的串就长,很符合直观的“贪心要求”。为了证明这样真的是能够做到的,我们现在来证明当我们要构造X=i对应的串的时候,我们能使用一个长度为ℓi的串,它不作为任何串的前缀。这意味着,假如我们想象一棵二叉树,左儿子边对应0,右儿子边对应1,那么一个串就是一条从根节点到某个节点的路径,为了保证任何以这个串为前缀的串都不再是合法的,我们需要删掉末尾节点为根节点的整个子树。我们只需要证明,当我们想构造X=i对应的串时,树上依然存在从根节点出发的长度为ℓi的串。我们计算来说明这一点:最初树上有2ℓi条这样的路径,假如对于j<i,我们删除了以j为根节点的子树,那么会导致消灭了2ℓi−ℓj条我们想要的路径。所以剩下的路径条数至少有2ℓi−j=1∑i−12ℓi−ℓj=2ℓi(1−j=1∑i−12ℓj1)≥2log2pi1(1−j=1∑i−12log2pj11)=pi1(1−j=1∑i−1pj)>0。所以我们总能找到这样的路径。
现在我们要说明,别的编码方法不可能更优。假设另一种编码方法,把X=i编码成ℓˉi。我们证明E[ℓˉi]≥H(x),也就是证明E[ℓˉi]−E[log2pi1]≥0。即证i∑pi(ℓˉi−log2pi1)=i∑pi(log21/pi2ℓˉi)=E[log2(2ℓˉipi)]≥0。即证−E[log2(2ℓˉipi1)]≥0。运用Jensen不等式,−E[log2(2ℓˉipi1)]≥ −log2(E[pi⋅2ℓˉi1])。其中E[pi⋅2ℓˉi1]=i=1∑npi⋅pi⋅2ℓˉi1=i=1∑n2−ℓˉi。因此只需证i=1∑n2−ℓˉi≤1。这个和式有个直观意义:作为一种编码方式,每个ℓˉi都对应着二叉树上某个点,我们给这些节点做上标记。我们想象一个人从根节点出发在二叉树上随机游走,等概率走向左儿子和右儿子,如果碰到被标记的节点那么就停止游走。于是,它走到某个被标记的节点ℓˉi上的概率就恰好是2−ℓˉi,和式i=1∑n2−ℓˉi是所有可能的停下来的情况之和,因此就代表“随机游走停下来”这一事件发生的概率。有相当的可能性,如果被标记节点没有封锁所有往下的路径的话,那么随机游走有可能永远停不下来,此时这个和式的值就小于1,如果封锁了全部路径,这个概率就等于1。不管怎么样,我们通过这个随机游走的组合意义看到i=1∑n2−ℓˉi≤1一定成立,这样证明就结束了。
所以我们看到,一个随机变量的熵真的能够代表对它进行二进制编码的最少位数。
联合随机变量的熵
现在我们来解释(X,Y)是什么含义。通常我们定义Z=(X,Y),表示随机变量Z是某两个随机变量X,Y的二元组,是一个由随机变量联合起来形成的对象,称为“联合随机变量”。
例如,假设现在我们生成两次0..7的随机数,那么样本空间Ω={0..7}×{0..7},同时我们采用的随机方法规定两次生成的数之和为奇数的概率为0,其余情况均匀分布。那么我们定义随机变量X返回第一次生成的随机数(这的确是个随机变量,因为它是样本空间到实数的映射),Y返回第二次生成的随机数,那么我们就可以用(X,Y)这样一个联合随机变量来表示样本空间中的一个事件了,这样的事件总共有8×8/2=32个。
下面来计算这个联合变量的熵。我们来计算联合随机变量的熵。首先,H(X)=H(Y)=i=1∑npilog2pi1=8×81×log2811=log28=3。对于联合随机变量(X,Y),我们也可以求它的熵,因为只要是由一个概率分布的东西都可以求熵。我们把(X,Y)当作普通的随机变量一样来看待的话,它有32种取值,每种取值的概率都是321。于是求得H(X,Y)=32×321×log232=5。于是我们发现H(X)+H(Y)>H(X,Y)。这说明了什么呢?熵代表的是信息量,或者更精确地,压缩成最优的二进制串需要的位数。如果我们先单独压缩X再单独压缩Y来得到(X,Y)的编码,我们发现这样做不是最优的,也就是我们浪费了一些无用的位数。这其实是容易发现的,因为我们已经提前知道了不可能出现两个奇偶性不同的X,Y,所以一旦X确定了以后,我们其实已经知道了一部分Y的信息,所以再单独给Y编码就一定造成浪费了。
这就证实了我们在给出熵的公理时为什么没有写H(X,Y)=H(X)+H(Y)而是给出了H(X,Y)=H(X)+H(Y∣X)。从韦恩图的角度来理解的话,我们把H(X,Y)看作集合X∪Y,表示(X,Y)包含的信息,那么H(Y∣X)必须表示的是Y∖X,表示Y上剔除所有X的信息以后单独留下的信息。换言之,我们需要用第一个变量的信息已知的眼光去看第二个变量,这就是我们为什么采用了和条件概率一样的符号,它用来提醒我们X是“作为条件的”已知量。严格地,H(Y∣X):=x∑Pr[X=x]⋅H(Y∣X=x),其中Y∣X=x与我们在“条件概率”中讨论的是同一个东西,可以把它展开写成H(Y∣X=x)=y∑Pr[Y=y∣X=x]log2Pr[Y=y∣X=x]1。于是就有H(Y∣X)=x∑Pr[X=x]y∑Pr[Y=y∣X=x]log2Pr[Y=y∣X=x]1,它可以看作Ex[y∑Pr[Y=y∣X=x]log2Pr[Y=y∣X=x]1]=Ex[H(Y∣X=x)]。
从熵的表达式出发,我们来验证H(X,Y)=H(X)+H(Y∣X)的正确性:H(X,Y)=x,y∑Pr[X=x∧Y=y]log2Pr[X=x∧Y=y]1 =−x,y∑Pr[X=x∧Y=y]log2Pr[X=x∧Y=y],根据条件期望的定义Pr[A∧B]=Pr[A∣B]⋅Pr[B],因此H(X,Y)=−x,y∑Pr[Y=y∣X=x]Pr[X=x]log2(Pr[Y=y∣X=x]Pr[X=x])。先枚举x,得到−x∑Pr[X=x]y∑Pr[Y=y∣X=x]log2(Pr[Y=y∣X=x]Pr[X=x]) =−x∑Pr[X=x](y∑Pr[Y=y∣X=x]log2(Pr[X=x])+y∑Pr[Y=y∣X=x]log2(Pr[Y=y∣X=x])) =−x∑Pr[X=x](log2(Pr[X=x])y∑Pr[Y=y∣X=x]+y∑Pr[Y=y∣X=x]log2(Pr[Y=y∣X=x])),其中y∑Pr[Y=y∣X=x]=1,于是H(X,Y)=−x∑Pr[X=x]log2(Pr[X=x])−x∑Pr[X=x]y∑Pr[Y=y∣X=x]log2(Pr[Y=y∣X=x]) =H(X)+x∑Pr[X=x]H(Y∣X=x)=H(X)+H(Y∣X)。
我们也可以根据定义证得我们通过例子给出的不等式H(X,Y)≤H(X)+H(Y),当随机变量X,Y独立时等号成立,因为它们之间互相不能给出对方的任何信息。
联合随机变量可以推广到超过2个变量的情形,这时我们得到的是“链式法则”:H(X1,⋯,Xn)=H(X1)+H(X2∣X1)+H(X3∣X1,X2)+⋯+H(Xn∣X1,⋯,Xn−1)。同样也有不等式H(X1,⋯,Xn)≤H(X1)+⋯+H(Xn),当所有变量互相独立时取到等号。
熵方法
下面我们就用熵来解决计数问题。其核心用到了熵与数量之间的对数关系(压缩编码时我们已经证明了这一点),如果我们证明了熵有某个下界w,那么对应着它的数量一定≥2w。
坐标投影计数
随机给出n3个R3中互不相同的整数点(x,y,z),构成集合S。设Sx为所有这些点的横坐标构成的集合,Sy,Sz同理。我们容易发现∣Sx∣,∣Sy∣,∣Sz∣中至少有一个≥n,因为如果三者都<n就不可能形成n3个点。
从熵的角度看它是怎么样的?考虑这n3个点是随机均匀生成的,那么H(X,Y,Z)=∑n31log2n3=3log2n。而根据我们的不等式,H(X,Y,Z)≤H(X)+H(Y)+H(Z),因此H(X),H(Y),H(Z)中至少有一个≥log2n,不妨设就是H(X)≥log2n。也就意味着,如果以最好的方式压缩也需要至少log2n位,那么X在十进制下至少是一个大于等于n的数。从这个过程我们也再次看到,熵确实可以被理解成一种加权平均,一种期望,根据期望的界来证明不等式我们是熟悉的,因此我们同样也可以用熵的界来证明不等式。
如果把条件修改为S往三个坐标平面上投影Sxy,Sxz,Syz,那么怎么证明Sxy≥n2。平凡的证法似乎不再有效了,但是熵方法依然可行。我们采用相似的方法,希望能够证明H(X,Y)≥log2n2,这可以通过H(X,Y)+H(X,Z)+H(Y,Z)≥6log2n来得到。右侧也就是2H(X,Y,Z)。根据链式法则,H(X,Y,Z)=H(X,Y)+H(Z∣X,Y)。同时也有H(X,Y,Z)=H(Y,Z)+H(X∣Y,Z)。因此2H(X,Y,Z)≤H(X,Y)+H(Y,Z)+H(Z∣X,Y)+H(X∣Y,Z)。因此只需证明H(Z∣X,Y)+H(X∣Y,Z)≤H(X,Z)。而根据条件概率的不等式H(Z∣X,Y)≤H(Z∣X),H(X∣Y,Z)≤H(X)。而H(X,Z)就等于H(X)+H(Z∣X),证毕。
2-path
设图G有n个点m条边,并且每个点的度数都为d。(可以求出d=n2m)我们要统计图中有多少条不同的长度为2的路径(2-path)。那我们枚举第一条边,有m种可能。第二条边有d−1种选择。因此总数就是m(d−1)。
现在如果我们并不保证每个点的度数都是d,而是保证点的平均度数恰好为d。此时依然有nd=2m。这时2-path的个数如何呢?我们用熵方法能够给出一个下界,基于我们能给出一个熵的下界。一条2-path的熵可以用三个顶点的随机变量来刻画:H(X,Y,Z)代表由边(X,Y)和(Y,Z)形成的2-path。H(X,Y,Z)=H(X,Y)+H(Z∣X,Y),也就是我们可以把随机的过程看作先随机地选取一条边,再以这条边的第二个端点为起点再选一条边。前者是等概率地,因此容易求出H(X,Y)=m⋅m1⋅log2m=log2m。为了讨论起来方便,我们暂时认为Z与X可以相等,之后再把这一部分影响去掉。这时,H(Z∣X,Y)就可以等价于H(Z∣Y)了,因为Z的取值丝毫不受X影响。于是H(Z∣Y)=y∑Pr[Y=y]H(Z∣Y=y),其中H(Z∣Y=y)= deg(y)⋅deg(y)1log2deg(y)=log2deg(y)。而要选到Y点,第一条边必须把Y当作第二个端点,每条边有两种顺序,因此Pr[Y=y]=2mdeg(y)。所以H(Z∣Y=y)=2m1y∑deg(y)log2deg(y)。基于xlog2x是下凸函数,我们可以根据Jensen不等式放缩,为此我们配凑一列系数n1,得到2mny∑n1deg(y)log2deg(y)=2mny∑n1f(deg(y))≥2mnf(y∑n1deg(y)) =2mnf(n2m)=2mn⋅n2mlog2n2m=log2n2m。综上H(X,Y,Z)≥log2m+log2n2m=log2n2m2。于是我们证明了(X,Y,Z)的个数至少有n2m2个,也就是md个。由于我们假设了X和Z可能相等,我们还得减掉(X,Y,X)这样的三元组的个数,这个数量用手就能输出来,因为它就是边的数量的两倍(因为要考虑顺序)。所以互不相同的三元组(X,Y,Z)数量至少为m(d−2)。由于枚举顺序的影响,这个三元组的个数恰好是2-path的两倍,因为每条路径都从不同方向被数了两边。因此我们证明了2-path的个数至少为m(2d−1)。
用类似的方法还可以数出图上的大小为4的环,因为排除了一些重叠的情况以后,大小为4的环就是两段2-path。