python - 为什么标签排列会产生不同的霍夫曼代码?

标签 python algorithm huffman-code

我根据以下输入分布生成霍夫曼代码:

a = [(1,0.5),(0,0.25),(0,0.125),(0,0.125)]
b = [(0,0.5),(1,0.25),(0,0.125),(0,0.125)]

唯一的区别是 1 位于不同的 bin 中。

但是,当我使用以下函数对它们进行编码时:

def encode(symbfreq):
    tree = [[wt, [sym, ""]] for sym, wt in symbfreq]
    heapq.heapify(tree)
    while len(tree)>1:
        lo, hi = heapq.heappop(tree), heapq.heappop(tree)
        for pair in lo[1:]:
            pair[1] = '0' + pair[1]
        for pair in hi[1:]:
            pair[1] = '1' + pair[1]
        heapq.heappush(tree, [lo[0] + hi[0]] + lo[1:] + hi[1:])
    return sorted(heapq.heappop(tree)[1:], key=lambda p: (len(p[-1]), p))

我得到了不同的发行版代码字:

a = [[1, '1'], [0, '00'], [0, '010'], [0, '011']]

同时

b = [[0, '0'], [1, '11'], [0, '100'], [0, '101']]

为什么我会得到这种差异?

供引用:我需要将树分成左右分支(基于以 1 开头的左分支,右分支以 0 开头),以尝试找到 1。在第一种情况下,我的算法应该进行 1 次迭代,第二次进行 2 次迭代。但是,因为每次两个版本当前都进行 2 次迭代才能找到 1,所以每个 bin 返回的代码字都不相同 - 这不是我想要的!

最佳答案

尽管它们看起来不同,但这个结果都是正确的并且等效

您可以通过对 lohi 分支进行排序来使它们看起来相同,这样您始终可以通过替换以下内容将 1 添加到更大的分支:

lo, hi = heapq.heappop(tree), heapq.heappop(tree)

与:

lo, hi = sorted([heapq.heappop(tree), heapq.heappop(tree)], key=len)

结果

>>> encode(a)
3: [[1, '0'], [0, '10'], [0, '110'], [0, '111']]
>>> encode(b)
4: [[0, '0'], [1, '10'], [0, '110'], [0, '111']]

关于python - 为什么标签排列会产生不同的霍夫曼代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19709896/

相关文章:

.net - 如何生成反向等效字符串键? (获得降序排序)

java - 将位的字符串表示形式转换为字节

java - 哈夫曼树优先队列

java - 使用动态编程查找添加到特定数字的列表的所有集合

java - 查找哈夫曼树中节点的索引

python - Python Web 应用程序的数据库访问策略

python - 当与 uwsgi 一起使用时,redis 附加值而不是设置它

python - 如何在 Pandas 中连接 MultiIndex

python - 强制 matplotlib 图的背景透明

algorithm - 有什么比蛮力更好的解决方案呢?