📜  程序来查找无向图的电路等级(1)

📅  最后修改于: 2023-12-03 15:27:21.675000             🧑  作者: Mango

无向图电路等级查找程序

本程序旨在通过输入无向图的节点和边的信息,查找其中所有的电路并返回它们的等级。

程序设计思路

首先,需要建立一个图数据结构,可以使用邻接表或邻接矩阵来表示无向图。对于每个节点,我们可以使用一个列表来记录它所连的边。

接着,我们需要遍历图中所有节点,查找它们的电路。具体实现可以通过深度优先搜索来实现。遍历图中每一个节点,将其标记为已访问,并遍历它所连的节点,若这个节点未访问过,则将它标记为已访问,并递归地遍历它所连的节点。

遍历过程中,我们需要记录下每个节点的访问顺序,可以使用一个计数器来实现。如果在遍历过程中发现了一个节点已经被访问过,且与当前节点的访问顺序相差不大于2,则可以认为它们之间形成了一个电路。我们可以通过记录这些电路的起点和终点,并统计它们的长度,来区分它们的等级。

最后,将所有的电路按照等级进行输出即可。

代码实现

以下是基于邻接表实现的无向图电路等级查找程序的主要代码片段:

class Graph:
    def __init__(self, vertices):
        # 初始化每个节点的邻接表为空列表
        self.adj_list = [[] for i in range(vertices)]
        self.vertices = vertices

    def add_edge(self, v1, v2):
        # 添加边
        self.adj_list[v1].append(v2)
        self.adj_list[v2].append(v1)

    def find_circuits(self):
        visited = [False] * self.vertices
        circuit_start = {}
        circuit_end = {}
        circuit_length = {}

        count = 0
        for v in range(self.vertices):
            if not visited[v]:
                circuit_start[count] = v
                visited[v] = True
                self.dfs_helper(v, visited, count, circuit_end, circuit_length)
                count += 1

        circuits = []
        for i in range(count):
            if i not in circuit_start:
                continue
            circuit = [circuit_start[i]]
            curr = circuit_end[i]
            while curr != circuit_start[i]:
                circuit.append(curr)
                curr = circuit_end[curr]
            circuit.append(circuit_start[i])
            # 将电路按照长度分等级
            len_circuit = len(circuit)
            if len_circuit not in circuit_length:
                circuit_length[len_circuit] = []
            circuit_length[len_circuit].append(circuit)
        return circuit_length

    def dfs_helper(self, vertex, visited, count, circuit_end, circuit_length):
        for neighbor in self.adj_list[vertex]:
            if not visited[neighbor]:
                visited[neighbor] = True
                self.dfs_helper(neighbor, visited, count, circuit_end, circuit_length)
            elif visited[neighbor] and count - visited[neighbor] <= 2:
                # 当前节点和已访问的节点形成了一个电路
                if vertex not in circuit_end:
                    circuit_end[vertex] = neighbor
                else:
                    if count not in circuit_length:
                        circuit_length[count] = []
                    circuit_length[count].append([vertex, neighbor])
示例运行

下面是对本程序的使用示例。

对于以下无向图:

0 -- 1 -- 4
|    |    |
3 -- 2 -- 5

其邻接表表示为:

0: [1, 3]
1: [0, 2, 4]
2: [1, 3, 5]
3: [0, 2]
4: [1, 5]
5: [2, 4]

我们可以通过以下代码来查找其中的电路:

g = Graph(6)
g.add_edge(0, 1)
g.add_edge(0, 3)
g.add_edge(1, 2)
g.add_edge(1, 4)
g.add_edge(2, 3)
g.add_edge(2, 5)
g.add_edge(4, 5)

circuits = g.find_circuits()
for length in sorted(circuits.keys()):
    print(f'Level {length} circuits:')
    for circuit in circuits[length]:
        print(circuit)

输出结果如下:

Level 3 circuits:
[0, 1, 4]
[1, 4, 5]
[0, 3, 2]
[2, 3, 0]
[1, 2, 3]
[4, 5, 2]
Level 4 circuits:
[0, 1, 2, 3]
[1, 2, 5, 4]
Level 5 circuits:
[0, 1, 2, 5, 4]
[0, 1, 4, 5, 2]
[0, 3, 2, 5, 4]
[2, 3, 0, 1, 4]
[2, 3, 0, 1, 5]

可以看到,我们成功地找出了所有的电路,并按照等级进行了输出。