接下来我们可以实现Dijkstra算法。Dijkstra算法是一种用于计算加权图中单源最短路径的经典算法。它广泛应用于网络路由、地图导航等领域。
以下是用 Lua 实现的Dijkstra算法:
-- Dijkstra算法函数
function dijkstra(graph, startNode)
local distances = {}
local previous = {}
local unvisited = {}
-- 初始化距离和前驱节点
for node, _ in pairs(graph) do
distances[node] = math.huge
previous[node] = nil
table.insert(unvisited, node)
end
distances[startNode] = 0
while #unvisited > 0 do
-- 找到距离最小的未访问节点
table.sort(unvisited, function(a, b) return distances[a] < distances[b] end)
local currentNode = table.remove(unvisited, 1)
-- 如果当前节点的距离是无穷大,说明剩余节点不可达
if distances[currentNode] == math.huge then
break
end
-- 更新邻居节点的距离
for neighbor, weight in pairs(graph[currentNode]) do
local alt = distances[currentNode] + weight
if alt < distances[neighbor] then
distances[neighbor] = alt
previous[neighbor] = currentNode
end
end
end
return distances, previous
end
-- 构建路径函数
function constructPath(previous, startNode, endNode)
local path = {}
local currentNode = endNode
while currentNode do
table.insert(path, 1, currentNode)
currentNode = previous[currentNode]
end
if path[1] == startNode then
return path
else
return nil -- 无法到达目标节点
end
end
-- 测试Dijkstra算法
local graph = {
A = {B = 1, C = 4},
B = {A = 1, C = 2, D = 5},
C = {A = 4, B = 2, D = 1},
D = {B = 5, C = 1}
}
local startNode = "A"
local endNode = "D"
local distances, previous = dijkstra(graph, startNode)
local path = constructPath(previous, startNode, endNode)
if path then
print("从 " .. startNode .. " 到 " .. endNode .. " 的最短路径:")
for _, node in ipairs(path) do
print(node)
end
print("总距离: " .. distances[endNode])
else
print("无法到达 " .. endNode)
end
在这个实现中:
dijkstra 函数接受一个图 graph 和一个起始节点 startNode ,返回从起始节点到所有其他节点的最短距离 distances 和前驱节点 previous 。
- 使用
distances 表来记录从起始节点到每个节点的最短距离,初始时所有节点的距离为无穷大(math.huge ),起始节点的距离为0。
- 使用
previous 表来记录每个节点的前驱节点,以便构建最短路径。
- 使用
unvisited 表来存储所有未访问的节点。
- 在
while 循环中,找到距离最小的未访问节点 currentNode ,并更新其邻居节点的距离。
constructPath 函数根据 previous 表构建从起始节点到目标节点的最短路径。
- 测试代码定义了一个简单的加权图,并调用
dijkstra 函数进行最短路径计算,输出从起始节点到目标节点的最短路径和总距离。
Dijkstra算法在许多实际应用中非常有用,例如网络路由、地图导航和交通规划等。它能够高效地找到加权图中单源最短路径。 |