A*算法lua实现
来源:互联网 发布:淘宝尺码怎么设置 编辑:程序博客网 时间:2024/06/15 11:26
转自:http://www.cocoachina.com/bbs/read.php?tid-279162.html
加了点注释方便理解
--[[ A*寻路算法,估价值代表估计代价值--]]-- 行走的4个方向local four_dir = { {1, 0}, {0, 1}, {0, -1}, {-1, 0},}-- 行走的8个方向local eight_dir = { {1, 1}, {1, 0}, {1, -1}, {0, 1}, {0, -1}, {-1, 1}, {-1, 0}, {-1, -1}}local AStar = {}-- 地图、起始点、终点-- map 是一个二维数组,对应值为0表示可以通行,1表示障碍物AStar.init = function(self, map, startPoint, endPoint, four_dir) self.startPoint = startPoint self.endPoint = endPoint self.map = map self.cost = 10 -- 单位花费 self.diag = 1.4 -- 对角线长, 根号2 一位小数 self.open_list = {} -- open_list表保存了所有已生成而未考察的节点 self.close_list = {} -- close_list表中记录已访问过的节点 self.mapRows = #map self.mapCols = #map[1] self.four_dir = four_dir -- 使用4方向的寻路还是八方向的寻路end-- 搜索路径,核心代码AStar.searchPath = function(self) -- 验证终点是否为阻挡,如果为阻挡,则直接返回空路径 if self.map[self.endPoint.row][self.endPoint.col] ~= 0 then logf("(", self.endPoint.row, ",", self.endPoint.col, ") 是阻挡!!!无法寻路") return nil end -- 把出发节点加入open_list中 local startNode = {} startNode.row = self.startPoint.row startNode.col = self.startPoint.col startNode.g = 0 startNode.h = 0 startNode.f = 0 table.insert(self.open_list, startNode) -- 检查边界、障碍点 local check = function(row, col) if 1 <= row and row <= self.mapRows and 1 <= col and col <= self.mapCols then if self.map[row][col] == 0 or (row == self.endPoint.row and col == self.endPoint.col) then return true end end return false end local dir = self.four_dir and four_dir or eight_dir while #self.open_list > 0 do local node = self:getMinNode() if node.row == self.endPoint.row and node.col == self.endPoint.col then -- 找到路径 return self:buildPath(node) end for i = 1, #dir do local row = node.row + dir<i>[1] local col = node.col + dir<i>[2] if check(row, col) then local curNode = self:getNodeWithFGH(node, row, col, (row ~= node.row and col ~= node.col)) local openNode, openIndex = self:findNodeInOpenList(row, col) local closeNode, closeIndex = self:findNodeInCloseList(row, col) if not openNode and not closeNode then -- 不在OPEN表和CLOSE表中 -- 求出估价值并把节点加到 open list table.insert(self.open_list, curNode) --根据估价函数重排OPEN表 --这样循环中的每一步只考虑OPEN表中状态最好的节点。 elseif openNode then -- 已经在OPEN表中,且估价值小于OPEN表中的估价值 -- 更新OPEN表中的估价值 if openNode.f > curNode.f then self.open_list[openIndex] = curNode end else -- 在CLOSE表中,且估价值小于CLOSE表中的估价值 -- 从CLOSE表中移除节点,并且加入OPEN表中 if closeNode.f > curNode.f then table.insert(self.open_list, curNode) table.remove(self.close_list, closeIndex) end end end end -- 节点放入到 close list 里面 table.insert(self.close_list, node) end -- 不存在路径 return nilend-- 获取 f ,g ,h, 最后一个参数代表是否允许沿着对角线走AStar.getNodeWithFGH = function(self, father, row, col, isdiag) local node = {} local cost = self.cost if isdiag then cost = cost * self.diag end node.father = father node.row = row node.col = col node.g = father.g + cost -- 估价值h if self.four_dir then node.h = self:manhattan(row, col) else node.h = self:diagonal(row, col) end node.f = node.g + node.h -- f = g + h return nodeend-- 判断节点是否已经存在 open list 里面AStar.findNodeInOpenList = function(self, row, col) for i = 1, #self.open_list do local node = self.open_list<i> if node.row == row and node.col == col then return node, i -- 返回节点和下标 end end return nilend-- 判断节点是否已经存在 close list 里面AStar.findNodeInCloseList = function(self, row, col) for i = 1, #self.close_list do local node = self.close_list<i> if node.row == row and node.col == col then return node, i end end return nilend-- 在open_list中找到最佳点,并删除AStar.getMinNode = function(self) if #self.open_list < 1 then return nil end local min_node = self.open_list[1] local min_i = 1 for i,v in ipairs(self.open_list) do if min_node.f > v.f then min_node = v min_i = i end end table.remove(self.open_list, min_i) return min_nodeend-- 计算路径AStar.buildPath = function(self, node) local path = {} local sumCost = node.f -- 路径的总花费 while node do path[#path + 1] = {row = node.row, col = node.col} node = node.father end return path, sumCostend-- 估价h函数-- 曼哈顿估价法(用于不能对角行走)AStar.manhattan = function(self, row, col) local h = math.abs(row - self.endPoint.row) + math.abs(col - self.endPoint.col) return h * self.costend-- 对角线估价法,先按对角线走,一直走到与终点水平或垂直平行后,再笔直的走AStar.diagonal = function(self, row, col) local dx = math.abs(row - self.endPoint.row) local dy = math.abs(col - self.endPoint.col) local minD = math.min(dx, dy) local h = minD * self.diag + dx + dy - 2 * minD return h * self.costendreturn AStar
0 0
- A*算法lua实现
- lua实现A星最短路径算法
- A*寻路算法的lua实现
- A星寻路算法的Lua实现
- cocos2dx A*寻路算法lua实现
- lua实现的A星(a star)算法
- lua实现KMP算法
- A Star 的Lua实现
- A星寻路的lua实现
- 纯lua版A*算法优化测试
- 【每日算法】lua实现快排算法
- A*算法实现
- A* 算法实现
- A*算法实现
- A*算法C实现
- micropather实现A*算法
- A*算法的实现
- C#实现A*算法
- 创建带权限控制的git server(使用gitolite)
- Python Qt定义自己的对话框
- 【Android】滑动确认的按钮
- 如何搭建自己CDN服务器
- PyPDF2处理pdf文件的一个例子
- A*算法lua实现
- SpringMVC配置JSON、JSP、FreeMark多视图解析器配置
- 洛谷_p1082同余方程
- 【深入iOS开发】iOS仿射变换和3D变换
- 从零开始,搭建博客系统MVC5+EF6搭建框架(1),EF Code frist、实现泛型数据仓储以及业务逻辑
- (Mysql 五)触发器的使用
- setNeedsDisplay和setNeedsLayout
- 类与对象的学习
- outlook用处