1. 程式人生 > >2018.3.1-2 huffman code and dynamic programming

2018.3.1-2 huffman code and dynamic programming

可能 空間 blog 線圖 bottom div 多重 很多 基礎

這周先是huffman code,這東西是一種對數據進行二進制編碼的方式,這樣子編碼可以壓縮空間,算是一種壓縮算法。比如一串數據裏只有a,b,c,d四個字節,一般可能會覺得就00,01,10,11來指代這四個了,然而這裏可能a出現的概率超過60%,其余三個都是百分之十幾,那麽像0,10,110,111這種編碼就更好一些。構造赫夫曼編碼的方式算是一種貪心算法,實際上是一個構造二叉樹的過程,實際就是先找出出現概率最低的兩個點,把它們作為最底層的葉子,然後合並它們的概率,再把它們當做一個點與其他點比較,重復這一過程。實際上我隱約記得離散數學裏面好像講過類似的東西,不過當時是完全不知道這是用來幹啥的。

然後是dynamic programming,這是一種算法思想,和二分法或者貪心算法對應的,他基本是一個求最優解的方法,通常涉及到1.搞清楚一個最優解的結構特征。2.以這個結構特征制定方案,遞歸這個方案。3.求最優解的值,通常是bottom-up的求以避免重復計算。其實挺抽象的,不是太好理解。需要結合具體例子來理解。

光頭哥講的dynamic programming的栗子是一個“求一個直線圖的不相臨點(每個點都帶一個權值)的最大權值之和”的問題。我最開始還以為他說的不相鄰的點只能是兩個點,想了半天都沒想明白他的算法是幹啥的,後來才發現原來是所有可能的不相鄰點都算在裏面的。。。這裏具體算法就是:把問題分為兩種可能性,一種的最優點集是包括最後一個結點(是指這個一串直線排列的圖的最右邊的結點),那麽倒數第二個結點就不包括,那就對排除最右兩個結點的圖遞歸求解;另一種是不包括最後一個結點,那麽對除最後一個點的圖遞歸求解。最後比較這兩種可能性得出的結果哪個更大,就選取哪個。基本上肯定是一個結果有最後一個點,一個沒有,就是按這個區分的。

不過這樣的解法,是up-bottom,就有很多重復求值,實際上還是brutal的。優化的辦法是把它顛倒過來變成bottom-up,從左向右開始求,先求最左邊0個結點和1個結點的最大權值之和,然後向右推進,這樣相當於是cach了每一步的結果用於下一步的計算的,就快了很多,只有O(n)了。

當然這樣也只能求出最大權值之和,後面還有進一步求出具體的點集的方法。是要在上一步基礎之上,先cach了每一步的結果,然後再從右向左判斷最開始講的那兩種可能是實際是哪種(就是比較兩種可能性的權值之和的大小),然後判斷每一步的結點(最開始是最右邊的)在不在點集之內。

說實話這算法感覺。。。真的很難。而且過於具體了,感覺不是特別有普適性,學了之後對dynamic programming好像理解也沒有更深入(-_-||),總感覺最近光頭哥講的東西越來越變態了。。。

另一門課開始啦——duke的sql,過兩天deadline,先上完第一周的,正好換換腦子~

2018.3.1-2 huffman code and dynamic programming