使现有图形完全连接

时间:2019-01-15 22:28:47

标签: python graph strongly-connected-graph

我有一个这种结构的图:

G = {
    '1':['100', '134', '1435'], 
    '145':['4', '2345', '253'], 
    '3773':['12'], '773':['1211', '629']}

该图实际上是如此之大,有6378个节点和39932个边。 我的问题是该图已断开连接,我希望该图完全连接且没有断开连接的组件。

有人可以帮我提供python代码吗?自星期日以来,我一直在crack头。谢谢

def add_disconnected_nodes(Graph, begin):
    gkey = []
    cap_vertices = []
    for vertex in Graph.keys():
        gkey.append(vertex)
    if begin in gkey:
        begin = gkey[0]    
    for vertices in Graph.keys():
        if vertices != begin and vertices not in Graph[begin]:
            cap_vertices.append(vertices)
            #Graph[begin] = [Graph[begin], cap_vertices]
            Graph[begin] + cap_vertices
            Graph.update()
    return Graph

我写了这段代码,但是没有错误地运行。尽管如此,它仍无法完成工作。我知道我做错了事情

编辑:所以我以这种方式重写了代码,现在它要花很多时间才能执行。我选择了一个起始顶点作为键,并在此键的值中选择了每个其他节点节点,然后尝试将其添加到该值中。也许我做错了事;有人请帮助我!

def add_disconnected_nodes(Graph, begin):
if begin not in Graph:
    return False

beg = {}
bbg = []
for vet in Graph.keys():
    bbg.append(vet)
bba = []
while len(bbg) != 0:
    for ls in bbg:
        if ls != begin and ls not in Graph[begin]:
            bba.append(ls)
            bbg.remove(ls)
            if len(bbg) == 0:
                break
            beg[begin] = Graph[begin] + bba
            Graph.update(beg)
return Graph

3 个答案:

答案 0 :(得分:2)

建立简单图的最简单方法是将一个节点连接到该图的所有其他节点:

for v in G.keys():
    if v != '1' and '1' not in G[v]:
        G['1'].append(v)
        G[v].append('1')

在这里,我们没有使用DFS或BFS。代码很简单,但是增加的边数不是最小的。 该代码只能在简单图中使用(因为有向图的连接定义不同)。

此算法的时间复杂度为O(| V | + | E |)或O(n + m)。 如果使用DFS或BFS,则时间复杂度将相同。

答案 1 :(得分:0)

我最终得以破解。它适用于简单图和较大图结构。我感谢那些为这个问题做出贡献的人,尤其是对让我相信的@Julien!这是下面的代码:

from collections import defaultdict as dd

def add_disconnected_nodes(Graph, begin):
if begin not in Graph:
    return False

temp_dict = dd()
init_node_list = []
temp_node_list = []
for vertices in Graph.keys():
    init_node_list.append(vertices)

if init_node_list:
    for node_items in init_node_list:
        if node_items != begin and not node_items in Graph[begin]:
            temp_node_list.append(node_items)

    temp_dict[begin] = Graph[begin] + temp_node_list
    init_node_list.remove(node_items)
    Graph.update(temp_dict)

return Graph

答案 2 :(得分:0)

如果要以优化的方式进行操作,请使用强连接的组件(kosaraju's algorithem)并找出最强连接的组件,然后添加弱连接的节点以创建完全连接的图。

代码示例以演示:

#Function to findout the closely connected components:

class Graph: 

def __init__(self,vertices): 
    self.V= vertices #No. of vertices 
    self.graph = defaultdict(list) # default dictionary to store graph 

# function to add an edge to graph 
def addEdge(self,u,v): 
    self.graph[u].append(v) 

# A function used by DFS 
def DFSUtil(self,v,visited): 
    # Mark the current node as visited and print it 
    visited[v]= True
    print(v)
    #Recur for all the vertices adjacent to this vertex 
    for i in self.graph[v]: 
        if visited[i]==False: 
            self.DFSUtil(i,visited) 


def fillOrder(self,v,visited, stack): 
    # Mark the current node as visited  
    visited[v]= True
    #Recur for all the vertices adjacent to this vertex 
    for i in self.graph[v]: 
        if visited[i]==False: 
            self.fillOrder(i, visited, stack) 
    stack = stack.append(v) 


# Function that returns reverse (or transpose) of this graph 
def getTranspose(self): 
    g = Graph(self.V) 

    # Recur for all the vertices adjacent to this vertex 
    for i in self.graph: 
        for j in self.graph[i]: 
            g.addEdge(j,i) 
    return g

def printSCCs(self): 

    stack = [] 
    # Mark all the vertices as not visited (For first DFS) 
    visited =[False]*(self.V) 
    # Fill vertices in stack according to their finishing 
    # times 
    for i in range(self.V): 
        if visited[i]==False: 
            self.fillOrder(i, visited, stack) 

    # Create a reversed graph 
    gr = self.getTranspose() 

     # Mark all the vertices as not visited (For second DFS) 
    visited =[False]*(self.V) 

     # Now process all vertices in order defined by Stack 
    while stack: 
        i = stack.pop() 
        if visited[i]==False: 
            gr.DFSUtil(i, visited) 
            print("*****")

让我们说我总共有18个节点和一些初始连接:

g = Graph(18) 
g.addEdge(0, 10) 
g.addEdge(1, 15)
g.addEdge(1, 17) 
g.addEdge(2, 1)
g.addEdge(2, 3) 
g.addEdge(4, 12) 
g.addEdge(5, 7)
g.addEdge(6, 11)
g.addEdge(7, 8)
g.addEdge(7, 9)
g.addEdge(8, 9)
g.addEdge(9, 10)
g.addEdge(11, 14)
g.addEdge(12, 0)
g.addEdge(13, 6)
g.addEdge(14, 13)
g.addEdge(14, 4)
g.addEdge(15, 1)
g.addEdge(16, 2)

我的初始输入具有如下连接:

 {0: [10],
 1: [15, 17],
 2: [3, 1],
 3: [],
 4: [12],
 5: [7],
 6: [11],
 7: [8, 9],
 8: [9],
 9: [10],
 10: [],
 11: [14],
 12: [0],
 13: [6],
 14: [13, 4],
 15: [1],
 16: [2],
 17: []}

运行上述算法后,我得到的强连接组件如下:

Following are strongly connected components in given graph
16
*****
6
13
14
11
*****
5
*****
7
*****
8
*****
9
*****
4
*****
12
*****
2
*****
3
*****
1
15
*****
17
*****
0
*****
10
***** 

如果我添加以下连接,请点击并尝试。我的图已完全连接:

##### New Additions ############
g.addEdge(9, 5)
g.addEdge(5, 11)
g.addEdge(12, 7)
g.addEdge(10, 13)
g.addEdge(3, 4)
g.addEdge(17, 16)
g.addEdge(14, 15)

再次运行上述“高度连接的组件”算法,最终输出为:

Following are strongly connected components in given graph
0
12
4
14
11
5
9
7
8
6
13
10
3
2
16
17
1
15
*****

该代码的参考位于以下链接: Strongly Connected Components

注意:我已经根据您的问题尝试了此操作,必须有一种更好的方法和更好的方法,而不是“一击而过”。如果找到更好的方法,请随时改善答案。该答案的目的是介绍一种分析问题的方法。