受到刘未鹏的启发,思考了霍夫曼编码。
霍夫曼编码要解决什么目的?
本质是找到一种编码,使期望值最小。用公式表达就是
编码有两种,一种定长,一种不定长。定长的很好理解。
那么不定长的最优解码会存在吗?
不定长的情况下,就要引入前缀码了。所谓的前缀码就是任意一个的编码不是其他任意一个的前缀。为什么?如果一个码是另一个码的前缀,当你解析到这个码的时候,你就无法分清谁是谁了。
比如a编码成0,b编码成10,c编码成11,这样abccb就是010111110了,很容易解码。
并且,这里的a假设0.5,b假设0.25,c假设0.25,那么期望值就是1.5了。而用定长编码的话,至少得2bit了。看起来优化方案还是可能存在的。(有时候得问自己优化方案存在吗?有两个证明方法,第一,举例,最简单的例子;第二,如果是有限集合,则肯定存在最优方案。)
由这个编码很容易想到编码树。(实在不知道为什么这里会有树也没关系。起码想起霍夫曼编码和树相关,比想起霍夫曼编码的具体细节要容易)
这个树有什么性质呢?
1,首先,所有编码都是叶子,不是内节点。因为如果有内节点,则不是前缀码了。对吧?
2,树是满树,所有的内节点都有两个儿子。不存在只有一个儿子的情况。(为什么?因为如果存在一个儿子,则用这个子树取代内节点,会生成更小的树)
怎么构造这棵树呢?苦恼啊!
我们先看看这棵树还有什么特性。我们只能按照我们一般的逻辑去分类思考了。
如果深度一样呢? 就变成一颗定长编码了,对吧?
假设深度不一样,则有些叶子深度大,有些叶子深度小。假如存在一棵优化树,则概率大的叶子肯定深度小,概率小的叶子肯定深度大,对吧?要不然就互换!
还是不知道该怎么构造树!想象中有一棵模糊的树,概率大的在上面,概率小的在下面。
有两个方向,也许我们可以针对最大的概率做些什么,也许可以针对最小的概率做些什么?
我们可以稍微缩小范围。现在假设有最小概率的两个叶子在下面f1,和f2。把这两个叶子用一个新的叶子替换,深度减小。那么
那么之前有若干个编码,f1,f2,。。。和fk换成了新的f1,f3,。。。fk。再加上两个概率的和。
就这样还能继续前进吗?这个公式有用吗?
我们继续把f1,f3,。。。fk按照这个逻辑一直进行下去,不就是解决方案吗?