海南師範大學學生狗一枚,最近老師要求算法設計論文一篇,,心累,,,耗時一週終於弄出來,,,就存在這裏了,,以後留着用。
【摘要】圖着色問題(Graph Coloring Problem, GCP) 又稱着色問題,是最著名的NP-完全問題之一。其數學定義爲:給定一個無向圖G=(V, E),其中V爲頂點集合,E爲邊集合,圖着色問題即爲將V分爲K個顏色組,每個組形成一個獨立集,即其中沒有相鄰的頂點。其優化版本是希望獲得最小的K值。
回溯法(探索與回溯法)是一種選優搜索法,又稱爲試探法,按選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術爲回溯法,而滿足回溯條件的某個狀態的點稱爲“回溯點”。
【關鍵詞】算法設計、回溯法、圖着色問題
一、 問題描述與思想概述
(1)、問題的提出
給定無向連通圖G和m種不同的顏色。用這些顏色爲圖G的各頂點着色,每個頂點着一種顏色。是否有一種着色法使G中每條邊的2個頂點着不同顏色。這個問題是圖的m可着色判定問題。若一個圖最少需要m種顏色才能使圖中每條邊連接的2個頂點着不同顏色,則稱這個數m爲該圖的色數。求一個圖的色數m的問題稱爲圖的m可着色優化問題。
輸入:無向圖,m
輸出:如果能,則輸出方案
四色問題是m圖着色問題的一個特例,根據四色原理,證明平面或球面上的任何地圖的所有區域都至多可用四種顏色來着色,並使任何兩個有一段公共邊界的相鄰區域沒有相同的顏色。這個問題可轉換成對一平面圖的4-着色判定問題(平面圖是一個能畫於平面上而邊無任何交叉的圖)。將地圖的每個區域變成一個結點,若兩個區域相鄰,則相應的結點用一條邊連接起來。多年來,雖然已證明用5種顏色足以對任一幅地圖着色,但是一直找不到一定要求多於4種顏色的地圖。直到1976年這個問題才由愛普爾,黑肯和考西利用電子計算機的幫助得以解決。他們證明了4種顏色足以對任何地圖着色。
(2)、問題的處理
如果把每一個區域收縮爲一個頂點,把相鄰兩個區域用一條邊相連接,就可以把一個區域圖抽象爲一個平面圖。
用m種顏色爲圖中的每個頂點着色,要求每個頂點着一種顏色,並使相鄰兩頂點之間有着不同的顏色
抽象地圖及其相應的平面圖
可以通過回溯的方法,不斷的爲每一個節點着色,在前面n-1個節點都合法的着色之後,開始對第n個節點進行着色,這時候枚舉可用的m個顏色,通過和第n個節點相鄰的節點的顏色,來判斷這個顏色是否合法,如果找到那麼一種顏色使得第n個節點能夠着色,那麼說明m種顏色的方案是可行的。
(3)、回溯法介紹及其基本思想
回溯法有“通用的解題法”之稱。用它可以系統的搜索一個問題的所有解或任一解。是一個既帶有系統性又帶有跳躍性的搜索算法。
在包含問題的所有解的解空間樹中,按照深度優先搜索的策略,從根結點出發深度探索解空間樹。當探索到某一結點時,要先判斷該結點是否包含問題的解,如果包含,就從該結點出發繼續探索下去,如果該結點不包含問題的解,則逐層向其祖先結點回溯。(其實回溯法就是對隱式圖的深度優先搜索算法)。若用回溯法求問題的所有解時,要回溯到根,且根結點的所有可行的子樹都要已被搜索遍才結束。而若使用回溯法求任一個解時,只要搜索到問題的一個解就可以結束。
(4)、回溯法解題步驟
在用回溯法搜索解空間樹時,通常採用兩種策略來避免無效搜索,提高回溯法的搜索效率。其一是用約束函數在擴展結點處剪去不滿足約束的子樹;其二是用限界函數剪去不能得到最優解得子樹。這兩類函數統稱剪枝函數。
運用回溯法解題通常包含以下三個步驟:
(1)針對所給問題,定義問題的解空間
(2)確定易於搜索的空間結構
(3)以深度優先的方式搜索解空間,並且在搜索過程中用剪枝函數避免無效搜索。
二、算法設計過程(解問題過程)
(1)、解題思路
我們討論一般連通圖的可着色問題,而不只是平面圖。給定一個平面圖G=(V,E)和M種顏色,如果這個圖不是M可着色的,就回答‘no’,如果是M可着色的,則要找出所有不同的着色方法,目前我們認爲,此方法是解決該問題的最佳選擇。
解決問題之前先了解幾個術語:
局部有效着色:如果其中i個頂點已經着色,滿足相鄰兩個頂點的顏色都不一樣並且仍有顏色未被使用,就稱當前的着色是局部有效着色。
無效着色:如果其中i個頂點已經着色,並且存在相鄰兩個頂點的顏色一樣,就稱當前的着色是無效着色。
我們假設一個實例來解決,如上圖所示,平面圖G=(V,E),V={V1,V2,V3,V4},|E|=4;用M=3種顏色去着色,分別把這三種顏色的序號標爲1、2、3。先把所有節點顏色設置零,從根節點開始,對根節點用第一種顏色進行着色,第一個肯定着色有效,接下去接着對下一個節點着色,先用第一種顏色對其節點着色,然後判斷這個節點與相鄰節點是否相同,有相同顏色則判定爲無效着色,繼續用第二種顏色着色,直到着色有效爲止,如果與相鄰節點顏色沒有相同,則判定爲有效着色,繼續下一節點着色。
(2)、算法程序分析
bool ok()函數用於檢查顏色的可用性,如果顏色在當前結點有效,則返回true,否則返回false。
Backtrack()函數用於查找所有的可解方法。
GraphColor(){ //函數把所有查找到的結點進行着色,
for(i=1;i<=n;i++) //把所有結點的初始顏色設置爲0
color[i]=0;
while(color[k]<=m)
{
cout<<"爲第"<<k<<"個節點上顏色"<<color[k]<<endl;
if(ok(k,c)) //有效則跳出循環
{
cout<<"着色有效"<<endl;
break;
}
else //如果是無效着色,則另取一種顏色給當前節點
{
color[k]=color[k]+1;
}
color[k]<=m&&k==n //若已經着色完全,則輸出着色方案
color[k]<=m&&k<n{
k=k+1 //着色未完全並且顏色夠用,節點下移
}
k=k-1; //着色未完全並且顏色不夠用,返回到父節點
k<1; //找不到着色方案
、程序流程圖
、算法效率
圖M着色問題用回溯法解決時,算法的時間上界可以通過計算解空間樹種內結點的個數來估計,該問題中,解空間樹中內結點數爲 ,
對於每一個結點,在最壞情況下,ok檢查當前結點的每一個兒子所相應的顏色的可用性需耗時O(m n);因此該方法的時間複雜度爲: = nm(m^n-1)/(m-1)=O(nm^n);
(5)、結果與分析
按照上述例子,給定的無向圖用m=3種顏色進行着色,用該例子檢查算法的可用性。
輸入:頂點=4
顏色=3
無向圖的矩陣:
0 1 0 1
1 0 1 0
0 1 0 1
1 0 1 0
輸入方式及輸出結果如下圖所示:
該算法程序能較好的解決m圖着色問題,但是如果算法輸入較大的話,程序複雜度將大大增加,運行效率將會減小,該程序還需要很多優化的地方。
三、 結束語
回溯法是一種比較簡單的算法。
參考文獻:
[1]計算機算法設計與分析(第四版),王曉東,電子工業出版社,2012
[2]