下面是一个简单的Python代码,用于实现无向图:
class Graph:def __init__(self):self.vertices = {}self.edges = {}def add_vertex(self, vertex):if vertex not in self.vertices:self.vertices[vertex] = []def add_edge(self, v1, v2):if v1 not in self.vertices:self.add_vertex(v1)if v2 not in self.vertices:self.add_vertex(v2)self.vertices[v1].append(v2)self.vertices[v2].append(v1)def print_graph(self):for v in self.vertices:print(v, end=' -> ')print(self.vertices[v])
在上述代码中,Graph类表示无向图,其中包含一个字典vertices,用于存储每个顶点及其相邻的顶点列表。add_vertex()方法用来添加顶点,add_edge()方法用来添加边,print_graph()方法用来打印整张图。
2.1 深度优先搜索
深度优先搜索(DFS)是一种递归方式的图遍历算法,其思路是从起始顶点开始,沿着一条路径不断向下探索直到无法继续为止,然后回溯到上一个节点继续遍历。深度优先搜索可以用来查找是否存在一条路径从起始顶点到目标顶点。
下面是一个简单的Python代码,用于实现深度优先搜索:
def dfs(graph, start, visited=None):if visited is None:visited = set()visited.add(start)print(start, end=' ')for neighbor in graph.vertices[start]:if neighbor not in visited:dfs(graph, neighbor, visited)
在上述代码中,dfs()函数接收三个参数:graph表示待遍历的图,start表示起始顶点,visited表示已访问过的顶点集合。如果visited未被初始化,则将其设为空集。接着,将起始顶点加入visited集合,并输出该顶点。然后,遍历与该顶点相邻的顶点,如果该相邻顶点未被访问,则递归调用dfs()函数进行遍历。
2.2 广度优先搜索
广度优先搜索(BFS)是一种迭代方式的图遍历算法,其思路是从起始顶点开始,按层次逐步扩展,先遍历与起始顶点相邻的所有顶点,然后遍历与这些
顶点相邻的所有未访问过的顶点,以此类推直到遍历完成。广度优先搜索可以用来查找两个顶点之间的最短路径。
下面是一个简单的Python代码,用于实现广度优先搜索:
from collections import dequedef bfs(graph, start):visited = set()queue = deque([start])while queue:vertex = queue.popleft()if vertex not in visited:visited.add(vertex)print(vertex, end=' ')for neighbor in graph.vertices[vertex]:if neighbor not in visited:queue.append(neighbor)
在上述代码中,bfs()函数接收两个参数:graph表示待遍历的图,start表示起始顶点。首先,初始化visited集合和queue队列,将起始顶点加入队列。然后,进入循环,每次从队列中取出一个顶点并进行判断,如果该顶点未被访问,则加入visited集合,并输出该顶点。接着,遍历与该顶点相邻的顶点,如果这些相邻顶点未被访问,则加入队列中等待遍历。
下面是一个简单的Python代码,用于判断无向图的连通性:
def is_connected(graph):visited = set()dfs(graph, next(iter(graph.vertices)), visited)return len(visited) == len(graph.vertices)
在上述代码中,is_connected()函数接收一个参数graph表示待检查的无向图。首先,初始化visited集合,并对任意一个顶点进行深度优先搜索。然后,比较已访问过的顶点数是否等于图中的顶点数,如果相等则说明该无向图是连通图。
4.1 Dijkstra算法
Dijkstra算法是一种贪心算法,其思路是从起始顶点开始,选择当前距离该顶点最近的未访问过的顶点,并更新与该顶点相邻的顶点的距离值。重复以上步骤直到找到目标顶点或者所有顶点都被访问过。
下面是一个简单的Python代码,用于实现Dijkstra算法:
import heapqdef dijkstra(graph, start, end):queue = [(0, start)]visited = set()while queue:(distance, vertex) = heapq.heappop(queue)if vertex == end:return distanceif vertex not in visited:visited.add(vertex)for neighbor, weight in graph.vertices[vertex]:heapq.heappush(queue, (distance + weight, neighbor))return -1
在上述代码中,dijkstra()函数接收三个参数:graph表示待求解的加权图,start表示起始顶点,end表示目标顶点。首先,初始化priority queue队列和visited集合,将起始顶点加入队列。然后,进入循环,每次从队列中取出一个顶点并进行判断,如果该顶点为目标顶点,则返回距离值。如果该顶点未被访问,则将其加入visited集合,并遍历与该顶点相邻的顶点,更新其距离值并加入队列中等待遍历。最后,如果没有找到目标顶点,则返回-1。
4.2 A算法
A算法是一种启发式算法,其思路是在Dijkstra算法的基础上加入启发函数,用来估算从当前顶点到目标顶点的距离。根据启发函数的估值,可以优先遍历与目标顶点更接近的顶点,从而提高搜索效率。
下面是一个简单的Python代码,用于实现A*算法:
import heapqdef astar(graph, start, end, heuristic):queue = [(0, start)]visited = set()while queue:(distance, vertex) = heapq.heappop(queue)if vertex == end:return distanceif vertex not in visited:visited.add(vertex)for neighbor, weight in graph.vertices[vertex]:heapq.heappush(queue, (distance + weight + heuristic(neighbor, end), neighbor))return -1
在上述代码中,astar()函数接收四个参数:graph表示待求解的加权图,start表示起始顶点,end表示目标顶点,heuristic表示启发函数。首先,初始化priority queue队列和visited集合,将起始顶点加入队列。然后,进入循环,每次从队列中取出一个顶点并进行判断,如果该顶点为目标顶点,则返回距离值。如果该顶点未被访问,则将其加入visited集合,并遍历与该顶点相邻的顶点,根据启发函数的估值更新其距离值并加入队列中等待遍历。最后,如果没有找到目标顶点,则返回-1。