目錄:
1、問題描述
2、Simple Local Search
3、Tabu Search
4、Hybrid Evolutionary Algorithm
5、總結
【注】本文源碼僅供參考。
1、問題描述
給定一個無向圖G = (V,E),其中V為頂點集合,E為邊集合,圖染色/圖着色問題(graph coloring problem, GCP)是將每個頂點塗上顏色,使得每個相鄰的頂點着不同的顏色,求出最少使用的顏色數K。
直接求取最小的顏色數K,是一個NP-hard問題。將問題轉化,對應於一個顏色數K,是否存在某種着色方案,使相鄰兩個節點顏色不同,是一個NP-complete問題,然后將逐漸的減小K。這樣兩個問題就等效了,我們稱后者為 K-coloring 問題。
K-coloring問題定義為:對於一個集合 S = {V1,V2,...,VK},其中 Vi 為所用顏色為 i 的頂點的集合,其中 1≤i≤K。若所有Vi為獨立集,則S為一個合法解,否則為一個非法解或者沖突解。任何兩個獨立集,互換顏色,都不影響沖突數目。
將目標函數定義為沖突數:
滿足:
對於所有的合法解,f(S) = 0。
2、Simple Local Search
對於一個K-coloring問題,作如下說明:
1、初始化解。可以選擇:為每個頂點從1到K中隨機的產生一個顏色;也可以通過某些啟發式的方法產生初始解。但是對於一個好的局部搜索算法對初始解應該不敏感,本文算法中采用隨機產生初始解
2、定義鄰域動作。本文算法中,定義為:對於每一個產生沖突的頂點,令其顏色等於其它K - 1個顏色。鄰域大小 = 沖突的頂點數 * (K -1) 。如下圖:
對於上圖K=3的情況,沖突對為(1,3),(1,4),(7,8),(5,6),沖突邊為4條,f(S) = 4,一共七個沖突頂點,每個沖突頂點可以着其它的2中顏色,鄰域大小7*2=14。
3、定義Adjacent-Color Table。M[N][K],其中N為頂點總數。M[u][i]其值的意思為,當頂點 u 着顏色 i 時,頂點 u 對應的沖突數。上圖的Adjacent-Color Table如下:
當頂點 u ,由顏色 i 變為顏色 j 時,定義這個動作為move(u,i,j),稱之為:critical one-moves。Δ(u,i,j) = M[u][j] - M[u][i];對於目標函數值將變為 f' = f + Δ(u,i,j),例如:我們將1號頂點由紅色(1)變為綠色(2)時,f'(S) = f(S) + Δ(u,i,j) = 4+1-2=3。如下圖所示:
4、更新Adjacent-Color Table。最終確定critical one-moves后,需要更新Adjacent-Color Table。更新的原則:對於move(u,i,j),對於與u頂點相鄰的頂點的行,第i列減一,第j列加一。如下:
5、為了更新Adjacent-Color Table,我們需要知道每一個頂點相鄰的所有頂點,因此定義一個數據結構:
typedef struct Adjacent_Matrix{ int neighbor ; //number of current vertex struct Adjacent_Matrix *next ; //point to the next vertex }Adjacent ;
Adjacent * *A_Matrix ;
A_Matrix[i] 指向第i個Vertex對應的所有相鄰節點,本文算法中,第一個neighbor其原本的功能可以用數組角標i代替,所以將其用於記錄第i個Vertex相鄰頂點的總個數。此時更新Adjacent-Color Table時只需遍歷move(u,i,j)中u的所有相鄰頂點即可。
以上說明都弄清楚了,則偽代碼就一目了然了,偽代碼如下:
3、Tabu Search
對於禁忌算法,我們還需要一個禁忌表,來記錄被禁忌的屬性和禁忌的長度。
如果某次迭代中執行了move(u,i,j),則頂點u將在接下來的tt次迭代中,禁止在回到顏色i。其中tt為禁忌長度。對於禁忌表TabuTenure[N][K],若記錄禁忌長度,則每次迭代都需要更新,即對所有非零的元素進行減一,當我們記錄的內容為:當前迭代次數+禁忌長度 的話,判斷屬性是否禁忌時,只需要比較當前迭代次數與禁忌表中值的大小,方法管理。
禁忌長度,可以采用常量的方式,也可以動態的改變。本文算法中,采用動態的改變禁忌長度,其值 = 2*f + rand()%10。其中f為目標函數的值,隨着目標函數值的下降,禁忌長度逐漸減小。
禁忌算法需要判斷每個鄰居解的質量,無論是否屬於禁忌解,對於禁忌解,判斷是否為當前最好的解且優於歷史最好解,若是,則進行解禁,否則只在非禁忌解中選擇最好解,若有若干個同等優度的解,則隨機選擇一個。
其偽代碼如下:
4、Hybrid Evolutionary
混合進化算法將局部搜索和進化算法相結合。進化算法是一個基於群體的算法(Population-based methods),混合進化算法可以將局部搜索的集中性和群體算法的疏散性相結合,達到更好的“集中性”和“疏散性”之間的平衡。
- 其主要思想是:維護一個比較小的“精英”群體,每個解都是經過局部搜索算法優化過的。對群體中的解采用進化算法的操作對其進行變換,並采用局部搜索算法對其優化。
- 當產生新解后,需要以解的優度和群體的多樣性等指標為依據,來對群體進行更新。
- 與進化算法相比,混合進化算法中的群體更新策略更重要。
- 混合進化算法往往表現出比單純的局部搜索或進化算法更優越的搜索性能。
偽代碼如下:
- 初始化Population:可以隨機選取若干個(一般是10~20),也可以通過啟發式的方法,本文算法中使用終止條件較為寬松的禁忌算法。
- 選擇雙親:隨機的從Population總選擇兩個。
- 交叉操作:下文詳細介紹
- 局部搜索:以上提到的局部搜索(LS),是泛指,可以是simple local search,tabu search,simulated annealing中的任意一種。
- 更新Population:替換掉Population選擇質量最差的一個解。
接下來着重講解Recombination Operator,即交叉算子(Crossover)。對於圖染色問題,考慮到質量優良的解,必有較多的獨立集,因此繼承雙親的最大獨立集,來保證后代的優良性。具體操作以下圖為例進行講解:
1、相同格子中為着同一顏色的頂點,從S1中選擇一個最大的集合{D,E,F,G},作為S的第一個顏色,然后將S1,S2中與S中相同的頂點刪除(見圖右上角)。
2、接下來,從另一個parent S2中選擇一個最大的集合,此時S中集合有{C},{A,I},{B,H,J},顯然選擇{B,H,J},放入到S的第二個顏色中,同樣將S1,S2中與S中相同的頂點刪除(見圖右側中間)。
3、重復1、2步,直至S所有顏色被填入集合(見圖右下角)。
4、對於剩余的,沒有分配的集合,隨機的選擇一個顏色,即隨機的將其放入S的任意格子中。同樣進行刪除操作。
5、重復4,直至所有頂點被加入到S。
偽代碼如下:
參考資料:
- A memetic algorithm for graph coloring
- 華中科技大學呂志鵬老師:啟發式優化課件