使用Python编程的邻接矩阵

邻接矩阵是图论中非常重要的概念。邻接矩阵使用矩阵以数学格式表示图。假设该图有“V”个顶点。邻接矩阵是维度为 V*V 的方阵。它代表图的边。

让我们了解如何使用这个公式创建邻接矩阵,

AdjM={
 
    A[i][j]=0 if [i,j] is not an edge in the Graph
    A[i][j]=1 if [i,j] is an edge in the Graph
 
where i,j <V
}

一个例子将阐明上面的邻接矩阵公式。图表如下所示:

示例图 1
上面给定图的邻接矩阵

第二张图显示了示例图的邻接矩阵。需要注意的是,由于图是无向的,因此邻接矩阵中位置 [i,j] 和 [j,i] 的元素均为 1,其中 [i,j] 是图中的边。由于图中顶点 2 和 0 之间有一条边,因此邻接矩阵中位置 (2,0) 和 (0,2) 的值为 1。对于其他边也可以看到。由于图中顶点 4 和 1 之间没有边,因此位置 (4,1) 和 (1,4) 处的值为 0。对于其他顶点也可以看到,它们之间也没有边。

欲了解更多信息:在 Python 中实现图

如何在Python中创建邻接矩阵?

Python的networkx模块帮助用户进行图形可视化。它将用于解释所形成的图和邻接矩阵。可以在 Command Shell 中使用以下命令来安装它:

>>> pip install networkx

本文将介绍两种不同的方法。第一种方法是从作为输入提供的顶点和边列表创建邻接矩阵。第二种方法是从作为输入给出的邻接矩阵创建一个图(顶点和边的集合)。整篇文章仅关注无向图。

从图的顶点和边创建邻接矩阵

该函数有两个输入:顶点和边的列表。边将作为列表的列表给出。每个内部列表由两个元素组成:第一个元素是边的起始顶点,第二个元素是边的结束顶点。它返回一个邻接矩阵作为其输出,并在函数中绘制相应的图形。下面的代码演示了这一点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 号
18
19
20
21
def createAdjacencyMatrix(vertices,edges):
  noofvertices=len(vertices)
  adjM=[]
  while(len(adjM)<noofvertices):
    temp=[]
    for i in range(noofvertices):
      temp.append(0)
    adjM.append(temp)
  for edge in edges:
    i=edge[0]
    j=edge[1]
    if i>=noofvertices or j>=noofvertices or i<0 or j<0:
      print(f"Not a Proper Input in Edge {i},{j}")
    else:
      adjM[i][j]=1
      adjM[j][i]=1
  G=nx.Graph()
  G.add_edges_from(edges)
  nx.draw_networkx(G)
  plt.show()
  return adjM

上面的代码片段创建了一个存储在名为 adjM 的变量中的邻接矩阵。它的行维和列维与图中的顶点数相同。初始化邻接矩阵,所有初始值为0。遍历边列表的所有内层列表,将第一个元素指定为起始节点,将第二个元素指定为结束节点。还可以在第 12 行看到检查条件也已实现。对于超出范围的顶点值,程序将打印一条错误消息。超出范围被定义为值大于最大顶点数或值小于 0 的顶点。之后,在位置 [i,j] 和 [j,i] 处的值邻接矩阵转换为1。

该函数的另一部分根据给定的输入绘制图表。该函数返回创建的邻接矩阵。networkx 模块的功能在下面提供的文章中得到了很好的定义:

另请阅读:NetworkX 包 – Python 图形库

执行时,该函数将产生一个邻接矩阵并绘制相应的图形。输入图的顶点和边如下所示:

vertices=[0,1,2,3,4,5]
edges=[[1,2],[2,4],[1,5],[3,5],[4,5],[1,3],[0,3],[0,2],[5,3],[5,1]]

当上面给出的值作为函数 createAdjacencyMatrix() 的输入时,它会产生以下输出:

CreateAdjacencyMatrix() 函数的图形输出
[[0, 0, 1, 1, 0, 0],
 [0, 0, 1, 1, 0, 1],
 [1, 1, 0, 0, 1, 0],
 [1, 1, 0, 0, 0, 1],
 [0, 0, 1, 0, 0, 1],
 [0, 1, 0, 1, 1, 0]]

第二个函数从邻接矩阵创建一个图。它将输入作为邻接矩阵,并提供输出作为顶点和边的集合。

从邻接矩阵创建图

在第二个函数中,提供邻接矩阵作为输入。它还会将图形可视化,返回值将是顶点和边。邻接矩阵是列表的列表,其中每个内部列表的长度与整个外部列表的长度相同。这确保提供方阵作为输入。下面的代码演示了这一点:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 号
18
19
def createGraph(adjM):
  edges=[]
  noofvertices=len(adjM)
  for mat in adjM:
    if len(mat)>noofvertices or len(mat)<noofvertices:
      print("False Adjacency Matrix")
      return 0
  for i in range(len(adjM)):
    mat=adjM[i]
    for j in range(len(mat)):
      if mat[j]==1:
        temp=[i,j]
        edges.append(temp)
  G=nx.Graph()
  G.add_edges_from(edges)
  nx.draw_networkx(G)
  plt.show()
  vertices=[i for i in range(len(adjM))]
  return vertices,edges

上面代码的主要功能是创建列表边。边被创建为列表的列表,每个内部列表都有两个元素:边的起始顶点和结束顶点。该代码遍历邻接矩阵的长度,对于矩阵中的每个元素(即 1),将行号和列号存储为边。该代码还检查条件以确保已提供方阵作为输入。如果维度不满足条件,该函数将提前退出。networkx 的 Graph() 对象使用创建的边列表来可视化图形。顶点是图中所有顶点的列表。它只是通过枚举邻接矩阵的长度来实现,如第 18 行所示。边和顶点的集合作为输出返回。

以下 5 个顶点的邻接矩阵用作函数 createGraph() 的检查输入:

adjM=[[1,0,1,0,1],[0,0,1,1,0],[1,1,0,1,0],[1,1,0,0,0],[0,0,0,1,0]]

它生成一个无向图作为其输出。应该注意的是,(0,0) 处的元素保持为 1,这意味着顶点 0 处有一条循环边。邻接矩阵作为输入提供时,会产生以下输出

CreateGraph() 函数的图形输出
([0, 1, 2, 3, 4],
 [[0, 0],
  [0, 2],
  [0, 4],
  [1, 2],
  [1, 3],
  [2, 0],
  [2, 1],
  [2, 3],
  [3, 0],
  [3, 1],
  [4, 3]])

输出中的第一个元素是顶点列表,第一个顶点为索引 0。第二个输出是显示图的边的列表列表。

源代码

我在 Google Colaboratory 中开发了完整的代码,用于演示给定的函数并生成输出。任何人都可以访问它的源代码。

结论

邻接矩阵是表示图的一种重要方式。在本文中,我们了解了如何使用 Python 轻松创建和操作邻接矩阵。它是一个方阵,其维度为图上的边数。可以从图输入轻松创建邻接矩阵,反之亦然。从邻接矩阵实现图同样容易。创建邻接矩阵的时间复杂度为 O(n2),其中 n 是图中的顶点数。

参考

网络x网站