前两天又跟同学聊起了最短路径问题,决定将部分理解和体会整理一下
实际路径图如下,忽略权重
首先根据实际路径图定义一个Map,map中存放一个当前位置,和与它相连的各位置.
查找路径时,
1.根据起点在map中从当前位置查找,
2.查找该当前位置所对应与它相连的各位置,并按该方法一直查找,直至找到终点
3.中间过程中,若在相连位置列表中出现已经遍历过的节点时,则不再遍历该节点
4.找到最终结果后,逆向推回来,并将结果整理
例如:
求从5到6的最短路径
首先观察5的位置,发现跟5关联的有1、3、4,然后将1、3、4记下来,并记录他们是从5过来的,然后观察1,发现跟1相连的有2、3、4,但是其中3、4都已经出现过了,所以不必要再记录,于是将2记录下来,并记录2是从1过来的,然后观察与2相连的节点,发现跟2相连的节点有3、6。 把3忽略,找到6,并且记录6是从2过来的,现在根据终点和他们每一次的来源点反向找回去,即可找到最佳路径。
lua代码实现
local map = {
[1] = {2,3,4,5},
[2] = {1,3,6},
[3] = {1,2,4,5},
[4] = {1,3,5},
[5] = {1,3,4},
[6] = {2},
}
-- 是否存在
function isExits(arr, value)
for i,v in ipairs(arr) do
if v.node == value then return true end
end
return false
end
function findWay(map, startNode, endNode)
-- 足迹
local foots = {
{node=startNode, from=nil} -- node 节点 from 从哪里来
}
-- 遍历足迹
for i1,v1 in ipairs(foots) do
-- 遍历v1的相邻节点
for i2,v2 in ipairs(map[v1.node]) do
-- 是否已经走过此地
if not isExits(foots, v2) then -- 如果没有走过此
foots[#foots + 1] = {node=v2, from=v1}
if v2 == endNode then
--TODO 已经找到,是写整理输出。
local way = {endNode}
local from = v1
while from ~= nil do
way[#way +1] = from.node
from = from.from
end
return way
end
end
end
end
end
求节点5到节点6的最短路径,最短路径可能不止一种,该算法会打印其中之一
local way = findWay(map, 5,6)
for i,v in ipairs(way) do
print(v)
end