日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python哈夫曼编码注意_Python 算法(2) 哈夫曼编码 Huffman Encoding

發(fā)布時間:2024/9/3 python 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python哈夫曼编码注意_Python 算法(2) 哈夫曼编码 Huffman Encoding 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這個問題原始是用來實現(xiàn)一個可變長度的編碼問題,但可以總結成這樣一個問題,假設我們有很多的葉子節(jié)點,每個節(jié)點都有一個權值w(可以是任何有意義的數(shù)值,比如它出現(xiàn)的概率),我們要用這些葉子節(jié)點構造一棵樹,那么每個葉子節(jié)點就有一個深度d,我們的目標是使得所有葉子節(jié)點的權值與深度的乘積之和$$\Sigma w{i}d{i}$$最小。

很自然的一個想法就是,對于權值大的葉子節(jié)點我們讓它的深度小些(更加靠近根節(jié)點),權值小的讓它的深度相對大些,這樣的話我們自然就會想著每次取當前權值最小的兩個節(jié)點將它們組合出一個父節(jié)點,一直這樣組合下去直到只有一個節(jié)點即根節(jié)點為止。如下圖所示的示例

代碼實現(xiàn)比較簡單,使用了heapq模塊,樹結構是用list來保存的,有意思的是其中zip函數(shù)的使用,其中統(tǒng)計函數(shù)count作為zip函數(shù)的參數(shù),

代碼實現(xiàn)比較簡單,使用了heapq模塊,樹結構是用list來保存的,有意思的是其中zip函數(shù)的使用,其中統(tǒng)計函數(shù)count作為zip函數(shù)的參數(shù),

from heapq importheapify, heappush, heappopfrom itertools importcountdefhuffman(seq, frq):

num=count()

trees= list(zip(frq, num, seq)) #num ensures valid ordering

heapify(trees) #A min-heap based on freq

while len(trees) > 1: #Until all are combined

fa, _, a = heappop(trees) #Get the two smallest trees

fb, _, b =heappop(trees)

n=next(num)

heappush(trees, (fa+fb, n, [a, b])) #Combine and re-add them

#print trees

return trees[0][-1]

seq= "abcdefghi"frq= [4, 5, 6, 9, 11, 12, 15, 16, 20]printhuffman(seq, frq)#[['i', [['a', 'b'], 'e']], [['f', 'g'], [['c', 'd'], 'h']]]

現(xiàn)在我們考慮另外一個問題,合并文件問題,假設我們將大小為 m 和大小為 n 的兩個文件合并在一起需要 m+n 的時間,現(xiàn)在給定一些文件,求一個最優(yōu)的合并策略使得所需要的時間最小。

如果我們將上面哈夫曼樹中的葉子節(jié)點看成是文件,兩個文件合并得到的大文件就是樹中的內(nèi)部節(jié)點,假設每個節(jié)點上都有一個值表示該文件的大小,合并得到的大文件上的值是合并的兩個文件的值之和,那我們的目標是就是使得內(nèi)部節(jié)點的和最小的合并方案,因為葉子節(jié)點的大小是固定的,所以實際上也就是使得所有節(jié)點的和最小的合并方案!

細想也就有了一個葉子節(jié)點的所有祖先節(jié)點們都有一份該葉子節(jié)點的值包含在里面,也就是說所有葉子節(jié)點的深度與它的值的乘積之和就是所有節(jié)點的值之和!可以看下下面的示例圖,最終我們知道哈夫曼樹就是這個問題的解決方案。

哈夫曼樹問題的一個擴展就是最優(yōu)二叉搜索樹問題,后者可以用動態(tài)規(guī)劃算法來求解

其他實現(xiàn)方式:

#Huffman Encoding

#Tree-Node Type

classNode:def __init__(self,freq):

self.left=None

self.right=None

self.father=None

self.freq=freqdefisLeft(self):return self.father.left ==self#create nodes創(chuàng)建葉子節(jié)點

defcreateNodes(freqs):return [Node(freq) for freq infreqs]#create Huffman-Tree創(chuàng)建Huffman樹

defcreateHuffmanTree(nodes):

queue=nodes[:]while len(queue) > 1:

queue.sort(key=lambdaitem:item.freq)

node_left=queue.pop(0)

node_right=queue.pop(0)

node_father= Node(node_left.freq +node_right.freq)

node_father.left=node_left

node_father.right=node_right

node_left.father=node_father

node_right.father=node_father

queue.append(node_father)

queue[0].father=Nonereturnqueue[0]#Huffman編碼

defhuffmanEncoding(nodes,root):

codes= [''] *len(nodes)for i inrange(len(nodes)):

node_tmp=nodes[i]while node_tmp !=root:ifnode_tmp.isLeft():

codes[i]= '0' +codes[i]else:

codes[i]= '1' +codes[i]

node_tmp=node_tmp.fatherreturncodesif __name__ == '__main__':#chars = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N']

#freqs = [10,4,2,5,3,4,2,6,4,4,3,7,9,6]

chars_freqs = [('C', 2), ('G', 2), ('E', 3), ('K', 3), ('B', 4),

('F', 4), ('I', 4), ('J', 4), ('D', 5), ('H', 6),

('N', 6), ('L', 7), ('M', 9), ('A', 10)]

nodes= createNodes([item[1] for item inchars_freqs])

root=createHuffmanTree(nodes)

codes=huffmanEncoding(nodes,root)for item inzip(chars_freqs,codes):print 'Character:%s freq:%-2d encoding: %s' % (item[0][0],item[0][1],item[1])

輸出結果:

>>>Character:C freq:2 encoding: 10100Character:G freq:2 encoding: 10101Character:E freq:3 encoding: 0000Character:K freq:3 encoding: 0001Character:B freq:4 encoding: 0100Character:F freq:4 encoding: 0101Character:I freq:4 encoding: 0110Character:J freq:4 encoding: 0111Character:D freq:5 encoding: 1011Character:H freq:6 encoding: 1110Character:N freq:6 encoding: 1111Character:L freq:7 encoding: 001Character:M freq:9 encoding: 100Character:A freq:10 encoding: 110

總結

以上是生活随笔為你收集整理的python哈夫曼编码注意_Python 算法(2) 哈夫曼编码 Huffman Encoding的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。