1. 程式人生 > 其它 >無向圖的連通分量計算

無向圖的連通分量計算

# 從某個頂點出發,訪問到其能訪問的所有其他頂點,這些頂點是屬於一個連通分量的。

# 以此類推,將圖的每個頂點都作為出發點一次。

 1 local ConnectedComponent = {}
 2 ConnectedComponent.__index = ConnectedComponent
 3 
 4 function ConnectedComponent.new()
 5     local obj = {}
 6     setmetatable(obj, ConnectedComponent)
 7     obj:ctor()
 8     return obj
 9 end
10 11 function ConnectedComponent:ctor() 12 self.graph = nil 13 self.vertexComponent = nil ---頂點所屬的連通分量 14 self.componentId = 0 15 end 16 17 function ConnectedComponent:Calc(graph) 18 self.graph = graph 19 self.vertexComponent = {} 20 self.componentId = 0 21 local visited = {}
22 23 local function dfsVisitAllReachable(v) 24 visited[v] = true 25 self.vertexComponent[v] = self.componentId 26 27 local adjList = graph:GetAdjacent(v) 28 for i=1,#adjList do 29 local adjV = adjList[i] 30 if not visited[adjV] then 31 dfsVisitAllReachable(adjV)
32 end 33 end 34 end 35 36 for i=1,graph:GetVertexCount() do 37 local v = graph:GetVertex(i) 38 if not visited[v] then 39 dfsVisitAllReachable(v) --這個頂點能訪問到的所有頂點屬於同一個連通分量 40 self.componentId = self.componentId + 1 41 end 42 end 43 end 44 45 function ConnectedComponent:IsConnected(v1, v2) 46 return self.vertexComponent[v1] == self.vertexComponent[v2] --是否屬於同一個連通分量 47 end 48 49 ---連通分量數量 50 function ConnectedComponent:GetCount() 51 return self.componentId 52 end 53 54 ---頂點所屬連通分量id 55 function ConnectedComponent:GetComponentId(v) 56 return self.vertexComponent[v] 57 end 58 59 function ConnectedComponent:Dump() 60 local ccVertexListTb = {} ---連通分量的頂點佇列 61 62 for i=1,self.graph:GetVertexCount() do 63 local v = self.graph:GetVertex(i) 64 local cid = self:GetComponentId(v) 65 local queue = ccVertexListTb[cid] 66 if nil == queue then 67 queue = {} 68 ccVertexListTb[cid] = queue 69 end 70 table.insert(queue, v) 71 end 72 73 for k_v, v_list in pairs(ccVertexListTb) do 74 print(table.concat(v_list, ",")) 75 end 76 end

 

使用下面的圖進行測試:

 

 

 1 function CreateGraph()
 2     local g = Graph.new()
 3 
 4     g:AddVertex("0")
 5     g:AddVertex("1")
 6     g:AddVertex("2")
 7     g:AddEdge("0", "1")
 8     g:AddEdge("0", "2")
 9 
10     g:AddVertex("3")
11 
12     g:AddVertex("4")
13     g:AddVertex("5")
14     g:AddVertex("6")
15     g:AddVertex("7")
16     g:AddEdge("4", "5")
17     g:AddEdge("4", "6")
18     g:AddEdge("5", "7")
19 
20     g:AddVertex("8")
21     g:AddVertex("9")
22     g:AddEdge("8", "9")
23 
24     tostring(g)
25     return g
26 end
27 
28 function Test1()
29     local g = CreateGraph()
30     local cc = ConnectedComponent.new()
31     cc:Calc(g)
32     cc:Dump()
33 end
34 Test1()

 

【參考】

圖論演算法——無向圖的連通分量_日積月累,天道酬勤-CSDN部落格_無向圖的連通分量