跟我一起学“仓颉”算法-A*算法
·
目录
一、A*算法
A*算法(A-Star Algorithm)是一种启发式搜索算法,用于在加权图中寻找从起点到终点的最短路径或最优路径。它结合了Dijkstra算法(保证找到最短路径)和贪心最佳优先搜索(使用启发式函数快速引导搜索方向)的优点,是路径规划、游戏开发、机器人导航等领域的经典算法。
二、实现
package Algorithm.a
import std.collection.*
import std.math.*
public class Node {
public var x: Int64
public var y: Int64
// f(n) = g(n) + h(n)
public var f: Int64 = 0
// 从起点到当前节点的实际代价
public var g: Int64 = 0
// 启发式函数估计的当前节点到终点的代价
public var h: Int64 = 0
// 路径中的前一个节点
public var parent: Option<Node> = Option<Node>.None
public init(x: Int64, y: Int64) {
this.x = x
this.y = y
}
// 判断两个节点是否相同
public operator func ==(other: Node): Bool {
return this.x == other.x && this.y == other.y
}
}
public class AStar {
// 定义移动方向(8方向或4方向)
private static let DIRECTIONS_8 = [
[0, 1], [1, 0], [0, -1], [-1, 0],
[1, 1], [1, -1], [-1, 1], [-1, -1]
]
private static let DIRECTIONS_4 = [
[0, 1], [1, 0], [0, -1], [-1, 0]
]
// 启发式函数(默认使用曼哈顿距离)
private static func heuristic(a: Node, b: Node, useDiagonal!: Bool = false): Int64 {
let dx = abs(a.x - b.x)
let dy = abs(a.y - b.y)
if (useDiagonal) {
// 或者使用欧几里得距离:
let result = Float64(dx * dx + dy * dy)
return Int64(sqrt(result))
} else {
return dx + dy // 曼哈顿距离
}
}
// 检查位置是否有效(在网格内且不是障碍物)
private static func isValid(grid: Array<Array<Int64>>, x: Int64, y: Int64): Bool {
return x >= 0 && x < grid.size && y >= 0 && y < grid[0].size && grid[x][y] == 0
}
// A*算法主函数
public static func findPath(grid: Array<Array<Int64>>, start: Node, end: Node, allowDiagonal!: Bool = false): ArrayList<Node> {
// 创建开放列表(优先队列)和关闭列表(Set)
let openList = ArrayList<Node>()
let closedList = HashSet<String>()
// 初始化起点
start.g = 0
start.h = heuristic(start, end, useDiagonal: allowDiagonal)
start.f = start.g + start.h
openList.set(start.f, start)
// 记录已访问节点的键值
let getNodeKey = {node: Node => "${node.x},${node.y}"}
while (!openList.isEmpty()) {
// 获取f值最小的节点
let currentNode = openList.remove(0)
// 如果到达终点,回溯路径
if (currentNode == end) {
let path: ArrayList<Node> = ArrayList<Node>()
var node: Option<Node> = currentNode
while (node.isSome()) {
path.prepend(node.getOrThrow())
node = node.getOrThrow().parent
}
return path
}
// 将当前节点加入关闭列表
closedList.put(getNodeKey(currentNode))
// 获取相邻节点
let directions: Array<Array<Int64>> = if (allowDiagonal) {
DIRECTIONS_8
} else {
DIRECTIONS_4
}
for (dir in 0..directions.size) {
let newX = currentNode.x + directions[dir][0]
let newY = currentNode.y + directions[dir][1]
// 检查新位置是否有效
if (isValid(grid, newX, newY)) {
continue
}
let neighbor = Node(newX, newY)
let neighborKey = getNodeKey(neighbor)
// 如果邻居节点在关闭列表中,跳过
if (closedList.contains(neighborKey)) {
continue
}
// 计算新的g值(对角线移动代价可能更高)
let diagonalCost: Int64 = if (allowDiagonal && directions[dir][0] != 0 && directions[dir][1] != 0) {
Int64(sqrt(2.0))
} else {
1
}
let tentativeG = currentNode.g + diagonalCost;
// 如果邻居节点不在开放列表中,或者找到更短的路径
if (!contains(openList, neighbor) || tentativeG < neighbor.g) {
neighbor.parent = currentNode
neighbor.g = tentativeG
neighbor.h = heuristic(neighbor, end, useDiagonal: allowDiagonal)
neighbor.f = neighbor.g + neighbor.h
// 如果邻居节点不在开放列表中,加入开放列表
if (!contains(openList, neighbor)) {
openList.set(neighbor.f, neighbor)
}
}
}
}
// 开放列表为空且未找到路径
return ArrayList<Node>()
}
private static func contains(nodeList: ArrayList<Node> ,node: Node): Bool {
for (i in 0..nodeList.size) {
if (nodeList[i] == node) {
return true
}
}
return false
}
}
测试代码
package Algorithm
import Algorithm.a.*
main(): Int64 {
// 示例网格:0表示可通行,1表示障碍物
let grid = [
[0, 0, 0, 0, 0],
[0, 1, 1, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 1, 1, 0],
[0, 0, 0, 0, 0]
]
let start = Node(0, 0)
let end = Node(4, 4)
// 查找路径(不允许对角线移动)
let path = AStar.findPath(grid, start, end, allowDiagonal: false)
if (!path.isEmpty()) {
println("找到路径:")
for (node in 0..path.size) {
println("(${path[node].x},${path[node].y})")
}
} else {
println("未找到路径")
}
return 0
}
三、小结
本章为大家详细的介绍了仓颉数据结构与算法中A*算法的内容,下一章,为大家带来IDA*算法的内容。最后,创作不易,如果大家觉得我的文章对学习仓颉数据结构与算法有帮助的话,就动动小手,点个免费的赞吧!收到的赞越多,我的创作动力也会越大哦,谢谢大家🌹🌹🌹!!!
昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链
更多推荐

所有评论(0)