霍夫曼编码和熵

曾经参加过一个面试,问题是有32只球队,每个球队获得冠军的概率不相同,给一种猜测冠军的方法,使得平均猜测的次数最少。

面试官靠我的是霍夫曼编码,但我本身不接触霍夫曼编码好多年,压根没想到这种方法(PS:由于面试官的个人喜好真的可能错过人才啊)。不过我想到了熵。把数据尽可能分成均匀的两份,一次递归,得到一个二叉树,就是最好的答案。关键是怎么样可以使得左右子树概率之和最接近?并且本次分的很平均并不能保证子树的子树也会分的很平均。例如,四个数:0.1,0.2,0.3,0.4。如果要保证局部熵最大,第一次划分应该是0.1和0.4一组,0.2和0.3一组。这样得到的结果是2,而霍夫曼编码得到的结果是1.9。可见并不能片面追求局部最优。可以考虑把这些数排序,排序后划分成子树,而子树也是排好序的,一次递归进行,得到结果和霍夫曼编码一样。

下面看一下算法的时间复杂度,第一次排序nlog(n),找到最佳划分是n,简单可以推算得到整棵树找到最佳的划分是0.5*nlog(n),所以算法复杂度是1.5*nlog(n)。

霍夫曼编码是从找最小的元素开始的找最下的两个元素时间复杂度是nlog2,递归进行,时间复杂度是n*(n-1)/2*log2。

改进的霍夫曼编码算法是也对初始化数组排序,时间复杂度是nlogn,找到最下的两个元素时间复杂度为1,但是对于找到的元素需要插入原来数组或者新建一个优先队列,每次找到的新元素要插入优先队列,队列操作的时间复杂度是mlogm,其中m是队列的长度。总共的时间复杂度也nlogn。

时间复杂度虽然相同,但是霍夫曼编码并没有基于熵的方法优美直观简单。

注:两种方法得到的树并不一样,但是最终的编码是一样的。

为什么结果是一样的?并不能给出证明。

为什么排序后的熵方法可行?而未排序的不可行?我的理解是这样的。直观的感觉是如果不排序,倾向于把最大的数和最小的数分在一个子树,通过上面的例子可以看出;而排序后倾向于相近的数分在一个子树。子树如果是相近的数更有利于子树的均匀划分;子树是不相近的数不利于子树的均匀划分。而熵方法需要各个子树尽可能均匀划分。暂时理解到这里,相信还可以更深入的挖掘。

 

你可能感兴趣的:(霍夫曼编码和熵)