最近沒有怎么更新博客,因為一直比較忙。最近發現所里在做的一個項目中,可以抽出一部分內容和0-1背包問題、子集合加總問題非常相似(雖然表面上不容易看出相似點),所以看了一些這方面的資料和論文,這里主要對問題特點和算法思想做一些整理。
這類問題其實很有意思,做數學和做計算機的人都會研究,而且我這里將要提到的論文都是做計算機的人所寫的。
問題簡述
0-1 Knapsack Problem (0-1背包問題,下面簡稱KP)和Subset Sum Problem (子集合加總問題,下面簡稱SSP)是經典的NP完全問題。
兩個問題簡要描述如下:
KP:有n個物品要放入背包,第i個物品的價值為ci,占據體積為vi,背包的總容積為V,要選擇一部分物品放入背包,使得他們的總價值最大。對應的優化問題是
maxxi∑ci∗xi
s.t.∑vi∗xi≤V,xi∈{0,1}
這里xi代表是否選取第i個物品進背包,等於1就代表放入背包,等於0代表不放入背包。
SSP: 給一個集合{c1,c2,…,cn},還有一個目標值V,問能否選出一個子集,使得子集中元素求和剛好等於V。我們一般考慮的是他的另一種表述方式:選出一個子集,使得子集中元素求和不超過V,且盡量大。對應的優化問題是
maxxi∑ci∗xi
s.t.∑ci∗xi≤V,xi∈{0,1}
這里xi代表是否選入子集,等於1就是選入子集,等於0就是不選入子集。
SSP是KP的特殊情況,也即當ci=vi的時候,KP退化為SSP,從問題式子上看,也完全一樣了。
盡管如此,研究了KP不代表就不用研究SSP了,后面會說明這一點。
精確算法與近似算法
這兩個問題都有很簡單的動態規划算法可以精確求解,但可惜算法的時間復雜度是偽多項式的,也即和V相關,但V不是問題輸入數據的規模,n才是。在ACM競賽等算法比賽中,經常會遇到一些問題屬於KP的變種,而偽多項式算法也就足夠了。由於網上資料很多,而且難度不大,這里就不詳細介紹了。如果你不知道,請你搜索“動態規划求解0-1背包問題”。
這里我們更關心多項式近似算法,也即PTAS(Polynomial Time Approximation Scheme),也即對任意給定的ϵ,算法可以在關於n的多項式時間內求得一個解,且該解和真實最優解的最多相差ϵ倍。
實際上這兩個問題都有FPTAS(Fully PTAS)算法,也即時間復雜度不僅要是n的多項式,而且還要是1ϵ的多項式。
KP的近似算法
KP有非常簡單的近似算法。
對任意ϵ,令P=maxici,K=ϵ∗Pn,記c′i=⌊ciK⌋ (這里⌊⋅⌋表示向下取整)
則使用c′i代替ci求0-1背包問題,求得的x即為ϵ近似解。這是因為每一個物品由於取整而產生的誤差都很小。
而這時候,由於c′i都是整數,可以使用動態規划算法求解,容易算得動態規划的狀態數至多n⌊PK⌋個,因此整個算法的時間復雜度為O(n2⌊PK⌋)=O(n2⌊nϵ⌋),
算法復雜度之所以能夠達到多項式,是由於取整減小了動態規划的狀態數,而K的出現是為了控制因取整而產生的誤差,K足夠小的時候就能保證解的相對誤差不會超過ϵ
此算法參考 Vijay V. Vazirani寫的書 Approximation Algorithms(點擊下載) , 第8.1,8.2章節(第69頁-70頁)
雖然這不一定是最快的多項式近似算法,但暫時沒看到別的算法在任何情況下復雜度都能更低。
我自己也沒有想到更好的。而有趣的是我最近在思考另一個等價的問題,但在發現等價性之前,我也想出了一個思路幾乎相同,復雜度完全一致的算法。現在看來,其實本質是同一個算法。
SSP的近似算法
根據前面所述,SSP是KP的特殊情況。所以KP的近似算法就可以認為是SSP的近似算法了。但是,之所以單獨考慮SSP,是因為他可以求得更快。
SSP也有思路非常類似的算法,可以在一些國外的教學資料上看到。如這一篇(點擊下載)。但是時間復雜度都比較高,事實上,SSP有O(min{nϵ,n+1ϵ2log(1ϵ)})的算法。我認為這個結論是比較漂亮的,復雜度嚴格比上面提到的KP的算法要低,而且低很多。
為了說明算法思想,我們先再深入理解一下前面的算法。
前面的算法是用取整來控制復雜度,取整的本質事實上是將狀態空間划分成若干段,每一段只取一個端點作為“代表”,這樣狀態數就會是多項式的,總的算法復雜度也就是多項式的。在SSP中,我們可以不事先取整,但仍然將狀態空間分段,讓每個段記錄兩個數值(也即選兩個“代表”),一個是落在該段上的最小子集和(最小代表),一個是落在該段上的最大子集和(最大代表)。這樣我們的狀態數相當於比前面KP的算法多了一倍,而且是需要動態維護的,但是由於誤差控制的更好(極端的例子是如果集合只有一個數,這么做就沒有誤差),沒有取整那么大的誤差,所以不需要分那么多段就能保證解的相對誤差不超過ϵ,因此最終算法復雜度會低。
此算法參考 Hans Kellerer等人的論文 An efficient fully polynomial approximation scheme for the Subset-Sum Problem (點擊查看) Journal of Computer and System Sciences 66 (2003) 349–370
可以發現,這個算法是不能簡單推廣到0-1背包問題上的。
SSP的拓展問題——ISSP
Anshul Kothari等人在2005年研究Uniform-Price Auction Clearing(其實我也不知道這是啥問題)的論文中提出了Interval Subset Sum Problem (下面簡稱ISSP),他是SSP的一個推廣。這個問題沒有前面的問題這么有名(事實上我沒看到第二篇論文討論這個問題),但剛好我也發現了另外一個實際問題可以抽象成這個模型,所以我覺得還是很有意義的。問題簡要描述如下:
給定n個區間[ai,bi],對每個區間可以選擇上面的一個數,也可以什么都不選,使這些數的和不超過目標值V,且盡量接近。對應的優化問題是
maxxi,yi∑yi∗xi
s.t.∑yi∗xi≤V,xi∈{0,1},yi∈[ai,bi]
至少從形式上看,他不再是線性的了,而且當ai=bi時退化為SSP。所以似乎更難了。
實際上這個問題也能改寫為線性模型。
maxxi,yi∑yi
s.t.∑yi≤V,xi∈{0,1},yi∈[xi∗ai,xi∗bi]
從直觀上看,如果ai很小,bi–ai很大,這個問題似乎很容易解。我已經可以給出看上去不是太強的條件,在該條件下,ISSP是多項式可解的,具體這里就不給出了。但無論如何,In general,ISSP也是NP難問題。
Anshul Kothari等人的論文中也給出了一個FPTAS算法,比較有趣的是,這個算法和上面的SSP的算法思想是一致的,時間復雜度也是一致的。因此這一算法應當是受到上面所述的SSP的算法啟發而設計的,而且是一個比較簡單的推廣。
此ISSP算法參考論文為 Interval Subset Sum and Uniform-Price Auction Clearing (點擊查看) Computing and Combinatorics, Lecture Notes in Computer Science Volume 3595, 2005, pp 608-620
一些啟示
1,SSP是KP的一個特殊情況,但是他們的近似算法復雜度卻可以完全不同,這說明特殊問題可以有特殊算法。使用General的算法是可以的,但需要仔細想想問題是否有特殊的地方沒發現,是否有更具針對性的算法沒找到。
2,ISSP是SSP的一個推廣,也即SSP是ISSP的特殊情況。但事實上ISSP並沒有更難,甚至某些時候很可能有多項式算法,這說明推廣了,也有可能變簡單,特殊情況也有可能更難。但是特殊情況的算法思想可以借鑒用來解決推廣了的問題。