探索单源最短路径算法及其贪心策略

版权申诉
0 下载量 145 浏览量 更新于2024-11-09 收藏 534B ZIP 举报
资源摘要信息:"从给定的节点和距离信息中,本文件描述了解决单源最短路径问题的方法,应用了贪心策略的算法。特别地,参考了单源最短路径算法的Bellman-Ford算法,该算法能够处理包含负权边的图。" 知识点详细说明: 1. 单源最短路径问题 单源最短路径问题是指在一个加权图中,找到从某一特定源点到所有其他节点的最短路径。这个问题是图论和算法领域中的一个基本问题,广泛应用于各种领域,如网络路由、地图导航等。 2. 贪心算法 贪心算法是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是全局最好或最优的算法。虽然贪心算法并不总是能保证找到最优解,但对于某些问题,如单源最短路径问题,贪心策略是有效的。 3. 单源最短路径算法 解决单源最短路径问题的常见算法有:Dijkstra算法、Bellman-Ford算法、Floyd-Warshall算法等。Dijkstra算法适用于没有负权边的图,而Bellman-Ford算法则可以处理含有负权边的图。 4. Bellman-Ford算法 Bellman-Ford算法由Richard Bellman和Lester Ford Jr.于1958年提出,它可以解决单源最短路径问题,尤其是在图中存在负权边时。该算法的核心思想是不断放松边,通过多次迭代来逐步接近真实的最短路径。 5. 邻接阵形式 图可以用多种数据结构表示,邻接阵(邻接矩阵)是一种常见的方式。在邻接矩阵中,图的每对顶点之间都有一个边的权重,如果两个顶点之间没有边则权重可以设为无穷大或某个特殊值表示不可达。对于Bellman-Ford算法,使用邻接矩阵可以方便地进行边的放松操作。 6. 负权边 在图论中,边的权重可以是任意实数,包括负数。如果图中包含负权边,某些算法(如Dijkstra算法)可能无法正确工作。Bellman-Ford算法的特殊之处在于它能够处理负权边,并且能够检测图中是否存在负权回路,即一个顶点通过一系列边回到自身且总权重为负。 7. 算法步骤 Bellman-Ford算法的基本步骤包括: - 初始化源点到自身的距离为0,到其他所有节点的距离为无穷大。 - 对所有边进行V-1次松弛操作(V为图中顶点的数量)。松弛操作指的是更新两个顶点之间的最短路径估计值,如果通过一条边从一个顶点到另一个顶点的距离比当前已知的最短路径更短,就更新这个估计值。 - 检查是否存在负权回路,通过再次尝试对所有边进行松弛操作,如果还能进一步减小路径长度,说明存在负权回路。 通过上述知识点,我们可以了解到单源最短路径问题、贪心策略、Bellman-Ford算法以及邻接阵形式在处理图中单源最短路径问题时的重要性和适用场景。Bellman-Ford算法以其处理负权边的特殊能力,在图算法中占有重要位置。

class Path(object): def __init__(self,path,distancecost,timecost): self.__path = path self.__distancecost = distancecost self.__timecost = timecost #路径上最后一个节点 def getLastNode(self): return self.__path[-1] #获取路径路径 @property def path(self): return self.__path #判断node是否为路径上最后一个节点 def isLastNode(self, node): return node == self.getLastNode() #增加加点和成本产生一个新的path对象 def addNode(self, node, dprice, tprice): return Path(self.__path+[node],self.__distancecost + dprice,self.__timecost + tprice) #输出当前路径 def printPath(self): for n in self.__path: if self.isLastNode(node=n): print(n) else: print(n, end="->") print(f"最短路径距离(self.__distancecost:.0f)m") print(f"红绿路灯个数(self.__timecost:.0f)个") #获取路径总成本的只读属性 @property def dCost(self): return self.__distancecost @property def tCost(self): return self.__timecost class DirectedGraph(object): def __init__(self, d): if isinstance(d, dict): self.__graph = d else: self.__graph = dict() print('Sth error') #通过递归生成所有可能的路径 def __generatePath(self, graph, path, end, results, distancecostIndex, timecostIndex): current = path.getLastNode() if current == end: results.append(path) else: for n in graph[current]: if n not in path.path: self.__generatePath(graph, path.addNode(n,self.__graph[path.getLastNode()][n][distancecostIndex][timecostIndex]), end, results, distancecostIndex, timecostIndex) #搜索start到end之间时间或空间最短的路径,并输出 def __searchPath(self, start, end, distancecostIndex, timecostIndex): results = [] self.__generatePath(self.__graph, Path([start],0,0), end, results,distancecostIndex,timecostIndex) results.sort(key=lambda p: p.distanceCost) results.sort(key=lambda p: p.timeCost) print('The {} shortest path from '.format("spatially" if distancecostIndex==0 else "temporally"), start, ' to ', end, ' is:', end="") print('The {} shortest path from '.format("spatially" if timecostIndex==0 else "temporally"), start, ' to ', end, ' is:', end="") results[0].printPath() #调用__searchPath搜索start到end之间的空间最短的路径,并输出 def searchSpatialMinPath(self,start, end): self.__searchPath(start,end,0,0) #调用__searc 优化这个代码

2023-06-07 上传
2023-06-08 上传