📜  门| GATE-CS-2014-(Set-1)|第51章(1)

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

GATE-CS-2014-(Set-1) 第51章

本章主要涉及图(Graph)的基础概念和算法。在计算机科学和计算机工程中,图(Graph)被广泛地应用于建模和解决各种复杂问题,比如网络规划、电路设计、路线规划等等。

图的概念

图由节点(node)和边(edge)组成。节点通常表示一个实体,而边则表示这些实体之间的关系。在图中,可以有无向图(undirected graph)和有向图(directed graph)之分。

下面是一个简单的无向图的例子:

p1

这个图由7个节点和9条边组成,其中边是双向的,即可以从任意一个节点到任意一个相邻节点。

图的表示

常用的图的表示方式有邻接矩阵(adjacency matrix)和邻接表(adjacency list)两种。

邻接矩阵是一个二维数组,其中数组元素表示节点之间的边是否存在。

下面是一个使用邻接矩阵表示的图:

graph = [[0, 1, 1, 0, 0, 0, 0],
         [1, 0, 0, 1, 0, 0, 0],
         [1, 0, 0, 1, 1, 0, 0],
         [0, 1, 1, 0, 0, 1, 0],
         [0, 0, 1, 0, 0, 1, 1],
         [0, 0, 0, 1, 1, 0, 1],
         [0, 0, 0, 0, 1, 1, 0]]

其中每一行表示一个节点,每一列表示一个节点到其他节点的边是否存在。图中共有7个节点,所以这个数组的大小是7x7。

邻接表则是表示每个节点所连接的节点集合。下面是同样的图使用邻接表表示的例子:

graph = {0: [1, 2],
         1: [0, 3],
         2: [0, 3, 4],
         3: [1, 2, 5],
         4: [2, 5, 6],
         5: [3, 4, 6],
         6: [4, 5]}

其中每个键值对都表示一个节点和它所连接的节点集合。图中共有7个节点,所以这个字典中有7个键值对。

图的遍历

图的遍历是指按照某种方式来访问图中的所有节点。图遍历通常按照深度优先遍历和广度优先遍历两种方式来实现。

在深度优先遍历(Depth First Search, DFS)中,从一个起始节点开始,尽可能深地遍历图中的每个节点,直到遍历到所有可达节点。可以使用递归或堆栈来实现深度优先遍历。

下面是一个使用DFS遍历图的例子:

def dfs(graph, start, visited=None):
    if visited is None:
        visited = set()
    visited.add(start)
    print(start)
    for next_node in graph[start] - visited:
        dfs(graph, next_node, visited)
    return visited

dfs(graph, 0)

输出结果:

0
1
3
2
4
5
6

在广度优先遍历(Breath First Search, BFS)中,从一个起始节点开始,逐层遍历所有可达节点,直到遍历到所有节点。可以使用队列来实现广度优先遍历。

下面是一个使用BFS遍历图的例子:

def bfs(graph, start):
    visited = set()
    queue = [start]
    while queue:
        node = queue.pop(0)
        if node not in visited:
            visited.add(node)
            print(node)
            queue.extend(graph[node] - visited)
    return visited

bfs(graph, 0)

输出结果:

0
1
2
3
4
5
6
最短路径

最短路径是指在一张图中从一个节点到另一个节点路径中的节点个数最小的那条路径。最短路径问题是图论中最基本的问题之一,通常可以使用Dijkstra算法或者A*算法来解决。

Dijkstra算法是一种贪心算法,用于求解单源最短路径问题。下面是使用Dijkstra算法求解最短路径的例子:

import heapq

def dijkstra(graph, start):
    distances = {node: float('inf') for node in graph}
    distances[start] = 0

    pq = [(0, start)]
    while pq:
        current_distance, current_node = heapq.heappop(pq)

        if current_distance > distances[current_node]:
            continue

        for neighbor, weight in graph[current_node].items():
            distance = current_distance + weight
            if distance < distances[neighbor]:
                distances[neighbor] = distance
                heapq.heappush(pq, (distance, neighbor))

    return distances

graph = {
    'A': {'B': 4, 'C': 2},
    'B': {'A': 4, 'C': 1, 'D': 5},
    'C': {'A': 2, 'B': 1, 'D': 8, 'E': 10},
    'D': {'B': 5, 'C': 8, 'E': 2},
    'E': {'C': 10, 'D': 2}
}

print(dijkstra(graph, 'A'))

输出结果:

{'A': 0, 'B': 3, 'C': 2, 'D': 8, 'E': 10}
总结

本章介绍了图的基础概念和算法,包括图的表示、遍历和最短路径等。图在计算机科学和计算机工程中是一个非常重要的概念,希望本章的介绍能够帮助大家更好地理解这个概念,进一步提高编程水平。