Dijkstra计算加权图的最短路径
# 加权的有向,无向图都可以
# Dijkstra是A* 算法的特例
【理论知识的,可以参考】
漫画:图的最短路径问题_~~ LINUX ~~-CSDN博客
该算法得到的是单源最短路径,即起点到任意目标点的距离
【lua实现】
1 local Dijkstra = {} 2 Dijkstra.__index = Dijkstra 3 4 function Dijkstra.new(g) 5 local obj = {} 6 setmetatable(obj, Dijkstra) 7 8 obj:ctor(g) 9 return obj 10 end 11 12 function Dijkstra:ctor(g) 13 self.graph = g 14 self.startVertex = nil 15 self.visitFrom = {} --点之间的遍历关系, key:当前遍历点, value:上一个遍历点 16 self.distFromStart = {} --从起始点到该点的距离 17 end 18 19 function Dijkstra:IsReachable(endVertex) 20 return self.distFromStart[endVertex].dist < 9999 21 end 22 23 function Dijkstra:VisitAllReachable(startVertex) 24 self.startVertex = startVertex 25 self.visitFrom = {} 26 self.distFromStart = {} 27 28 for i=1,self.graph:GetVertexCount() do 29 local v = self.graph:GetVertex(i) 30 self.distFromStart[v] = { 31 dist = 9999, 32 used = false, 33 } 34 end 35 36 local distInfo = self.distFromStart[startVertex] 37 distInfo.dist = 0 38 distInfo.used = true 39 40 local v = startVertex 41 while true do 42 local adjList = self.graph:GetAdjacent(v) 43 for i=1,#adjList do 44 local edge = adjList[i] 45 local v2 = edge:GetV2() 46 local oldDist = self.distFromStart[v2].dist 47 local newDist = self.distFromStart[v].dist + edge:GetWeight() 48 if newDist < oldDist then 49 self.distFromStart[v2].dist = newDist 50 self.visitFrom[v2] = v 51 end 52 end 53 54 --从距离最小的点继续往后遍历 55 --从ta开始过1次, 后面将不会再从ta开始 56 local minDistInfo = nil 57 local minV = nil 58 for i=1,self.graph:GetVertexCount() do 59 local v = self.graph:GetVertex(i) 60 local distInfo = self.distFromStart[v] 61 if not distInfo.used then 62 if nil == minDistInfo or distInfo.dist < minDistInfo.dist then 63 minDistInfo = distInfo 64 minV = v 65 end 66 end 67 end 68 if nil == minDistInfo then --所有都遍历过了 69 break 70 end 71 72 minDistInfo.used = true 73 v = minV 74 end 75 end 76 77 function Dijkstra:GetDist(endVertex) 78 return self.distFromStart[endVertex].dist 79 end 80 81 function Dijkstra:GetPath(endVertex) 82 if not self:IsReachable(endVertex) then return nil end 83 84 local pathQueue = {} 85 local v = endVertex 86 while v ~= self.startVertex do 87 table.insert(pathQueue, 1, v) 88 v = self.visitFrom[v] 89 end 90 table.insert(pathQueue, 1, v) 91 return pathQueue 92 end
计算下面这张图的最短路径:
1 function CreateGraph() 2 local g = WeightedGraph.new() 3 g:AddVertex("A") 4 g:AddVertex("B") 5 g:AddVertex("C") 6 g:AddVertex("D") 7 g:AddVertex("E") 8 g:AddVertex("F") 9 g:AddVertex("G") 10 11 g:AddEdge("A", "B", 5) 12 g:AddEdge("A", "C", 2) 13 g:AddEdge("B", "D", 1) 14 g:AddEdge("B", "E", 6) 15 g:AddEdge("C", "D", 6) 16 g:AddEdge("C", "F", 8) 17 g:AddEdge("D", "E", 1) 18 g:AddEdge("D", "F", 2) 19 g:AddEdge("E", "G", 7) 20 g:AddEdge("F", "G", 3) 21 22 --tostring(g) 23 return g 24 end 25 26 function Test1() 27 local g = CreateGraph() 28 local d = Dijkstra.new(g) 29 d:VisitAllReachable("A") 30 assert(d:IsReachable("B")) 31 assert(d:IsReachable("G")) 32 33 assert(5 == d:GetDist("B")) 34 assert(2 == d:GetDist("C")) 35 assert(6 == d:GetDist("D")) 36 assert(7 == d:GetDist("E")) 37 assert(8 == d:GetDist("F")) 38 assert(11 == d:GetDist("G")) 39 end 40 Test1()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异