無向圖的連通分量計算
阿新 • • 發佈:2022-03-13
# 從某個頂點出發,訪問到其能訪問的所有其他頂點,這些頂點是屬於一個連通分量的。
# 以此類推,將圖的每個頂點都作為出發點一次。
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 end10 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部落格_無向圖的連通分量