目錄
- 1.問題描述
1.1 問題描述
1.2 問題的數(shù)學(xué)表示(規(guī)劃類問題想幻,此種表示可以轉(zhuǎn)換為回溯法)
1.3 三種方法的比較 - 2.動(dòng)態(tài)規(guī)劃
2.1 刻畫一個(gè)最優(yōu)解的結(jié)構(gòu)特征(最優(yōu)子結(jié)構(gòu))
2.2 遞歸地定義最優(yōu)解的值(重疊子問題)
2.3 計(jì)算最優(yōu)解的值,通常采用自底向上的方法
2.4 利用計(jì)算出的信息構(gòu)造一個(gè)最優(yōu)解 - 3.回溯法
3.1 01背包問題的數(shù)學(xué)描述
3.2 用回溯法搜索解空間
3.3 一個(gè)示例 - 4.分支限界法
4.1 分支限界法解決0-1背包問題
4.2 一個(gè)示例 - 5.可以轉(zhuǎn)換為0-1背包問題的雙核問題
5.1 題目描述
5.2 轉(zhuǎn)化為背包問題
1.問題描述
1.1 問題描述
假定n個(gè)商品重量分別為w0, w1, ..., wn-1食店,價(jià)值分別為p0, p1, ..., pn-1吉嫩,背包載重量為M自娩。怎樣選擇商品組合,使得價(jià)值最高?
1.2 問題的數(shù)學(xué)表示(規(guī)劃類問題荠锭,此種表示可以轉(zhuǎn)換為回溯法)
- 假設(shè)xi表示商品i被裝入背包的情況证九,xi = 0,1愧怜。根據(jù)題目要求拥坛,有如下約束方程和目標(biāo)函數(shù):
- 問題歸結(jié)為尋找一個(gè)滿足上述約束方程并使目標(biāo)函數(shù)達(dá)到最大的解向量X = (x1, x2, ..., xn)丸氛。
1.3 三種方法的比較
- 動(dòng)態(tài)規(guī)劃通過最優(yōu)子結(jié)構(gòu)缓窜,將問題轉(zhuǎn)換為子問題的求解。轉(zhuǎn)換的過程中恩掷,涉及到某個(gè)具體的商品是否選擇的問題螃成。
- 回溯法根據(jù)數(shù)學(xué)表達(dá)式寸宏,搜索解向量(x1, x2, ..., xn)的整個(gè)解空間
搜索的時(shí)候利用貪心性質(zhì)(按照單位重量?jī)r(jià)值遞減排序氮凝,估算可能的最高上界)罩阵、以及已經(jīng)計(jì)算出的可行解作為界限進(jìn)行剪枝。
但是回溯法傅是,原則上要窮盡所有可能喧笔,只不過是對(duì)有些分支提前返回了书闸。 - 分支限界法
剪枝方法同回溯法是一樣的:利用貪心性質(zhì)(按照單位重量?jī)r(jià)值遞減排序嫌术,估算可能的最高上界)蛉威、以及已經(jīng)計(jì)算出的可行解作為界限進(jìn)行剪枝蚯嫌。
唯一的不同是择示,分支限界法利用的是優(yōu)先隊(duì)列,并且谈秫,當(dāng)針對(duì)一個(gè)結(jié)點(diǎn)進(jìn)行擴(kuò)展時(shí)拟烫,會(huì)將所有兒子結(jié)點(diǎn)進(jìn)行展開,計(jì)算出所有兒子結(jié)點(diǎn)所能達(dá)到的最高上界置媳。因此拇囊,當(dāng)一個(gè)優(yōu)先隊(duì)列中首結(jié)點(diǎn)是一個(gè)可行解寂拆,則結(jié)束鬓长。 - 因此涉波,可以看出回溯法與分支限界法的本質(zhì)不同是在于搜索解空間的遍歷方式不同。
回溯法是深度優(yōu)先惭聂,要窮盡解空間的所有可能,找到最優(yōu)解耕腾。
分支限界法是廣度優(yōu)先扫俺,本質(zhì)上也是窮盡了解空間的所有可能,找到最優(yōu)解疗琉。
2.動(dòng)態(tài)規(guī)劃
2.1 刻畫一個(gè)最優(yōu)解的結(jié)構(gòu)特征(最優(yōu)子結(jié)構(gòu))
- 假設(shè)01背包問題的一個(gè)最優(yōu)解為S,其中i為序號(hào)最大的商品犯戏;
那么S' = S - {i}必然是M - wi的最優(yōu)解
證明方法可以采用cut-paste方法進(jìn)行證明
2.2 遞歸地定義最優(yōu)解的值(重疊子問題)
- 定義c[i, w]為商品1,....,i送火,最大重量為w的最優(yōu)解(最大價(jià)值)。那么就有以下兩種情況:
- 如果wi > w先匪,c[i, w]轉(zhuǎn)化為求解一個(gè)子問題c[i-1, w]种吸;
- 如果wi ≤ w,c[i, w]轉(zhuǎn)換成了求解兩個(gè)子問題:
一個(gè)包含商品i呀非,pi + c[i-1, w- wi];
一個(gè)不包含商品i岸裙,c[i-1, w]猖败;
兩種情況中的較大者即為c[i, w] - (重疊子問題)很顯然c[i-1, w-wi]與c[i-1, w]有重疊子問題。
2.3 計(jì)算最優(yōu)解的值降允,通常采用自底向上的方法
-
如下動(dòng)態(tài)規(guī)劃方法的運(yùn)行時(shí)間為Θ(nM)
2.4 利用計(jì)算出的信息構(gòu)造一個(gè)最優(yōu)解
- 如果c[i, w] = pi + c[i-1, w-wi]恩闻,則i是答案的一部分;否則便不是剧董。
3.回溯法
3.1 01背包問題的數(shù)學(xué)描述
- 假設(shè)xi表示商品i被裝入背包的情況幢尚,xi = 0,1破停。根據(jù)題目要求,有如下約束方程和目標(biāo)函數(shù):
- 問題歸結(jié)為尋找一個(gè)滿足上述約束方程并使目標(biāo)函數(shù)達(dá)到最大的解向量X = (x1, x2, ..., xn )尉剩。
3.2 用回溯法搜索解空間
3.2.1 解空間
- 很顯然真慢,解空間為一棵高度為n的完全二叉樹。所有解的可能性為所有的葉子節(jié)點(diǎn)理茎,總共有2n種黑界。
3.2.2 剪枝的方法(根據(jù)約束條件和bound來進(jìn)行剪枝)
- 上界bound = 0
- 假定第i層左兒子表示商品i被裝入背包,右兒子表示未被裝入背包
- 將物體按照價(jià)值重量比的非增順序排序功蜓,然后按照這個(gè)順序搜索园爷,在搜索過程中,盡量沿著左兒子繼續(xù)前進(jìn)式撼。
- 當(dāng)不能沿著左兒子繼續(xù)前進(jìn)時(shí)童社,得到問題的一個(gè)部分解,并把搜索轉(zhuǎn)移到右子樹著隆。此時(shí)扰楼,估計(jì)由這個(gè)部分解所能得到的最大價(jià)值,把該值與當(dāng)前的上界進(jìn)行比較美浦,如果高于上界弦赖,就繼續(xù)在右子樹上搜索,知道找到一個(gè)可行解浦辨,用可行解的值刷新上界bound蹬竖。
- 向上回溯,尋找其他可行解流酬。如果部分解所估計(jì)的最大值小于當(dāng)前的上界币厕,就丟棄當(dāng)前正在搜索的部分解,直接向上回溯芽腾。
最大值的估算法(跟分支限界法本質(zhì)上是一樣的)
- 假定當(dāng)前解是{x0, x1, ..., xk-1 }
向上回溯的方法
- 如果當(dāng)前的結(jié)點(diǎn)是左兒子分支結(jié)點(diǎn)旦装,就轉(zhuǎn)而搜索相應(yīng)的右兒子分支結(jié)點(diǎn);
- 如果當(dāng)前的結(jié)點(diǎn)是右兒子分支結(jié)點(diǎn)摊滔,就沿著右兒子分支結(jié)點(diǎn)向上回溯阴绢,知道左兒子分支結(jié)點(diǎn)為止,然后再轉(zhuǎn)而搜索相應(yīng)的右兒子分支結(jié)點(diǎn)
3.2.3 回溯法的步驟描述
w_cur——表示當(dāng)前正在搜索的部分解中轉(zhuǎn)入的總重量
p_cur——當(dāng)前總價(jià)值
p_est——部分解可能達(dá)到的最大價(jià)值的估計(jì)值
p_total——當(dāng)前搜索到的所有可行解中的最大價(jià)值艰躺,是當(dāng)前目標(biāo)函數(shù)的上界
yk呻袭、xk——部分解的第k個(gè)分量及其副本
k——表示當(dāng)前搜索深度
- step1.按商品價(jià)值重量比的非增排序排序
- step2.w_cur、p_cur和p_total初始化為0腺兴,把部分解初始化為空棒妨,k=0
- step3.從當(dāng)前的部分解可取得的最大價(jià)值p_est
- step4.若p_est > p_total,轉(zhuǎn)step5;否則券腔,轉(zhuǎn)step8
- step5.從vk開始把商品裝入背包,直到?jīng)]有商品可裝貨裝不下vi為止拘泞,并生成部分解yk, ..., yi纷纫,k ≤ i < n,刷新p_cur
- step6.如果i ≥ n陪腌,得到一個(gè)新的可行解辱魁,把所有的yi復(fù)制給xi,p_total = p_cur诗鸭,p_total是目標(biāo)函數(shù)的新界染簇;令k = n,轉(zhuǎn)step3强岸,以便回溯搜索其他的可能解
- step7.否則锻弓,得到一個(gè)部分解,令k=i+1蝌箍,舍棄商品vi青灼,從商品vi+1繼續(xù)裝入,轉(zhuǎn)step3.
- (回溯)step8.當(dāng)i ≥ 0且yi為0時(shí)妓盲,執(zhí)行i = i -1杂拨,直到y(tǒng)i ≠ 0為止;即沿右兒子分支結(jié)點(diǎn)方向回溯悯衬,直到左兒子分支結(jié)點(diǎn)弹沽。
- step9.如果i < 0,算法結(jié)束筋粗,否則策橘,轉(zhuǎn)step10
- step10.令yi = 0,w_cur = w_cur - wi, p_cur = p_cur - pi, k = i + 1亏狰,轉(zhuǎn)step3役纹;從左兒子分支結(jié)點(diǎn)轉(zhuǎn)移到相應(yīng)的右兒子分支結(jié)點(diǎn),繼續(xù)搜索其他的部分解或可能解暇唾。
3.3 一個(gè)示例
M = 50
商品重量分別為5,15,25,27,30
商品價(jià)值分別為12,30,44,46,50
上面已經(jīng)按照單位重量?jī)r(jià)值遞減順序排列促脉。
4.分支限界法
4.1 分支限界法解決0-1背包問題
- 按價(jià)值重量比 遞減 的順序,對(duì)n個(gè)商品進(jìn)行排序
排序后商品序號(hào)的結(jié)合為S = {0, 1, ..., n-1} - 將這些商品分為3個(gè)集合:
S1——選擇裝入背包的商品集合
S2——不選擇裝入背包的商品集合
S3——尚待選擇的商品集合 - S1(k)策州、S2(k)瘸味、S3(k)分別表示在搜索深度為k時(shí)的3個(gè)集合中的商品。開始時(shí)有:
S1(0) = ?
S2(0) = ?
S3(0) = {0, 1, ..., n-1}
4.1.1 分支方法(二叉分支)
- 假設(shè)比值pi/wi最大的商品序號(hào)為s(s ∈ S3)够挂,用s進(jìn)行分支旁仿,一個(gè)分支結(jié)點(diǎn)表示把商品s裝入背包,另一個(gè)分支結(jié)點(diǎn)表示不把商品s裝入背包。
當(dāng)商品按照價(jià)值重量比遞減排序后枯冈,s就是集合S3(k)中的第一個(gè)元素毅贮。特別地,當(dāng)搜索深度為k時(shí)尘奏,商品s的序號(hào)就是集合S中的元素k滩褥。 -
把商品s裝入背包的分支結(jié)點(diǎn)
S1(k+1) = S1(k) ∪ {k}
S2(k+1) = S2(k)
S3(k+1) = S3(k) - {k} -
不把商品s裝入背包的分支結(jié)點(diǎn)
S1(k+1) = S1(k)
S2(k+1) = S2(k) ∪ {k}
S3(k+1) = S3(k) - {k}
4.1.2 上界估算方法(按照單位價(jià)值最大進(jìn)行貪心選擇)
- 假定b(k)表示在搜索深度為k時(shí),某個(gè)分支結(jié)點(diǎn)的背包中商品的價(jià)值上界炫加。
此時(shí)S3(k) = {k, k+1, ..., n-1}瑰煎。用如下方法計(jì)算兩種分支結(jié)點(diǎn)背包中商品價(jià)值的上界:
- 上述公式的理解
1)按照一個(gè)商品是否加入到S1集合,總共有2n個(gè)葉子節(jié)點(diǎn)俗孝,每個(gè)葉子節(jié)點(diǎn)對(duì)應(yīng)一種情況
2)當(dāng)一層一層向下搜索是酒甸,如果當(dāng)前S1集合中的總重量超過了載重量M,則直接將b(k)置為0赋铝,該分支終止插勤。
為什么這樣做?因?yàn)樵谒阉魃弦粚訒r(shí)柬甥,該商品不應(yīng)該加入到S1集合饮六,這種不加入該商品情況對(duì)應(yīng)于另一個(gè)分支。加入該商品的此分支已經(jīng)不滿足要求了苛蒲,所以剪枝卤橄。
4.1.3 分支限界法求解步驟
每個(gè)結(jié)點(diǎn)都包含如下信息:
??S1——當(dāng)前選擇裝入背包的商品集合
??S2——當(dāng)前不選擇裝入背包的商品集合
??S3——當(dāng)前尚待選擇的商品集合
??k——搜索深度
??b——上界
bound——一個(gè)可行解的取值,當(dāng)做剪枝的標(biāo)準(zhǔn)
- step1.bound = 0臂外,把商品按價(jià)值重量比遞減排序
- step2.建立根節(jié)點(diǎn)X
X.b = 0
X.k = 0
X.S1 = ?
X.S2 = ?
X.S3 = S - step3. 若X.k == n窟扑,算法結(jié)束,X.S1即為裝入背包中的物體漏健,X.b即為裝入背包中物體的最大價(jià)值嚎货;
否則轉(zhuǎn)向step4 - (分支1)step4.建立結(jié)點(diǎn)Y
Y.S1 = X.S1 ∪ {X.k}
Y.S2 = X.S2
Y.S3 = X.S3 - {X.k}
Y.k = X.k + 1
計(jì)算Y.b,將Y.b與bound進(jìn)行比較蔫浆,據(jù)此判定是否插入優(yōu)先隊(duì)列;當(dāng)S3為空時(shí)瓦盛,找到一個(gè)可行解洗显,判定是否更新bound。 - (分支2)step5.建立結(jié)點(diǎn)Z
Z.S1 = X.S1
Z.S2 = X.S2 ∪ {X.k}
Z.S3 = X.S3 - {X.k}
Z.k = Z.k + 1
計(jì)算Z.b原环,將Z.b與bound進(jìn)行比較挠唆,據(jù)此判定是否插入優(yōu)先隊(duì)列;當(dāng)S3為空時(shí)嘱吗,找到一個(gè)可行解玄组,判定是否更新bound。 - step6.取出優(yōu)先隊(duì)列首元素作為結(jié)點(diǎn)X,轉(zhuǎn)向step3
4.2 一個(gè)示例
-
有5個(gè)商品俄讹,重量分別為8,16,21,17,12哆致,價(jià)值分別為8,14,16,11,7,背包的載重量為37患膛,求裝入背包的商品及其價(jià)值沽瞭。
5.可以轉(zhuǎn)換為0-1背包問題的雙核問題
5.1 題目描述
一種雙核CPU的兩個(gè)核能夠同時(shí)的處理任務(wù),現(xiàn)在有n個(gè)已知數(shù)據(jù)量的任務(wù)需要交給CPU處理剩瓶,假設(shè)已知CPU的每個(gè)核1秒可以處理1kb,每個(gè)核同時(shí)只能處理一項(xiàng)任務(wù)城丧。n個(gè)任務(wù)可以按照任意順序放入CPU進(jìn)行處理延曙,現(xiàn)在需要設(shè)計(jì)一個(gè)方案讓CPU處理完這批任務(wù)所需的時(shí)間最少,求這個(gè)最小的時(shí)間
輸入描述:
輸入包括兩行: 第一行為整數(shù)n(1 ≤ n ≤ 50) 第二行為n個(gè)整數(shù)length[i](1024 ≤ length[i] ≤4194304)亡哄,表示每個(gè)任務(wù)的長(zhǎng)度為length[i]kb枝缔,每個(gè)數(shù)均為1024的倍數(shù)。
輸出描述:
輸出一個(gè)整數(shù)蚊惯,表示最少需要處理的時(shí)間
輸入例子:
5 3072 3072 7168 3072 1024
輸出例子:
9216
5.2 轉(zhuǎn)化為背包問題
- 最小時(shí)間的意思即兩個(gè)核同時(shí)滿負(fù)荷運(yùn)行愿卸,并且當(dāng)兩個(gè)核所處理的任務(wù)量都接近于總?cè)蝿?wù)量M的一半時(shí),時(shí)間最少
- 因此題目轉(zhuǎn)換為:對(duì)于其中一個(gè)核截型,假設(shè)其任務(wù)量為上限M/2趴荸,在所有這些任務(wù)中選擇一個(gè)處理組合,使得這些任務(wù)組合在不超過M/2的情況下達(dá)到最大
- 因此本質(zhì)上就是一個(gè)背包問題宦焦,背包的容量為M/2发钝,商品的單位重量?jī)r(jià)值均為1,商品的重量即為任務(wù)所需要的時(shí)間量波闹。