第三章 混和式基因演算法
在基因演算法中,我們需要一個模擬自然界生物演化的對象稱作為族群,在族群 中包含許多個體。這些個體會依照自然界的法則,進行繁衍、突變以及物競天擇的族 群取代等行為。繁衍會在族群中產生新的個體;突變會改變一個體的某些基因值;物 競天擇則依適者生存,不適者淘汰的法則保持族群中固定的個體數量。在群中每一個 個體都是我們所要解決之問題的一個可能解答,適應函數可用來評估個體對於環境的 適應度,亦即對於一解答依照滿足問題的限制程度給予分數。經過不斷的重複這些生 物演化行為,我們可以從族群中得到越來越好的解。
本章詳述在我們方法中使用到的所有模組,基本架構與BeCh GA 大致相同,藉 以比較以TPOA 來選擇 GA 之初始族群之混和式基因演算法與原始 BeCh GA 之間的 不同之處。
第一節 個體表示法與適應函數
使用基因演算法來解決問題的第一步驟,就是設計合適的問題編碼方式。一般的 0-1 二元表示法非常適合作為 SCP 的編碼,我們在這裡使用n 個位元的字串來當作個 體的結構,n 為行的數量。一個個體代表著一個可行的可能解,第 j 個行若是在解中,
則個體的第j 個位元值設為 1,反之其值則設為 0。SCP 的一個個體之表示法如圖 3.1.1 所示。
1 0 1 0 1 ………… 0 1 圖3.1.1 一個個體的二元表示法
一個個體的適應值與其目標函數值有直接的關係,而使用二元表示法可以以下式
∑=
= n
j ij j
i c x
f
1
, (式 3.1)
其中x 為第 i 個個體中第 j 個位元的值,若ij x 為 1 表示在第 i 個個體的解中包含集合ij j,反之則否;cj為第j 個行的選擇成本。在 SCP 中,fi等於第 i 個個體所表示解的總 成本,總成本越低表示適應度越高。
使用二元表示法必須考慮一個重要的課題,就是當使用基因演算法的一些運算子
(如繁衍、突變)於二元字串個體之後,造成其成為非可行解時應該如何解決。一般 來說,有兩種解決方法,第一種方法是使用懲罰函數於非可行解上,根據非可行解所 違反問題限制的情況扣減其適應度;另一種方法是設計一種啟發式運算子,將非可行 解轉換成為一可行解。因為一個好的懲罰函數難以設計,而且根據我們的實驗,使用 簡單的懲罰函數無法有效率的產生最佳解,因此我們在這裡採用第二種方式,也就是 使用將非可行解轉換成為一可行解的作法,方法將在本章第六節中詳細說明。
第二節 族群初始方法
在[8]中的族群初始方法為在一菁英集合內的隨機產生法。其演算法如圖 3.2.1 所示,其中的第5 行是針對每一列i,在能夠覆蓋該列 i 的前 k 個最小選擇成本的行 集合αi,k中任選一個行來覆蓋該列,最後產生一個可行解Sp。步驟 2.d 對此一可行解 施以一貪婪法,以去除冗餘行。其提出對所有的問題,設 k=5,也就是在一菁英集
合Selite =Uim=1αi,5 中隨機產生解。
圖3.2.1 BeCh GA 初始族群演算法
在我們的族群初始演算法中,我們使用2.4 節中已詳細介紹過的二階段最佳化演 算法來產生具有不同基因片段的近似解。對於問題大小較大的 SCP 問題而言,利用 精確演算法求解非常耗時甚至不可行,即使是利用 TPOA 來幫助搜尋亦是如此。但 是,TPOA 提供我們一個系統化的方式來初始 GA 族群,不僅是隨機的產生而已,而 是更能產生一些異質性基因片段的近似解,降低GA 落入局部最佳解的機率,這也是 基因演算法強調初始族群要夠亂的原因之一。
我們的族群初始演算法示意圖如圖3.2.2 所示,Td 與 Tkd分別為TPOA 中的搜尋 深度與展開水平寬度係數。一開始時呼叫TPOA(ψ ,S , 0, population),S 為此
Initial_Population( SCP, population){
1. population={};
2. While (|population|<M){ //M is the population size。
3. Initialize Sp={} and vector w:wi =0,∀i∈I;//Sp: partial solution 4. For (each i∈I){
5. Randomly choose a column j∈αi,5, Sp =Sp+{ j}; 6. For (each i’∈βj) w[i’]++; //update w
7. }
8. T=Sp;
9. Do_untill(T={}){
10. Randomly select a column j∈T, T=T-{j};
11. For (each i∈βj){
12. If (w[i]>1, ∀ i∈βj){
13. Sp=Sp-{j}; // j is a redundant column 14. For (each i∈βj) w[i]=w[i]-1; //update w 15. }
16. } 17. }
18. If (Sp is not in the population) then add Sp into the population;
19. }
20. Return population;
}
個節點所求得之部分解,d 為深度索引值,k 為水平位置索引值。ψ0,0之值如後面(式 3.3)所示。
為了避免產生重複的解與增加基因演算法初始群組的多樣性,一節點Sd,k的可使 用行集合ψd ,k,在Sd,k往下展開一個節點選擇一個行加入部分解之後,會把所選擇的 行從ψd ,k中剔除,並把更新後的ψd ,k傳給所展開的節點。在第d 層水平位置索引值為 k 的 節 點 所 生 成 的 第 l 個 子 節 點 在 第 d+1 層 的 水 平 位 置 索 引 值 為
+l
−
×
=Tkd+1 (k 1)
δ 。一節點在同一層中由同一父親所產生之所有左邊節點(深度索
引值相同,水平位置索引值較自己小者)為其兄節點,同一層中由同一父親所產生之 所有右邊的節點為弟節點(深度索引值相同,水平位置索引值較自己大者),如在圖 3.2.2 中 S1,3的兄節點為S1,1與S1,2,S1,2之弟節點為S1,3。一節點在往下展開時會將所 展開過節點使用過的行,自可使用行集合ψd ,k中排除後再傳給其後代。例如,S0,0 展 開S1,1與S1,2之後,在展開 S1,3時S0,0的ψd ,k已去除掉加入S1,1與S1,2的行j1與j2,並 在選擇一行 j3加入 S1,3後,將ψd ,k-j3作為 S1,3的可使用行集合。很明顯的,兄節點 的可使用行集合包含弟節點的可使用行集合ψd,k ⊃ψd,k',k 為兄節點的水平位置索引 值,k’ 為弟節點的水平位置索引值。由於ψd,k ⊃ψd,k',弟節點因為不含有兄節點的 某些行,所能產生的後代也就不可能產生會與兄節點所能產生的一樣。所以,最終在 葉節點得到的所有解也都不會相同。在 TPOA 樹中深度為 d 時所產生的所有部分解 全都相異,每個部分解所含的行數量皆為d 個,但每個部分解所涵蓋的列數量不盡相 同,可使用行集合也都不相同,亦即 Sd,k≠Sd,k’,Sd,k = Sd,k' =d,∀k≠k,'d ≤Td,Sd,k
為在深度索引值為 d 且水平位置索引值為 k 的節點所得到的部分解。在深度 d 大於 Td 後使用貪婪法將部分解完成成為一可行解,最後完成的可行解所含的行集合數可 能不盡相同。使用TPOA 來產生基因演算法初始族群的演算法如圖 3.2.3 所示。
Td Tk2
Tk2
S1
S2
S3
Tk1
, 2
S2 Tk S2,Tk2+1
2 2
,
S2 Tk 1
,
S2
0 ,
S0
1 ,
S1 S1,2
, 1
S1 Tk
1 ,
STd STd,2 STd,3
圖3.2.2 使用 TPOA 來產生初始族群示意圖
圖3.2.3 使用 TPOA 產生基因演算法初始族群演算法 在我們的實作中,我們設定在第d 層的分支數
c d
Tkd =(int)log2( +1)+ , (式 3.2) 其中(int)為四捨五入至最接近整數之函數,c=1,c 可用來控制分支數的偏移量。層 數越深,該層的分支數越多。使用這個公式決定分支數的考量為,當在一開始展開 TPOA 樹時所選擇的行都是最好的,若展開分支數過多,而弟節點會去除兄節點所已 經選擇了的行,因此越右方的弟節點所展開的子代會越不可能找到好的解。根據實驗 的結果,使用(式 3.2)來動態決定分支度會較使用固定分支度的結果與效率來的好。
在TPOA 中展開到第 Td 層之後,我們使用貪婪法將產生的部分解 STd,k補至成為 一可行解,在我們的實作中設定 Td=3。第一種貪婪法 TPOA_greedy1 如圖 3.2.4 所 示,首先先找出未被目前所得之部分解 STd,k所覆蓋之列所成的集合 U,對每一在 U 中的列去尋找能覆蓋該列中平均貢獻成本cj U∩βj 最小的行j,將行 j 加入 Sd,k中,
並將行j 可覆蓋但在 U 中的列自U 中移除,重複做上列的動作直到得到的解 Sd,k能夠 覆蓋所有的列,也就是U 成為空集合,最後 Sd,k成為一可行解。
TPOA(ψd ,k, Sd,k, d, population){
1. d++; //d is the present depth of TPOA tree 2. If (d>Td) then TPOA_greedy(ψd ,k,Sd,k, population);
3. Tkd =(int)log2(d+1)+1; //branch factor for 4. If (d≦Td){
5. U is the set of rows that Sd,k can not cover;
6. For(l=1 to TKd){
7. Find the column j∈ψd,k with lowest score cj U∩βj ; 8. ψd,k =ψd,k −{j};
9. Sd+1,δ =Sd,k+{j}; //δ =Tkd ×(k−1)+l 10. TPOA(ψd ,k,Sd+1,δ , d, population);
11. } 12. } 13. d--;
14. Return population;
}
圖3.2.4 TPOA_greedy1 演算法
TPOA_greedy1(ψd ,k,Sd,k, population){
1. Initialize vector w:wi =0,∀i∈I ;
2. For (each j∈Sd,k){ //calculate how many times each row has been covered by Sd,k
3. For (each i∈βj) w[i]++; //update w 4. }
5. U is the set of rows that cannot be covered by Sd,k; 6. When(U≠{}){
7. For the first uncoverd row i in U, find a column j∈ψd ,k that can cover row i with the lowest score cj U∩βj ;
8. Sd,k=Sd,k + {j};
9. Update w;
10. U=U-βj; 11. }
12. For(j∈Sd,k){ //utilize vector w to eliminate redundant columns in Sd,k 13. If (w[i]>1, ∀ i∈βj){
14. Sd,k=Sd,k-{j}; // j is a redundant column 15. For (each i’∈βj) w[i’]=w[i’]-1; //update w 16. }
17. }
18. If (Sd,k is not in population) then add Sd,k into the population;
19. Return population;
}
圖3.2.5 TPOA_greedy2 演算法
由實驗結果得到,第一種貪婪法可以有效的幫助產生近似解,但是所花費的時間 不貲,尤其在問題大小較大的問題上。當產生100 個近似解之後,BeCh GA 法已經 可以產生兩三百個子代,在許多的問題中此時所得到的答案已經較貪婪法所能夠產生 的最好的解還要好了。因此,我們就使用亂數產生法來減少生成初始族群的時間。修 改圖3.2.4 中的步驟 3.a,在考慮要選擇哪一行來覆蓋一個未被目前之部分解所覆蓋的 列時,不再去尋找分數最小的行,改成在可使用行集合中,任意挑選一個能夠覆蓋該 列之行加入部分解中。修改後的貪婪法TPOA_greedy2 如圖 3.2.5 所示。
對於問題大小較大的問題,在每次要找最小貢獻成本的行時由於行的數量非常 TPOA_greedy2(ψd ,k,Sd,k, population){
1. Initialize vector w:wi =0,∀i∈I ;
2. For (each j∈Sd,k){ //calculate how many times each row has been covered by Sd,k
3. For (each i∈βj) w[i]++; //update w 4. }
5. U is the set of rows that cannot be covered by Sd,k; 6. When(U≠{}){
7. For the first uncoverd row i in U, randomly select a column j∈ψd ,k that can cover row i;
8. Sd,k=Sd,k +{j};
9. Update w;
10. U=U-βj; 11. }
12. For(each j∈Sd,k){ //utilize vector w to eliminate redundant columns in Sd,k
13. If (w[i]>1 , ∀ i∈βj){
14. Sd,k=Sd,k-{j}; // j is a redundant column 15. For (each i’∈βj) w[i’]=w[i’]-1; //update w 16. }
17. }
18. If (Sd,k is not in the population) then add Sd,k into the population;
19. Return population;
}
多,需要大量的運算時間。由於許多的高選擇成本之行非常不可能在最佳解中,為了 增加計算效率,我們在TPOA 生成初始族群時只考慮一小菁英集合
⎣ ⎦
Uim1 i,alpha_k/2
0 , 0
=
= α
ψ , (式 3.3)
其中alpha_k =log2(10nφ)。在表3.2.1 中顯示了 BeCh GA 法與 TGA 在各問題中所取 得菁英集合的個數。我們可以很明顯地由表3.2.1 中看出,問題集 4 與問題集 A 的密 度ψ相同但行數n 相差了 3 倍,但在菁英集合內的行數卻差不多。當 k 固定不變,密 度越高,被選入菁英集合的行數會越少,因此我們認為 k 應該與行數和密度成正相 關。在各類問題中,我們的alpha_k 與⎣alpha_k/2⎦參數如表3.2.2 所示。
Problem
set n ψ=
Density(%)
Average
Uim=1αi,5
Average
Uim=1αi,alpha_k
Average
⎣ ⎦
Uim=1αi,alpha_k/2
4 1000 2 361 483 239
5 2000 2 357 538 295
6 1000 5 173 250 146
A 3000 2 391 654 323
B 3000 5 185 318 186
C 4000 2 418 670 352
D 4000 5 195 335 195
E 5000 10 105 203 121
F 5000 20 57 117 65
G 10000 2 489 808 483
H 10000 5 225 423 256
表3.2.1 BeCh GA 法與 TGA 在各問題中所取得菁英集合的個數
Problem set alpha_k ⎣alpha_k/2⎦
4 7 3 5 8 4 6 8 4 A 9 4 B 10 5 C 9 4 D 10 5 E 12 6 F 13 6 G 10 5
最後,為了不浪費我們所花的時間所產生的部分解STd,且增加STd在族群中的數
量以提高其存活率,每一部份解都要用greedy2 產生 ∏
=
+
Td +
d
c d
N
1
2( 1) )
log ((int)
/ 個可行
解,若初始族群個數超過N 個,則保留前 N 個好的解作為初始族群,在我們的實做 中族群大小N=100。最後,我們的貪婪法 TPOA_greedy 如圖 3.2.6 所示。
圖3.2.6 TPOA_greedy 演算法 TPOA_greedy(ψd ,k,Sd,k, population){
1. Initialize vector w:wi =0,∀i∈I ;
2. For (each j∈Sd,k){ //calculate how many times each row has been covered by Sd,k
3. For (each i∈βj) w[i]++; //update w 4. }
5. U is the set of rows that cannot be covered by Sd,k; 6. When(U≠{}){
7. For the first uncoverd row i in U, randomly select a column j∈ψd ,k that can cover row i;
8. Sd,k=Sd,k + {j};
9. Update w;
10. U=U-βj; 11. }
12. For(generated_chiled=1 to ∏
=
+
Td +
d
c d
N
1
2( 1) )
log ((int)
/ ){
13. For(each j∈Sd,k){ //utilize vector w to eliminate redundant columns in Sd,k
14. If (w[i]>1 , ∀ i∈βj){
15. Sd,k=Sd,k-{j}; // j is a redundant column 16. For (each i’∈βj) w[i’]=w[i’]-1; //update w 17. }
18. }
19. If (Sd,k is not in the population) then add Sd,k into the population;
20. }
21. Return population;
}
第三節 父母選擇技術
父母選擇是在族群中挑選個體來進行繁殖的工作。在基因演算法的領域中最常使 用的方法,莫過於比例選擇(proportionate selection)與競爭選擇(tournament selection)。
比例選擇法依據每個個體的適應值來計算其被選來交配的機率。競爭選擇法(示意圖 如圖 3.3.1 所示)則是產生兩個競爭池(Pool),每個競爭池含有 T 個隨機自族群抽選的 個體,然後從兩個競爭池各自中挑出適應值最高的個體來交配。當 T 值越大,被選 出來交配的個體的適應值會越高。
圖3.3.1 競爭選擇示意圖
因競爭選擇法不需計算各個個體的選擇機率,因此實作上較比例選擇法有效率的 多,且[8]指出二元競爭選擇法(當T=2)與比例選擇法所產生的解之品質不相上下,
所以我們在這裡採用二元競爭選擇法。
第四節 交配運算子
在傳統的基因演算法中,有許多常用的交配運算子如單點交換法(圖3.4.1)、
雙點交換法(圖3.4.2)、均勻交換法(圖 3.4.3)等。單點與雙點交換法的運作方式
代。均勻交換法為子代的第 i 個位元值來自父或母(P1或P2)第 i 個位元值的機率相 等,且一次只產生一個子代。
圖3.4.1 單點交換法
圖3.4.2 雙點交換法
圖3.4.3 均勻交換法
由於在一開始我們所使用的SCP 的 benchmark 已經將行依選擇成本由小至大排 列好,在個體的右半部屬於選擇成本較高的行,被選擇的機會較小,因此右半部的基 因值會大多為0。當交換點落在右半部的基因時,所產生的後代將有很高的機率會和
P1 P2
C1 C2
交換點1 交換點2 交換點1 交換點2
P1 P2
C1 C2
交換點 交換點
P1 P2
C
Probability=0.5 Probability=0.5
i i
i
父母相同。此外,當基因演算法趨於收斂時,個體之間的差異將不太大,使用單點及 雙點交換法並不能夠有效的產生新的子代(不與現存於族群中之任一個體相同)。
Beasley 和 Chu 在[8]提出一般化的基於適應值的交換法,稱為融合交換法,詳細 的運作情形在2.4 節已詳述過,示意圖與圖 3.4.3 所示之均勻交換法一樣,只不過子 代基因來自父母哪一方的機率不再相同,而是有較高的機率來自適應度較高的一方。
基於適應值作法的理由是當要複製某一位置的基因時,若父母雙方在這個位置的基因 值不相同時,子代應有較高的機率從父母之中適應性較高的一方繼承相對應位置的基 因。這種作法在於強調父母雙方的不同,因此會較單點與雙點交換法能夠產生出新的 不與舊有族群中任一個體相同的能力。
第五節 變動式突變率
在一子代產生之後,通常會在其上施以突變的動作,將某些位置的基因值反轉,
藉以提供一小量的隨機搜尋。突變在基因演算法趨於收斂時尤其重要,此時交配所能 產生新的子代的機率會越來越低而陷入所謂的局部最佳解情況,使用適當的突變可以 有效的幫助跳脫局部最佳解的情況,達到搜尋全域最佳解的目標。
變動式的突變程序並不與原始的基因演算法一樣使用固定的突變率,其突變率會 依時間而改變。其理由為在執行初期,交配程序主要在於產生不錯的解,此時突變率 小可以避免打亂尋找好的解的機會。當基因演算法所得的解漸漸收斂,就需要突變的 機制來幫助其跳脫局部最佳解的窘境。突變的基因數在2.4 節也已詳述過,公式如(式 2.1)。
由圖 2.2.3 可以清楚的看出,突變的基因數在一開始為 0,到了產生了設定的子 代數量後,突變的基因數開始上升到所設定的數目為止,以免突變的基因數過多反而 影響產生好的解。關於突變的參數,都是經由實驗觀察該問題的在沒有突變的情況下 的收斂過程而設定的。[8]中對所有 OR-Library 中的 SCP 問題皆設定m=200,m =
此外,若是針對所有的基因來進行突變的動作,並不能夠有效的找到品質好的 解。因為高選擇成本之集合為最佳解之一部份的機率很低,當突變將原本不在解中的 高選擇成本集合選取作為解的一部份時,只會讓解越糟而無法找到好的解。因此,在 BeCh GA 法中針對一菁英集合(Selite)來作為突變的對象,
Uim i
elite
S
1 5 ,
=
= α , (式 3.4)
其 中αi,5 為 第 i 列 最 低 選 擇 成 本 的 前 5 個 行 所 成 的 集 合 。 我 們 在 這 裡 使 用
Uim ialpha k
elite
S
1
_ ,
=
= α ,此處alpha_k 如表 3.2.2 所示,雖然我們使用的菁英集合較大,可
能在一些問題的最佳解的搜尋過程中需要較長的時間,但也較不會錯過最佳解的機 率。
第六節 啟發式可行化運算子
由於一個經由融合交換法與突變運算子之後所生成的子代解可能是一個不可行 的解,也就是這個解違反了問題的一些限制,像是有一些列未被覆蓋,因此此時就需 要額外的處理來使得所生成的新解成為一個可行的解。[8]提出了一個啟發式的運算 子,不僅可以讓非可行解成為可行解,同時也提供了局部最佳化的能力,讓基因演算 法在SCP 求解的過程更有效率。該啟發式可行化運算子主要包含兩個步驟,”涵蓋未 被涵蓋的列”來讓解成為可行解,與貪婪式的”去除可行解中的冗餘行”,藉以提供局 部最佳化。演算法如圖3.6.1 所示。
在”涵蓋未被涵蓋的列”步驟中,首先要先找出哪些列還未被目前之部分解所覆 蓋。我們用一個含有 m 個元素的向量 w 來計數每一個列被在目前的部分解中的行覆 蓋了幾次,其中在 w 中被覆蓋次數為 0 的那些列就是未被覆蓋的列。這些未被覆蓋 的列集合為U,針對每一個在 U 裡的列來尋找可覆蓋該列之最小分數
j j
U c
β
∩ 的行 j
來覆蓋該列,U∩βj 為選擇行 j 可覆蓋的列但還未被目前所得到的部分解所覆蓋的 列個數。每選擇一行來覆蓋在U 中的一個列時,可能覆蓋其他在 U 中的列,將其自 U 中移除,並同時更新 w 中每一列的被覆蓋次數。執行完此步驟之後,一開始的部 分解就成為一可行解,其可覆蓋所有的列。
在”去除可行解中的冗餘行”的步驟 4 中,依舊會使用到向量 w 的資訊。由於在 SCP 問題中,在不失一般性的情況下,我們可以假設所有在解中的行依其選擇成本由 低到高排序,若選擇成本相同則依可覆蓋的列個數由多到少排序。因此,我們可以依 選擇成本由高至低檢查被選入解中的行,若去除所檢查的行之後該解依舊為可行解,
則我們就將該行視為冗餘行而將其自解中刪除。在此我們可以利用向量 w 來輕易的 幫助我們判斷一在解中之行是否為一冗餘行。若我們要判斷行 j 是否為冗餘行,我們 只要檢查行 j 所能夠覆蓋的列是否有任一列非由行 j 覆蓋不可,也就是在 w 中是否有 行 j 可覆蓋的列的覆蓋個數小於 2(等於 1)。若是,則行 j 不可被刪除,因為一旦行 j 被刪除之後該解就會成為非可行解;若否,由於行 j 所能覆蓋之列都能由其他在解 中的行所覆蓋,因此可以安心的移去行 j。
圖3.6.1 啟發式可行化運算子 Feasible 演算法
第七節 族群取代模型
族群取代模型有「一代取代一代法」(generational replacement)與「穩定狀態取代 法」(steady-state replacement)兩種。「一代取代一代法」為一次產生與原始族群數個 數一樣多的子代,在下一個世代由子代完全取代上一世代的族群。「穩定狀態取代法」
則為生成的子代只取代在原始族群中較差的個體;或生成後的子代與母族群混和後,
將適應性較差的個體去除,只留下固定數量適應性較高的個體。我們所使用的方法是 穩定狀態取代法,即在一子代生成之後,我們將原始族群依其適應函數值排列,在其 較差的一半之個體中,任意選一個體剔除之,然後將所生成之子代加入族群中,示意
Feasible(S){
1. Initialize vector w:wi =0,∀i∈I ;
2. For (each j∈S){ //calculate how many times each row has been covered by S
3. For (each i∈βj) w[i]++ ; 4. }
5. U is the set of rows that cannot be covered by S;
6. For(each i∈U){
7. Find the first column j∈αiwith the lowest score cj /U∩βj ; 8. U=U-βj;
9. S=S+{j}, then update w;
10. }
11. Sort S in increasing order of cost;
12. For(each j∈S in decreasing order){ //eliminate redundant columns 13. If (w[i]>1, ∀ i∈βj){
14. S=S-{j}; // j is a redundant column
15. For (each i’∈βj) w[i’]=w[i’]-1; //update w 16. }
17. }
18. Return S;
}
圖如圖3.7.1 所示。
圖3.7.1 穩定狀態取代法
第八節 區域搜尋
在區域搜尋方面,我們採用[21]所提出的區域最佳化方法來幫助我們找到最佳 解。其主要精神為對於一可行解,在所有的可用的行集合中找出能獲得利益的行所成 的集合,所謂能獲得利益的行是指將該行加入原來的可行解S 中,能夠使多個原先在 該可行解中的行成為冗餘行,在去除這些冗餘行後的總選擇成本較原先的總選擇成本 小,而該行所能獲得的利益便是該行在加入後與加入前可行解S 之總選擇成本間的差 值。在所有能獲得利益的行所成的優勢行集合中,依所能獲得的利益由大到小排序,
依序檢查該行對於S 是否依舊能有利益可得,若有則將該行加入解 S 中,並去除其中 之冗餘行,直到優勢行集合中的所有行都被檢查過一次,我們就可以得到一個局部最 佳解。
由於使用區域搜尋非常耗時,因此為了效率上的考量,在每次產生一個子代便對 較差的一半
族群
在較差的一半的族群中 任選一個體刪除
新產生的子代C 加入
得到最佳解,所以我們只對於夠好的解進行區域搜尋來尋找局部最佳解。在這裡,我 們設定當(score(S)−best)2 /best <0.01時,我們對該可行解S進行區域搜尋來尋找局 部最佳解,其中 score 函式會回傳解S的適應函數值,best為到目前為止此族群中 所找到最好的解之適應函數值。區域搜尋演算法如圖3.8.1 所示。
圖3.8.1 區域搜尋演算法
Local_search(S, ψ ){ //S is a feasible solution, ψ is the column set that can be used 1. SSup={}; //SSup is a superior column set
2. For(each j∈ψ ){
3. S’=S+{j};
4. Feasible(S’);
5. gainj=cost(S)-cost(S’);
6. If(gainj>0) then add j into SSup; 7. }
8. Sort SSup in decreasing order of gain;
9. Do_untill(SSup={}){
10. j=the first column in SSup; 11. S’=S+{j};
12. If(cost(Feasible(S’))<cost(S)){
13. S=S+{j};
14. Feasible(S) ; 15. }
16. SSup=SSup-{j};
17. }
18. Return S;
}
第九節 問題縮減
為了增加問題之求解效率,近年來求解 SCP 的啟發式演算法大多會對問題 進行問題縮減的動作。問題縮減的方法有許多種,去除冗餘行為一種常見的方 式。冗餘行所能覆蓋的列能夠被其他一個或多個行所覆蓋,且總選擇成本較冗餘 行之選擇成本低。但由於去除冗餘行的複雜度過高,因此此法不適用於要求快速 求解的演算法。另有一法為將所考慮的行集合縮減為一菁英集合,此法相當快 速,因此有許多的研究者使用此種方法來縮減問題。我們在TGA 中為了增加問 題的求解效率,只考慮在菁英集合 Selite 中的行,從這些行中選擇一子集來覆蓋 所有的列,因此n=|Selite|。
第十節 回顧
最後,我們以圖3.10.1 表示我們的 TGA 演算法整體架構。在圖 3.10.1 的演算法 中,行1 為設定我們所要用到的兩個集合 Selite以及Slittle_elite,並在行2 利用 Selite來縮 減問題以提高解決問題的效率。在行3 中初始一些必要的變數,在行 4 時使用這些變 數來呼叫TPOA 來產生 GA 的初始族群。由於我們用 TPOA 所產生的初始族群有可 能多於我們預先設定的族群大小N,因此行 5~7 中我們只保留由 TPOA 所產生的族 群中前N 個好的個體作為初始族群。行 8~20 為基本的 GA 架構,其停止條件為產 生M 個子代,我們的設定與 BeCh GA 一樣設定 M=100000。在行 8~20 中,行 9 使用競爭選擇法由族群中選出兩個個體,作為行10 使用融合交換法來產生子代 C 的 父母,並在行11 使用 3.5 所介紹的變動式突變程序對產生的子代 C 進行突變的動作。
經由行10、11 所產生的子代 C 可能不為一可行解,行 12 使用一啟發式可行化演算 法將C 修正為一可行解。行 13~15 為若產生的子代 C 夠接近目前在族群中最好的解,
則呼叫一局部搜尋函式來精化子代C,在 TGA_without_Local_search 的版本中此步驟
就利用穩定狀態取代法將子代C 加入現有的族群中。最後當 GA 的停止條件滿足時,
我們就在行21 輸出族群中最好(也就是總成本最低)的個體做為我們所找到的最好 的解。
圖3.10.1 TGA 演算法
TGA(SCP, N, Td){ //SCP is a given problem, N is the population size, Td is the TPOA depth of tree search.
1. Selite=Uim=1αi,alpha_k ,Slittle_elite=Uim=1αi,⎣alpha_k/2⎦ ;//alpha_k =log2(10nφ)
2. Reduce SCP by only keeping the columns in Selite; 3. S0,0={}, d=0, generate_children=0, population={};
4. TPOA(Slittle_elite, S0,0, d, population);// Generate GA initial population 5. While(the size of the population>N){ //Keep the N best solutions in the
population;
6. Delete the highest cost individual in the population;
7. }
8. When(generate_children<M){ //M=100000
9. Select parents P1 and P2 using binary tournament selection;
10. Use P1 and P2 to generate a child C using fusion crossover;
11. Mutate C;
12. Feasible(C); //make C feasible
13. If((cost(C)−best)2/best<0.01){ //in TGA_without_Local_search version, this step is skipped. The best is the cost of the best solution in the population.
14. Local_search(C);
15. }
16. If (C is not in the population) {
17. Replace an individualin the population by C with steady-state replacement;
18. generate_children++;
19. } 20. }
21. Output the lowest cost individual in the population as the best solution found.
}