目錄
- 1.分支限界法簡介
1.1 分支限界法的本質(zhì)——通過限界阻塞子樹
1.2 分支限界法與回溯法的區(qū)別
1.3 下界或者上界估算——貪心 - 2.單源最短路徑問題
2.1 問題描述
2.2 分支限界法解決單元最短路徑問題 - 3.裝載問題
- 4.布線問題
- 5.0-1背包問題
5.1 問題描述
5.2 分支限界法解決0-1背包問題
5.3 一個示例 - 6.最大團(tuán)問題
- 7 作業(yè)分配問題
7.1 問題描述
7.2 分支限界法步驟描述 - 8.旅行商問題
8.1 問題描述
8.2 分支限界法解決旅行商問題
8.3 一個示例 - 9.電路板排列問題
- 10.批處理作業(yè)調(diào)度
1.分支限界法簡介
1.1 分支限界法的本質(zhì)——通過限界阻塞子樹
- 分支限界法通常僅關(guān)心使給定函數(shù)最大化或最小化。
- (分支限界法的本質(zhì))因此,如果算法找到了一個耗費(fèi)為c的解,并且有一個部分解,它的耗費(fèi)至少是c,那么就不會有該部分解的擴(kuò)展生成。
- 在分支限界法中,每一個活結(jié)點(diǎn)只有一次機(jī)會成為擴(kuò)展結(jié)點(diǎn)。活結(jié)點(diǎn)一旦成為擴(kuò)展結(jié)點(diǎn),就一次性產(chǎn)生其所有兒子結(jié)點(diǎn)。在這些兒子結(jié)點(diǎn)中,導(dǎo)致不可行解或?qū)е路亲顑?yōu)解的兒子結(jié)點(diǎn)被舍棄,其余兒子結(jié)點(diǎn)被加入活結(jié)點(diǎn)表中。
然后,從活結(jié)點(diǎn)表中取下一節(jié)點(diǎn)(優(yōu)先隊(duì)列中最大或最小值)成為當(dāng)前擴(kuò)展結(jié)點(diǎn),并重復(fù)上述擴(kuò)展過程。這個過程一直持續(xù)到找到所需的解或活結(jié)點(diǎn)表為空時(shí)為止。 - (分支限界法實(shí)現(xiàn)的本質(zhì))對某個節(jié)點(diǎn)進(jìn)行搜索時(shí),先估算出目標(biāo)的解,再確定是否向下搜索(選擇最小損耗的結(jié)點(diǎn)進(jìn)行搜索)
在分支結(jié)點(diǎn)上,預(yù)先分別估算沿著它的各個兒子結(jié)點(diǎn)向下搜索的路徑中,目標(biāo)函數(shù)可能取得的界,然后把它的這些兒子結(jié)點(diǎn)和它們可能取得的界保存在一張結(jié)點(diǎn)表中,再從表中選擇界最小或最大的結(jié)點(diǎn)向下搜索。一般采用優(yōu)先隊(duì)列維護(hù)這張表。
1.2 分支限界法與回溯法的區(qū)別
- 回溯法
1)(求解目標(biāo))回溯法的求解目標(biāo)是找出解空間中滿足約束條件的一個解或所有解。
2)(搜索方式深度優(yōu)先)回溯法會搜索整個解空間,當(dāng)不滿條件時(shí),丟棄,繼續(xù)搜索下一個兒子結(jié)點(diǎn),如果所有兒子結(jié)點(diǎn)都不滿足,向上回溯到它的父節(jié)點(diǎn)。 - 分支限界法
1)(求解目標(biāo))分支限界法的目標(biāo)一般是在滿足約束條件的解中找出在某種意義下的最優(yōu)解,也有找出滿足約束條件的一個解。
2)(搜索方式)分支限界法以廣度優(yōu)先或以最小損耗優(yōu)先的方式搜索解空間。
3)常見的兩種分支界限法
a.隊(duì)列式(FIFO)分支界限法(廣度優(yōu)先):按照隊(duì)列先進(jìn)先出原則選取下一個結(jié)點(diǎn)為擴(kuò)展結(jié)點(diǎn)
b.優(yōu)先隊(duì)列式分支限界法(最小損耗優(yōu)先):按照優(yōu)先隊(duì)列規(guī)定的優(yōu)先級選取優(yōu)先級最高的結(jié)點(diǎn)成為當(dāng)前擴(kuò)展結(jié)點(diǎn)
1.3 下界或者上界估算——貪心
- 分支限界法對下界和上界的估算,總是采用貪心算法,選擇當(dāng)前最優(yōu)作為界加入到優(yōu)先隊(duì)列
2.單源最短路徑問題
2.1 問題描述
- 給定帶權(quán)重的有向圖G=(V, E),圖中的每一條邊都具有非負(fù)的長度,求從源頂點(diǎn)s到目標(biāo)頂點(diǎn)t的最短路徑問題。
2.2 分支限界法解決單元最短路徑問題
- 把源頂點(diǎn)s作為根節(jié)點(diǎn)開始進(jìn)行搜索。對源頂點(diǎn)s的所有鄰接頂點(diǎn),都產(chǎn)生一個分支結(jié)點(diǎn),估計(jì)從源點(diǎn)s經(jīng)該鄰接頂點(diǎn)到達(dá)目標(biāo)頂點(diǎn)t的距離作為該分支結(jié)點(diǎn)的下界
- 選擇下界最小的分支結(jié)點(diǎn),對該分支結(jié)點(diǎn)所對應(yīng)的頂點(diǎn)的所有鄰接頂點(diǎn)繼續(xù)進(jìn)行上述的搜索
2.2.1 下界估算方法(貪心)
- 假定d(node)是搜索樹中從根節(jié)點(diǎn)到結(jié)點(diǎn)node所對應(yīng)的頂點(diǎn)u的路徑長度,頂點(diǎn)u的鄰接頂點(diǎn)為v1, v2, ..., vl,而cu,vi為頂點(diǎn)u到其鄰接頂點(diǎn)vi(i = 1, ..., l)的距離。
令h = min(cu,v1, cu,v2, ..., cu,vl)
則結(jié)點(diǎn)node的下界b(node) = d(node) + h -
一個例子
源頂點(diǎn)為a,目標(biāo)定的為t,把a(bǔ)作為根節(jié)點(diǎn)進(jìn)行搜索:
a->b->t距離的下界為:1+min{2, 9} = 3
a->c->t距離的下界為:4+min{3,6,3,4} = 7
a->d->t距離的下界為:4+min{7} = 11
2.2.2 分支限界法的步驟
將頂點(diǎn)編號為0, 1, ..., n-1.
每個結(jié)點(diǎn)包含如下信息:
??u——該節(jié)點(diǎn)所對應(yīng)的頂點(diǎn)
??path[n]——從源點(diǎn)開始的路徑上的頂點(diǎn)編號
??k——當(dāng)前搜索深度下,路徑上的頂點(diǎn)個數(shù)
??d——從源點(diǎn)到本節(jié)點(diǎn)所對應(yīng)頂點(diǎn)的路徑長度
??b——經(jīng)本節(jié)點(diǎn)到目標(biāo)頂點(diǎn)最短路徑的長度下界
bound——一個可行解的取值,當(dāng)做剪枝的標(biāo)準(zhǔn)
假定源頂點(diǎn)為s,目標(biāo)頂點(diǎn)為t。
- step1.初始化。建立根節(jié)點(diǎn)X
X.u = s
X.k = 1
X.path[0] = s
X.d = 0
X.b = 0
當(dāng)前可行解的最短路徑下界bound置位∞。 - step2.令頂點(diǎn)X.u所對應(yīng)的頂點(diǎn)為u,對u的所有鄰接頂點(diǎn)vi,建立兒子結(jié)點(diǎn)Yi,把結(jié)點(diǎn)X的數(shù)據(jù)復(fù)制到結(jié)點(diǎn)Yi
- step3.計(jì)算Yi的相關(guān)值
Yi.u = vi
Yi.path[Yi.k] = vi
Yi.k = Yi.k + 1
Yi.d = Yi.d + cu,vi
計(jì)算h和Yi.b - step4.若Yi.b < bound,轉(zhuǎn)向step5;
否則剪去結(jié)點(diǎn)Yi,轉(zhuǎn)向step6 - step5.把結(jié)點(diǎn)Yi插入優(yōu)先隊(duì)列。如果結(jié)點(diǎn)Yi.u = t,表明它是問題的一個可行解,用Yi.b更新當(dāng)前可行解的最短路徑長度下界bound。
- step6.取下優(yōu)先隊(duì)列首元素作為子樹的根節(jié)點(diǎn)X,若X.u = t,表明它是問題的最優(yōu)解,算法結(jié)束,數(shù)組X.path存放從源點(diǎn)s到目標(biāo)頂點(diǎn)t的最短路徑上的頂點(diǎn)編號,X.d存放該路徑長度,否則,轉(zhuǎn)向step2.
2.2.3 一個示例
- k=1。
根節(jié)點(diǎn)0對應(yīng)于源點(diǎn)a,有3個鄰接頂點(diǎn)b、c、d,其下界為3,7,11,壓入優(yōu)先隊(duì)列。 - k=2。優(yōu)先隊(duì)列中下界3最小,對于的頂點(diǎn)b,也即結(jié)點(diǎn)1。從頂點(diǎn)b繼續(xù)進(jìn)行搜索。
頂點(diǎn)b的鄰接頂點(diǎn)為c和e,其下界為6和11,壓入優(yōu)先隊(duì)列。 - k=3。優(yōu)先隊(duì)列中下界6最小,對應(yīng)頂點(diǎn)c,也即結(jié)點(diǎn)4.從頂點(diǎn)c繼續(xù)進(jìn)行搜索。
頂點(diǎn)c鄰接頂點(diǎn)d、e、f、g,對應(yīng)的下界為13,10,8,8,壓入優(yōu)先隊(duì)列。 - (回溯到了k=2)k=2。優(yōu)先隊(duì)列中7最小,對應(yīng)頂點(diǎn)c,也即結(jié)點(diǎn)2。從頂點(diǎn)c進(jìn)行搜索。
頂點(diǎn)c鄰接頂點(diǎn)d、e、f、g,對應(yīng)的下界為14,11,9,9,壓入優(yōu)先隊(duì)列。 - k=4。優(yōu)先隊(duì)列中8最小,對應(yīng)頂點(diǎn)f,也即結(jié)點(diǎn)8。
頂點(diǎn)f的鄰接頂點(diǎn)為e、t,下界分別為9、11,壓入棧中。其中11為一個可行解,將bound置為11. - (回溯到了k=4)k=4。優(yōu)先隊(duì)列中8最小,對應(yīng)頂點(diǎn)g,也即結(jié)點(diǎn)9。
頂點(diǎn)g的鄰接頂點(diǎn)為f、t,下界都是10。其中10為一個可行解,將bound置為10. - k=5.優(yōu)先隊(duì)列中9最小,對應(yīng)頂點(diǎn)e,也即結(jié)點(diǎn)14.
頂點(diǎn)e只有一個鄰接頂點(diǎn)t,下界為9,從而得到一個可行解,路徑長度為9,加入優(yōu)先隊(duì)列中。
優(yōu)先隊(duì)列中最小的為9,且最后一個結(jié)點(diǎn)為t,因此是最優(yōu)解。
3.裝載問題
4.布線問題
5.0-1背包問題
5.1 問題描述
假定n個商品重量分別為w0, w1, ..., wn-1,價(jià)值分別為p0, p1, ..., pn-1,背包載重量為M。怎樣選擇商品組合,使得價(jià)值最高?
5.2 分支限界法解決0-1背包問題
- 按價(jià)值重量比 遞減 的順序,對n個商品進(jìn)行排序
排序后商品序號的結(jié)合為S = {0, 1, ..., n-1} - 將這些商品分為3個集合:
S1——選擇裝入背包的商品集合
S2——不選擇裝入背包的商品集合
S3——尚待選擇的商品集合 - S1(k)、S2(k)、S3(k)分別表示在搜索深度為k時(shí)的3個集合中的商品。開始時(shí)有:
S1(0) = ?
S2(0) = ?
S3(0) = {0, 1, ..., n-1}
5.2.1 分支方法(二叉分支)
- 假設(shè)比值pi/wi最大的商品序號為s(s ∈ S3),用s進(jìn)行分支,一個分支結(jié)點(diǎn)表示把商品s裝入背包,另一個分支結(jié)點(diǎn)表示不把商品s裝入背包。
當(dāng)商品按照價(jià)值重量比遞減排序后,s就是集合S3(k)中的第一個元素。特別地,當(dāng)搜索深度為k時(shí),商品s的序號就是集合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}
5.2.2 上界估算方法(貪心)
- 假定b(k)表示在搜索深度為k時(shí),某個分支結(jié)點(diǎn)的背包中商品的價(jià)值上界。
此時(shí)S3(k) = {k, k+1, ..., n-1}。用如下方法計(jì)算兩種分支結(jié)點(diǎn)背包中商品價(jià)值的上界:
- 上述公式的理解
1)按照一個商品是否加入到S1集合,總共有2n個葉子節(jié)點(diǎn),每個葉子節(jié)點(diǎn)對應(yīng)一種情況
2)當(dāng)一層一層向下搜索是,如果當(dāng)前S1集合中的總重量超過了載重量M,則直接將b(k)置為0,該分支終止。
為什么這樣做?因?yàn)樵谒阉魃弦粚訒r(shí),該商品不應(yīng)該加入到S1集合,這種不加入該商品情況對應(yīng)于另一個分支。加入該商品的此分支已經(jīng)不滿足要求了,所以剪枝。
5.2.3 分支限界法求解步驟
每個結(jié)點(diǎn)都包含如下信息:
??S1——當(dāng)前選擇裝入背包的商品集合
??S2——當(dāng)前不選擇裝入背包的商品集合
??S3——當(dāng)前尚待選擇的商品集合
??k——搜索深度
??b——上界
bound——一個可行解的取值,當(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í),找到一個可行解,判定是否更新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í),找到一個可行解,判定是否更新bound。 - step6.取出優(yōu)先隊(duì)列首元素作為結(jié)點(diǎn)X,轉(zhuǎn)向step3
5.3 一個示例
-
有5個商品,重量分別為8,16,21,17,12,價(jià)值分別為8,14,16,11,7,背包的載重量為37,求裝入背包的商品及其價(jià)值。
6.最大團(tuán)問題
7 作業(yè)分配問題
7.1 問題描述
- n個操作員(編號:0, 1, ..., n-1)以n種不同時(shí)間完成n項(xiàng)不同作業(yè)(編號:0, 1, ..., n-1),要求分配每位操作完成一項(xiàng)作業(yè),使完成n項(xiàng)作業(yè)的時(shí)間總和最少。
- cij表示第i位操作員完成第j號作業(yè)所需的時(shí)間。
- 用向量x來描述分配給操作員的作業(yè)編號,如分量xi表示分配給第i位操作員的作業(yè)編號。
7.2 分支限界法步驟描述
- (估算下界,放到優(yōu)先隊(duì)列)從根節(jié)點(diǎn)開始向下搜索,在整個搜索過程中,每遇到一個結(jié)點(diǎn),對其所有兒子結(jié)點(diǎn)計(jì)算它們的下界,把它們記錄在結(jié)點(diǎn)表中。
- (從優(yōu)先隊(duì)列取最值,重復(fù)操作)從表中選取最小的結(jié)點(diǎn),并重復(fù)上述過程。
- (葉節(jié)點(diǎn)是否是最優(yōu)解的判定)當(dāng)搜索到一個葉子節(jié)點(diǎn),如果該節(jié)點(diǎn)的下界是結(jié)點(diǎn)表中最小的,那么該節(jié)點(diǎn)就是問題的最優(yōu)解。
否則,對下界最小的結(jié)點(diǎn)繼續(xù)進(jìn)行擴(kuò)展。
7.2.1 下界估算方法(類似于貪心,是一種最小估算方法)
- 假定k表示搜索深度,當(dāng)k = 0,從根節(jié)點(diǎn)開始向下搜索。若將0號作業(yè)(j = 0)分配給第i位操作員(0 ≤ i ≤ n-1),其余作業(yè)分配給其余操作員,則所需時(shí)間至少為:第i位操作員完成第0號作業(yè)的時(shí)間 + 其余n-1項(xiàng)作業(yè)分配給其余n-1位操作員單獨(dú)完成時(shí)所需最短時(shí)間之和。(下式中l(wèi)是任意的,只要不等于i即可)
下圖中,若將第0號作業(yè)分配給第0位操作員,c00 = 3,此時(shí)所需時(shí)間下界為: 3 + 7(1號作業(yè)給其余三位操作員完成最短時(shí)間) + 6(2號作業(yè)給其余三位操作員完成最短時(shí)間) + 3(3號作業(yè)給其余三位操作員完成最短時(shí)間) = 19
一個示例 - 一般的,當(dāng)搜索深度為k,前面第0, 1, ..., k-1號作業(yè)已經(jīng)分別分配給編號i0, i1, ..., ik-1的操作員。令S = {0, 1, ..., n-1}表示所有操作員的編號集合;mk-1 = {i0, i1, ..., ik-1}表示作業(yè)已分配的操作員的編號集合。當(dāng)把k號作業(yè)分配給編號為ik的操作員時(shí),ik ∈ S - mk-1。顯然,其下界為:
7.2.2 分支限界法求解作業(yè)分配問題
每個結(jié)點(diǎn)包含如下信息:
??m——已分配作業(yè)的操作員編號集合
??S——未分配作業(yè)的操作員編號集合
??x——操作的分配方案向量x,分量xi表示分配給第i位操作員的作業(yè)編號。
??k——搜索深度(表示分配的第k號作業(yè))
??t——所需時(shí)間的下界
bound——一個可行解的取值,當(dāng)做剪枝的標(biāo)準(zhǔn)
- step1.開始步驟。建立根節(jié)點(diǎn)X
X.k = 0
X.S = {0, 1, ..., n-1}
X.m = ?
把當(dāng)前問題的可行解的最優(yōu)時(shí)間下界bound置位∞。 - step2.對所有操作員i(i ∈ X.S),建立兒子結(jié)點(diǎn)Yi,把結(jié)點(diǎn)X的數(shù)據(jù)復(fù)制到Y(jié)i
- step3. 修改Yi的值
Yi.m = Yi.m ∪ {i}
Yi.s = Yi.S - {i}
Yi.xi= Yi.k (表示將第k號作業(yè)分給第i號操作員)
Yi.k= Yi.k + 1
并計(jì)算Yi.t - step4.若Yi.t < bound,轉(zhuǎn)step5;
否則剪去結(jié)點(diǎn)Yi,轉(zhuǎn)step6 - step5.把結(jié)點(diǎn)Yi插入優(yōu)先隊(duì)列,如果結(jié)點(diǎn)Yi是葉節(jié)點(diǎn),表明它是問題的一個可行解,用Yi.t更新當(dāng)前可行解的最優(yōu)時(shí)間下界bound。
- step6.取下隊(duì)列首元素作為子樹的根節(jié)點(diǎn)X,若X.k = n,則該節(jié)點(diǎn)是葉節(jié)點(diǎn),表明它是問題的最優(yōu)解,算法結(jié)束,向量X.x便是作業(yè)最優(yōu)分配方案;否則轉(zhuǎn)向step2.
7.2.3 一個實(shí)例
考慮如圖所示的4個操作員的作業(yè)最優(yōu)分配方案
令tik表示在某個搜索深度k下,把作業(yè)k分配給操作員i的時(shí)間下界。
- 當(dāng)k = 0時(shí),有
t00 = 3 + 7 + 6 + 3 = 19
t10 = 9 + 7 + 4 + 3 = 23
t20 = 8 + 7 + 4 + 5 = 24
t30 = 12 + 7 + 4 + 3 = 26
將這四個結(jié)點(diǎn)插入優(yōu)先隊(duì)列 - 當(dāng)k = 1時(shí),結(jié)點(diǎn)2(把0號作業(yè)分給0號操作員)的下界做小,將其取出,并由它向下繼續(xù)搜索
t11 = 3 + 12 + 6 + 3 = 24
t21 = 3 + 7 + 6 + 5 = 21
t31 = 3 + 7 + 9 + 3 = 22
將這三個結(jié)點(diǎn)插入優(yōu)先隊(duì)列 - 當(dāng)k =2時(shí),結(jié)點(diǎn)7(把1號作業(yè)分給2號操作員)的下界最小,將其取出,并由它向下繼續(xù)搜索
t12 = 3 + 7 + 13 + 8 = 31
t32 = 3 + 7 + 6 + 5 = 21
將這兩個結(jié)點(diǎn)插入優(yōu)先隊(duì)列 - 當(dāng)k = 3時(shí),結(jié)點(diǎn)10(將2號作業(yè)分給3號操作員)的下界最小,將其取出,并由它向下繼續(xù)搜索
t13 = 3 + 7 + 6 + 5 = 21
將其插入隊(duì)列中。
因?yàn)樗顷?duì)列中最小的結(jié)點(diǎn),所以將其取出,又因?yàn)槭侨~子節(jié)點(diǎn),所以是最優(yōu)解。(分量xi表示分配給第i位操作員的作業(yè)編號。)
x0 = 0, x1 = 3, x2 = 1, x3 = 2
8.旅行商問題
8.1 問題描述
8.1.1 問題描述
- 一個售貨員必須訪問n個城市,恰好訪問每個城市一次,并最終回到出發(fā)城市。
售貨員從城市i到城市j的旅行費(fèi)用是一個整數(shù),旅行所需的全部費(fèi)用是他旅行經(jīng)過的的各邊費(fèi)用之和,而售貨員希望使整個旅行費(fèi)用最低。 - (等價(jià)于求圖的最短哈密爾頓回路問題)令G=(V, E)是一個帶權(quán)重的有向圖,頂點(diǎn)集V=(v0, v1, ..., vn-1)。從圖中任一頂點(diǎn)vi出發(fā),經(jīng)圖中所有其他頂點(diǎn)一次且只有一次,最后回到同一頂點(diǎn)vi的最短路徑。
- c——費(fèi)用矩陣(鄰接矩陣),cij表示頂點(diǎn)vi到頂點(diǎn)vj的關(guān)聯(lián)邊的長度。
8.1.2 費(fèi)用矩陣的特性及規(guī)約
- 令G=(V, E)是一個帶權(quán)重的有向圖,l是圖G的一條哈密爾頓回路,c是圖G的費(fèi)用矩陣,則回路上的邊對應(yīng)于費(fèi)用矩陣c中每行每列各一個元素。
證明:因?yàn)閘上面的每個頂點(diǎn)vi有且僅有一條入邊和出邊,入邊表示費(fèi)用矩陣第i列僅有一個元素對應(yīng),出邊表示費(fèi)用矩陣第i行僅有一個元素對應(yīng)。 - 費(fèi)用矩陣c的第i行(或第j列)中的每個元素減去一個整數(shù)lhi(或chj),得到一個新的費(fèi)用矩陣c'。使得c'中第i行(或第j列)中的最小元素為0,稱為費(fèi)用矩陣的行歸約(或列歸約)。稱lhi為行歸約常數(shù),chj為列歸約常數(shù)。
-
對費(fèi)用矩陣c的每一行和每一列都進(jìn)行行歸約和列歸約,得到一個新的費(fèi)用矩陣c',使得c'中每一行和每一列至少都有一個元素0,稱為費(fèi)用矩陣的歸約。矩陣c'稱為費(fèi)用矩陣c的歸約矩陣,稱常數(shù)h為矩陣c的歸約常數(shù)。
- 令G=(V, E)是一個帶權(quán)重的有向圖,l是圖G的一條哈密爾頓回路,c是G的費(fèi)用矩陣,w(l)是以費(fèi)用矩陣c計(jì)算的這條回來的費(fèi)用。如果c'是費(fèi)用矩陣c的歸約矩陣,歸約常數(shù)為h,w'(l)是以費(fèi)用矩陣c'計(jì)算的這條回路的費(fèi)用。則有:
w(l) = w'(l) + h - 令G=(V, E)是一個帶權(quán)重的有向圖,l是圖G的一條最短哈密爾頓回路,c是G的費(fèi)用矩陣,c'是c的歸約矩陣,G'是與c'對應(yīng)的圖,c'是G'的費(fèi)用矩陣,則l是G'的一條最短的哈密爾頓回路。
8.2 分支限界法解決旅行商問題
8.2.1 分支方法(二叉分支)
- (分支1)選取沿著某一條邊出發(fā)的路徑,作為進(jìn)行搜索的一個分支結(jié)點(diǎn)
- (分支2)不沿這條邊的其他所有路徑集合,作為進(jìn)行搜索的另一個分支結(jié)點(diǎn)
8.2.2 下界確定
- 假定父親結(jié)點(diǎn)為X, w(X)是父親結(jié)點(diǎn)的下界。
現(xiàn)在,選擇沿vivj邊向下搜索作為其一個分支結(jié)點(diǎn)Y;
不沿vivj邊向下搜索作為另一個分支結(jié)點(diǎn)Y'。 - 分支Y:
費(fèi)用矩陣被降階和歸約,歸約常數(shù)為h,則w(Y) = w(X) + h - 分支Y':
將cij置位∞。
同時(shí)它必然包含費(fèi)用矩陣中第i行的某個元素和第j列的某個元素,令dij為第第i行和第j列中除cij之外的最小元素之和。
如果這兩個最小元素不為零,那么也即按照這兩個元素進(jìn)行歸約。本質(zhì)上dij也是矩陣進(jìn)一步的歸約常數(shù)。
因此有w(Y') = w(X) + dij。
8.2.3 分支的選擇(貪心)
- 1)沿cij 為0的方向選擇,使所選擇的路線盡可能短。
- 2)在多個cij 為0的方向中,沿dij最大的方向選擇,使w(Y')盡可能大
令S是費(fèi)用矩陣中cij 為0的元素集合,Dkl是S中使dij達(dá)到最大的元素,即:
即vkl就是所要選擇的分支方向。
8.2.4 分支限界法的求解步驟
每個結(jié)點(diǎn)包含如下信息:
??c——?dú)w約過后的費(fèi)用矩陣
??k——費(fèi)用矩陣的階數(shù)
??w——下界
??ad——頂點(diǎn)鄰接表
bound——一個可行解的取值,當(dāng)做剪枝的標(biāo)準(zhǔn)
- step1.bound = ∞
- step2.建立父親結(jié)點(diǎn)X
X.c 為費(fèi)用矩陣,并進(jìn)行歸約,歸約常數(shù)為h
X.k = n
X.w = h(下界)
X.ad頂點(diǎn)鄰接表 - step3.由X.c中所有為0的cij,計(jì)算dij
- step4.選擇使dij最大的元素dkl,選擇邊vkl作為分支方向。
step5是分支Y'的處理 - step5.(分支1)建立兒子結(jié)點(diǎn)Y'
Y'.c = X.c,將Y'.c中元素ckl置為∞,歸約Y'.c
Y'.ad = X.ad
Y'.k = X.k
計(jì)算下界Y'.w,并與bound進(jìn)行比較,根據(jù)比較決定是否插入優(yōu)先隊(duì)列。
step6-step9是分支Y的處理 - step6.(分支2)建立兒子結(jié)點(diǎn)Y
Y.c = X.c,將clk置為∞
Y.ad = X.ad
Y.k = X.k - step7.刪除Y.c的第k行與第l列元素
Y.k = Y.k -1
歸約Y.c
計(jì)算Y.w - step8.Y.k為2,直接判斷最短回路的兩條邊,并登記Y.ad,使Y.k = 0
- step9. Y.w與bound進(jìn)行比較,處理是否插入優(yōu)先隊(duì)列和更新bound
- step10.取下優(yōu)先隊(duì)列元素作為結(jié)點(diǎn)X,若X.k為0,算法結(jié)束;否則轉(zhuǎn)向step3.