資料結構與演算法 演算法思想 貪心演算法

2021-10-23 20:36:08 字數 2510 閱讀 3136

貪心演算法

回溯演算法

分治演算法

動態規劃

四種基本的演算法思想:貪心演算法,分治演算法,回溯演算法,動態規劃,他們不是具體演算法,常用來指導我們設計具體的演算法和編碼等。

霍夫曼編碼(huffman coding),prim和kruskal最小生成數演算法,dijkstra單源最短路徑演算法。

假設我們有乙個可容納100kg物品的揹包,可以裝下各種物品,我們有以下5中豆子,每種豆子的總量和總價值都各不相同。為了讓揹包中所裝物品的總價最大,該如何?

第一步:當我們看到這類問題時,首先要聯想到貪心演算法:針對一組資料,定義了限制值和期望值,系統從中選出幾個資料,在滿足限制值的情況下,期望值最大。

第二步:嘗試看這個問題是否可以用貪心演算法解決:每次選擇當前情況下,在對限制值同等貢獻量的情況下,對期望值貢獻最大的資料

第三步:舉幾個例子看下貪心演算法產生的結果是否最優的。大部分情況下,舉幾個例子驗證一下就可以了。嚴格的證明貪心演算法的正確性,非常複雜,需要涉及較多的數學推理。並且,從實踐的角度來說,大部分能用貪心演算法的問題,貪心演算法的正確性都是顯而易見的,月不需要嚴格的數學推導證明。

貪心演算法,專注於當下最優,但可能無法取得全域性最優。

一:分糖果

有m個糖果和n個孩子,但m可將這個問題抽象成:從n個孩子中抽取一部分孩子分配糖果,讓滿足的孩子個數(期望值)是最大的。這個問題的限制值就是糖果個數m。

對於乙個孩子而言,如果小的糖果可以滿足,我們就沒必要用更大的糖果,這樣更大的就可以留給其他對糖果大小需求更大的孩子。另一方面,對糖果大小需求小的孩子更容易被滿足,所以,我們可以從需求小的孩子開始分配他糖果。因為滿足乙個需求大的孩子跟滿足乙個需求小的孩子,對我們期望值貢獻是一樣的。

二:錢幣找零(部分題目不適用 100 99 1 找396 )

假設有1元,2元,5元,10元,50元,100元這些面額的紙幣,他們的張數分別是c1,c2,c5,c10,c20,c50,c100。我們要有支付k元,最少要用多少張紙幣呢?

在貢獻相同期望值(紙幣數目)的情況下,我們希望多貢獻點金額,這樣就可以讓紙幣數更少。這就是一種貪心演算法的解決思路。

三:區間覆蓋

假設有n個區間,區間的起始端點和結束端點分分別是[l1,r1],[l2,r2],[l3,r3]……,從n個區間中選出一部分區間,這部分區間滿足兩兩不相交(端點相交的情況不算相交),最多能選出多少個區間?

我們假設這 n 個區間中最左端點是 lmin,最右端點是 rmax。這個問題就相當於,我們選擇幾個不相交的區間,從左到右將[lmin, rmax]覆蓋上。我們按照起始端點從小到大的順序對這 n 個區間排序。

我們每次選擇的時候,左端點跟前面的已經覆蓋的區間不重合的,右端點又盡量小的,這樣可以讓剩下的未覆蓋區間盡可能的大,就可以放置更多的區間。這實際上就是一種貪心的選擇方法。

四:如何用貪心演算法實現霍夫曼編碼?

假設有乙個包含1000個字元的檔案,每個字元佔1個byte(1byte=8bits),儲存這1000個字元就一共需要8000bits。

但使用霍夫曼編碼,可實現壓縮率在20%~90%之間。

霍夫曼編碼不僅會考察文字彙總有多少個不同字元,還會考察每個字元出現的頻率,根據頻率的不同,選擇不同長度的編碼。霍夫曼編碼試圖用這種不等長的編碼方法,來進一步增加壓縮的效率。

根據貪心的思想,可以把出現頻率比較多的字元,用稍微短一些的編碼;出現頻率比較少的字元,用稍微長一些的編碼。

由於霍夫曼編碼是不等長的,每次應該讀取1為還是2位,3位等來解壓縮是個問題,這個問題導致霍夫曼編碼解壓縮比較複雜。

為了避免解壓縮過程中的歧義,霍夫曼編碼要求各個字元的編碼之間,不會出現某個編碼是另乙個編碼字首的情況。

假設這6個字元出現的頻率從高到低依次是a,b,c,d,e,f。我們把它們編碼下面這個樣子,任何乙個字元的編碼都不是另乙個的字首,在解壓縮的時候,我們每次會讀取盡可能長的可解壓縮的二進位制,所以在解壓縮的時候也不歧義。

根據字元出現頻率的不同,給不同的字元進行不同長度的編碼的實現方式

把每個字元看作乙個節點,並且輔帶著把頻率放到優先順序佇列中。從佇列中取出頻率最小的兩個節點a,b,然後新建乙個節點c,把頻率設定為兩個節點的頻率之和,並把這個新節點c作為節點a,b的父節點。最後再把c節點放入到優先順序佇列中。重複這個過程,直到佇列中沒有資料。

給每一條邊畫上乙個權值,指向左子節點的邊,我們統統標記為0,指向右子節點的邊,我們統統標記為1,那從根節點到葉節點的路徑就是葉節點對應字元的霍夫曼編碼

資料結構與演算法 貪心演算法

1 給定 n 種物品和乙個揹包,物品 i 的重量是 w i 其價值是 p i 揹包的容量為 c。設物品已按單位重量價值遞減的次序排序。每種物品不可以裝入揹包多次,但可以裝入部分的物品 i。揹包問題是選擇裝入揹包中的物品,在不超過揹包容量的前提下使揹包的得總價值最大。用貪心法設計與實現乙個演算法,求解...

資料結構與演算法 貪心演算法

定義每個古董重量 揹包問題 在對問題求解時,總是作出在當前看來是最好的選擇。也就是說,不從整體上加以考慮,它所作出的僅僅是在某種意義上的區域性最優解 是否是全域性最優,需要證明 有一天海盜們截獲了一艘裝滿各種各樣古董的貨船,每一件都價值連城,一旦打碎就是去了價值,海盜船載重量為c,每件固定的重量為w...

資料結構與演算法 貪心演算法

有如下場景 針對一組資料,我們定義了限制值和期望值,希望從中選出幾個資料,在滿足限制值的情況下,期望值最大。為了達到上述目的,貪心演算法是其中的乙個解決方案。例如,路徑選擇問題,從 s 城市至 e 城市,在只能路過 2 個城市的情況下,如何走的最短,如下圖所示 英文全稱 greedy algorit...