【发布时间】:2013-11-26 17:07:19
【问题描述】:
我在使用霍夫曼树的搜索算法时遇到问题:对于给定的概率分布,我需要霍夫曼树是相同的,而不管输入数据的排列如何。
这是正在发生的事情与我想要的图片:
基本上我想知道是否可以保留从列表到树的项目的相对顺序。如果不是,为什么会这样?
作为参考,我使用霍夫曼树根据概率划分生成子组,以便我可以运行下面的 search() 过程。请注意,merge() 子例程中的数据与权重一起被合并。代码字本身不如树重要(应该保持相对顺序)。
例如,如果我生成以下霍夫曼代码:
probabilities = [0.30, 0.25, 0.20, 0.15, 0.10]
items = ['a','b','c','d','e']
items = zip(items, probabilities)
t = encode(items)
d,l = hi.search(t)
print(d)
使用以下类:
class Node(object):
left = None
right = None
weight = None
data = None
code = None
def __init__(self, w,d):
self.weight = w
self.data = d
def set_children(self, ln, rn):
self.left = ln
self.right = rn
def __repr__(self):
return "[%s,%s,(%s),(%s)]" %(self.data,self.code,self.left,self.right)
def __cmp__(self, a):
return cmp(self.weight, a.weight)
def merge(self, other):
total_freq = self.weight + other.weight
new_data = self.data + other.data
return Node(total_freq,new_data)
def index(self, node):
return node.weight
def encode(symbfreq):
pdb.set_trace()
tree = [Node(sym,wt) for wt,sym in symbfreq]
heapify(tree)
while len(tree)>1:
lo, hi = heappop(tree), heappop(tree)
n = lo.merge(hi)
n.set_children(lo, hi)
heappush(tree, n)
tree = tree[0]
def assign_code(node, code):
if node is not None:
node.code = code
if isinstance(node, Node):
assign_code(node.left, code+'0')
assign_code(node.right, code+'1')
assign_code(tree, '')
return tree
我明白了:
'a'->11
'b'->01
'c'->00
'd'->101
'e'->100
但是,我在搜索算法中所做的假设是,更有可能的项目被推向左侧:也就是说,我需要“a”才能拥有“00”代码字——无论'abcde' 序列的任何排列。一个示例输出是:
codewords = {'a':'00', 'b':'01', 'c':'10', 'd':'110', 'e':111'}
(请注意,即使“c”的代码字是“d”的后缀,也可以)。
为了完整起见,这里是搜索算法:
def search(tree):
print(tree)
pdb.set_trace()
current = tree.left
other = tree.right
loops = 0
while current:
loops+=1
print(current)
if current.data != 0 and current is not None and other is not None:
previous = current
current = current.left
other = previous.right
else:
previous = other
current = other.left
other = other.right
return previous, loops
它的工作原理是在一组 0 和 1 中搜索“最左边的”1 - 霍夫曼树必须将更多可能的项目放在左边。例如,如果我使用上面的概率和输入:
items = [1,0,1,0,0]
那么算法返回的项目的索引是 2 - 这不是应该返回的(应该是 0,因为它在最左边)。
【问题讨论】:
-
你所画的树并不是你所得到的。例如。左侧的树显示
d的值为 111,但d的值为 101。 -
@MarkAdler,对不起。我已经盯着这个看了3天,现在从下到上都说不出来。你会原谅一个小小的失误吗?
-
您的示例代码早期有
t = hi.encode(items),但未定义hi。这是什么? -
顺便说一句,你从我之前给你的代码中拿走了一些东西,现在这会非常有用:区分
Symbol节点和人工(内部)霍夫曼节点,和一个将符号名称映射到其Symbol节点的字典。拥有这两者会让你想要的现在或多或少简单明了。 -
@TimPeters 抱歉,应该是 t = encode(items)
标签: python data-structures huffman-code