编程之美——买书问题:贪心算法
生活随笔
收集整理的這篇文章主要介紹了
编程之美——买书问题:贪心算法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1 問題描述及分析 買書折扣問題的描述是,某出版社的《哈里波特》系列共有5卷,每本單賣都是8塊錢,如果讀者一次購買不同的k(k>=2)卷,就可以享受不同的折扣優惠,如下所示:
(2)下一步可選的書的種類多就能證明這個子問題比別的子問題更好?這點我不敢茍同,須知該問題的解決是一個多步選擇的過程,所以要得到這個結論就需要嚴格證明。如果這個條件不成立,那么書中給出的遞歸式也就不成立,即不能證明優化子結構性質成立。 作者計算了訂單中書的數量在[1-10]區間內,各種不同的選取方法所能獲得的最大折扣數:
表1-2 折扣計算表 但是,這里出現了一個違反貪心規則的地方,當我們要買8本書的時候,我們的選擇方式是5+3,其折扣 為5*0.25+3*0.10=1.55;而如果采用4+4的模式,則折扣數為2*4*0.20=1.6。 作者采用了改進的貪心算法,將所有5+3的組合全部替換成4+4的組合。 (由于書中的表述方式不清晰,甚至是錯誤,我將采用我自己的表達方法,例如:一組“4種不同卷”的組合,就表示這一組書由4本不同卷的書組成,<卷一,卷二,卷四,卷五>或者<卷一,卷二,卷三,卷五>) 按照書中的例子,X=(2,2,1,1,3), 我們將其轉換成Y的形式,則Y=(3,2,2,1,1)。 按照貪心策略,我們可以取出一組“5種不同卷”的組合,即Y5=1組,這時,Y=(2,1,1,0,0); 接下來,我們要取出“4種不同卷”的組合,發現條件不成立,不能取出一組不同的四卷書來,即Y4-Y5=1-1=0組; 但是,我們可以取出1組“3種不同卷”的組合,即Y3-Y4=2-1=1組,這時,Y=(1,0,0,0,0); 接下來,我們要取出“2種不同卷”的組合,發現條件不成立,不能取出一組不同的兩卷書來,即Y2-Y3=2-2=0組; 最后,我們還可以取出1組“1種不同卷”的組合,即Y1-Y2=3-2=1組。 這樣,我們對訂單中的9本書做出了如上的分組。 但是根據表1-2的反例,我們要做出一些調整,將所有的5+3組合換成4+4組合。“5種不同卷”有1組(Y5=1),“3種不同卷”有1組(Y3-Y4=2-1=1),因此K=min{Y5,Y3-Y4}=1。 這時,我們對訂單中的9本書所做出的分組就變成了: 5種不同卷 Y5-K=1-1=0
4種不同卷 Y4-Y5+2K=1-1+2=2
3種不同卷 Y3-Y4-K=2-1-1=0
2種不同卷 Y2-Y3=2-2=0
1種不同卷 Y1-Y2=3-2=1
?
問題是如果給定一個訂單,如何計算出最大的折扣數? 書中給出的動態規劃解法這里就不再贅述了。不過,里面有兩個問題需要單獨關注一下: (1)如果訂單描述為X:(X1,X2,X3,X4,X5),其中X1,X2,X3,X4,X5為所訂書的數量,其所在位置為卷的編號,即第一卷X1本,第二卷X2本,…,第5卷X5本,由于每本書的價格相同,所以折扣的多少僅僅在于如何選取而不在于究竟取那一卷書。我們將(X1,X2,X3,X4,X5)按照大小順序重新排列成為一個新的序列Y:(Y1,Y2,Y3,Y4,Y5),其中Y1≥Y2≥Y3≥Y4≥Y5。為什么要這樣排列呢?因為我們的關注點不在于第一卷書要買幾本,而在于,如何將這些書組合起來,使得組合后的優惠更多。(2)下一步可選的書的種類多就能證明這個子問題比別的子問題更好?這點我不敢茍同,須知該問題的解決是一個多步選擇的過程,所以要得到這個結論就需要嚴格證明。如果這個條件不成立,那么書中給出的遞歸式也就不成立,即不能證明優化子結構性質成立。 作者計算了訂單中書的數量在[1-10]區間內,各種不同的選取方法所能獲得的最大折扣數:
| 本數 | 可能的分解本數 | 對應的折扣 |
| 對于2-5本, 直接按折扣 購買 | 2 3 4 5 | 0.10.30.81.25 |
| 6 | =5+1 =4+2 =3+3 =2+2+2 | 1.25 0.9 0.6 0.3 |
| 7 | =5+2 =4+3 | 1.35 1.1 |
| 8 | =5+3 =4+4 =3+3+2 =2+2+2+2 | 5*25%+3*10%=1.55 4*20%+4*20%=1.6 0.7 0.4 |
| 9 | =5+4 =5+2+2 =4+3+2 =3+3+3 | 2.05 1.45 1.2 0.9 |
| 10 | =5+5 =4+4+2 =4+3+3 =2+2+2+2+2 | 2.5 1.7 1.4 0.5 |
4種不同卷 Y4-Y5+2K=1-1+2=2
3種不同卷 Y3-Y4-K=2-1-1=0
2種不同卷 Y2-Y3=2-2=0
1種不同卷 Y1-Y2=3-2=1
?
上述方法對于10本之內的情況適用。但是對于十本以上的情況呢?
作者想把多余10本的訂單分成 若干個小于10的訂單組,并把每組的最大折扣相加,以得到全局最優解,關于這一點我將在下面進行說明。 2 貪心算法是否適用的分析 貪心算法的適用有兩個必要條 件,即優化子結構和貪心選擇性。第一個性質由于已經證明可以適用動態規劃算法,所以優化子結構性質顯然成立(假如書中的動態規劃遞歸式成立的話)。現需要 證明其貪心選擇性,即如何“貪心”的進行選擇。顯然每次都查找最大的折扣數進行處理的貪心方法是行不通的,那么是貪心方法真的不行還是我們“貪”的不正確 呢?我們下面就來分析。 貪心選擇性的含義是,一個全 局最優解可以通過局部最優選擇來達到,換句話說,當考慮作何選擇時,我們只考慮對當前問題最佳的選擇而不考慮子問題的結果。貪心算法所做的當前選擇可能要 依賴于已經做出的所有選擇,但不依賴于有待于做出的選擇或子問題的解。所以,貪心策略通常是自頂向下地,一個一個地做出貪心選擇,不斷地將給定的問題歸約 為更小的問題。當然,在此之前我們必須證明在每一步所做的貪心選擇最終能產生一個全局最優解,這也正是本題的關鍵所在。 書中解法二給出的分組的思想是可以借鑒的,但是顯然犯了方向性的錯誤。因為貪心算法的關鍵在于“選擇”, 即從當前的狀態來“貪心地”從多種子狀態中選擇一個“當前的”最優解進行下去,并由其貪心選擇性而使最終的解剛好是最優解。既然書中最后采用的還是(經修 改后的)貪心算法,就不應該把整體的問題分成若干組來執行。這是因為貪心算法的上一次選擇與下一次選擇之間是帶有連續性的,并不能夠將它們拆開處理;而如 果要拆開處理之后再將結果相加,就還需要證明拆分是使得結果最優的拆分。所以我們的目標最終還是應該定為尋找如何“貪”!其實作者的意圖是對的,但實際目 標應該定為限制本次選擇對于此后選擇的影響,或使本次選擇的影響僅限于下一次選擇,這也是表格1-1只需要計算到10的原因(兩次選擇最多選擇10本書),但由于下一次選擇的影響可能會影響下下次的選擇,所以我們不能硬性將這些選擇拆開然后再相加,而只能一次一次地完成選擇。?
部分內容分析來自: http://www.kuqin.com/algorithm/20080417/6890.html轉載于:https://www.cnblogs.com/z-j-n-2015/p/5072417.html
總結
以上是生活随笔為你收集整理的编程之美——买书问题:贪心算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Struts2框架学习之七:避免表单重复
- 下一篇: 用HTTP协议连接网络(HttpURLC