1.問題描述:
對於著名的圖的m着色,有兩個主要的問題,一個是圖的m色判定問題,一個是圖的m色優化問題,描述如下。
圖的m色判定問題: 給定無向連通圖G和m種顏色。用這些顏色為圖G的各頂點着色.問是否存在着色方法,使得G中任2鄰接點有不同顏色。
圖的m色優化問題:給定無向連通圖G,為圖G的各頂點着色, 使圖中任2鄰接點着不同顏色,問最少需要幾種顏色。所需的最少顏色的數目m稱為該圖的色數。
對於網上或書上的一些求解方式主要用貪心算法求解的方式,也有用回溯法的方式(一般不用,時空太大)。如這位博主 http://blog.csdn.net/pi9nc/article/details/9339199 使用的貪心算法來求解上面兩個問題。
對於該問題的貪心算法求解方式,是十分直觀、易懂,而且時空復雜度低。我個人的一種方式是非貪心算法的,采用的是一種 "掃描--判斷--增加" 的方式來進行求解,算法的時空復雜度類似於貪心求解的過程,且,也十分的清晰易懂。
2.對於圖的m優化問題求解過程&思路:"掃描--判斷--增加"
a. 初始化:全局顏色變量 C = 0 ;代表當前整張圖,可用的顏色數量有 C 種,即最大色數為 0 ;
b. 掃描: 對於V有n個頂點的無向連通圖,從V0開始線性掃描每一個頂點。
c. 判斷: 對於掃描到的頂點Vi,嘗試使用 1 - C 的顏色(1 - C 代表每一種不同的顏色)去着Vi,並判斷V0 - Vi-1 頂點中與Vi相鄰的頂點是否有顏色沖突。若沒有則着上該顏色。
d. 增加: 若對於當前掃描節點Vi,對於所有的 1 - C 的顏色都沒辦法着色。這時,就需要增加一種新的顏色,讓C++。並對Vi 着上新C值的顏色。
e. 線性掃描結束。
3.對於圖的m着色判斷問題求解&思路
圖的m着色判斷與上面的優化問題幾乎相似。只是開始的時候令顏色變量C = m 。當在 "判斷" 這一步時,若無法給Vi着色,則給出不能着色的結論。若能線性掃描完畢,則給出m色能夠着色的結論。
4.圖的m着色的優化問題代碼
下面給出個人的圖的m着色的優化問題的C++代碼。
#include<iostream> #include<string.h> #define N 5 using namespace std; bool isCollsion(bool a[][N] ,int c[],int i , int clor); int main(){ bool a[N][N] = {{false,true,true,true,false},{true,false,true,true,true},{true,true,false,true,false},{true,true,true,false,true},{false,true,false,true,false}}; int c[N]; memset(c,-1,N*sizeof(int)); int i = 0; int cl = 1; //cl 為顏色庫 顏色的編號從 [1 - cl] 之間選擇,初始的顏色庫中 只有 1 種顏色 int j = 0; for(i = 0; i < N;++i){ //遍歷每一個節點 vi for(j = 1; j <= cl ;++j){ //對vi 節點嘗試使用顏色 j來着色(1<= j <= cl) if(!isCollsion(a,c,i,j)){ // 若vi 着顏色j ,且與已經着色的節點(v0 - v(i-1))不發生任何着色沖突的話,就將vi着色為j c[i] = j; break; } if(c[i] == -1){ //若顏色庫中所有顏色都不能為vi節點 着色的話,就增加一種顏色,cl++;並將 該顏色賦予節點i c[i] = ++cl; } } } cout<<cl<<endl;; return 0; } //檢查 若vi 着顏色j ,與已經着色的節點(v0 - v(i-1)) 是否連通且不發生任何顏色沖突的話, bool isCollsion(bool a[][N] ,int c[],int i , int clor){ int j = 0; for(; j < i ;++j){ if(a[i][j] && c[j] == clor)return true; } return false; }
5.實驗結果截圖
6.總結
復習到這部分的內容后,尤其是圖的幾個重要算法,無不與貪心算法有關系。都是以局部最優達到全局最優。這里針對圖的m着色問題本人的一個非貪心算法的示例,具有簡單、易懂、時空低的特點。So...繼續學習,daydayup。算法和數據結構是非常重要的基礎。
參考資料
計算機算法設計與分析
http://blog.csdn.net/pi9nc/article/details/9339199