AStar算法

使用A*算法 计算路径, 算法测试中使用excel文件提供数据, 算法完成后,在excel中显示找到的路径

主要代码:

  /// <summary>
        /// 使用A* 算法
        /// </summary>
        /// <param name="graph"> 整个立库节点信息  </param>
        /// <param name="startNode">开始的节点编号</param>
        /// <param name="endNode">目标点的节点编号</param>  
        /// <returns>是否有用的路径</returns>
        public bool SearchPath(List<IPathNode> graph, IPathNode startNode, IPathNode endNode)
        {
            init(graph);

            APathNode startPathNode = GetAPathNode(startNode);
            APathNode endPathNode = GetAPathNode(endNode);

            if (startPathNode == null || endPathNode == null)
            { //节点不存在
                return false;
            }

            try
            {
                //将起点加入开表
                openList.Add(startPathNode);
                while (openList.Count > 0)
                {
                    APathNode currentNode = openList.Dequeue();//取出第一元素,在开表中删除

                    //将当前的节点移除开表,放入闭表中(将当前的节点标记为已评估节点)  
                    closeList.Add(currentNode); 

                     //如果评估点等于终点,找到寻路路径 ,结束寻路
                    if (currentNode == endPathNode)
                    {
                        RetracePath(endPathNode);
                        return true;
                    }
                    else
                    {
                        //遍历评估节点 
                        List<APathNode> neighborNodes = GetNeighborNodes(currentNode);
                        foreach (APathNode neiNode in neighborNodes)
                        {
                            //如果闭表已经有该点(该点已经被评估过)或者该点是障碍物
                            if (!neiNode.NodeObj.IsAvailable || closeList.Contains(neiNode))
                            {
                                continue;
                            }

                            //新的 起点->neighbor =当前点->邻近点 +当前点->起点
                            //计算 该邻近点到起点总花费=当前到邻近点的距离+当前点到起点的花费  
                            float newGGost = GetGCost(currentNode, neiNode);

                            //1.如果邻近点到起点总花费<之前已计算的花费,说明之前的路径存在绕远路,将邻近点的上一节点改为当前点
                            //  因为计算过邻近点Gcost,所有一定存在开表中,后面值为false
                            //2》.开表中不包含邻近点,该节点没有被遍历
                            bool flagContain = openList.Contains(neiNode); //是否包含相邻节点
                            if (newGGost < neiNode.GCost || !flagContain)
                            {
                                //更新邻近点的三大代价,将邻近点的上一节点设置为当前节点
                                neiNode.GCost = newGGost;
                                neiNode.HCost = GetHCost(neiNode, endPathNode);
                                neiNode.FCost = GetFCost(neiNode);
                                neiNode.PNode = currentNode;

                                //2》.如果开表中不包含邻近点,该节点没有被遍历
                                if (!flagContain)
                                {
                                    openList.Add(neiNode);
                                }
                            } //end if 
                        } // end foreach 
                    }
                } //end  while
            }
            finally
            {
                //清除过程数据
                closeList.Clear();
                openList.Clear();
                mapNodes.Clear();
            }

            return false;
        }

 

参考:【A星算法】A星寻路算法详解(小白也可以看懂+C#代码+零基础学习A*)-优快云博客

### A*算法介绍 A* (A-star) 算法是一种用于解决最短路径问题的启发式搜索算法,在众多同类算法中最为常用[^1]。该算法不仅能够高效地找到两点之间的最优路径,还因其灵活性而被广泛应用于各种场景下的路径规划。 #### 原理概述 核心在于通过评估函数f(n)=g(n)+h(n),其中n代表当前节点;g(n)是从起点到此节点的实际成本;h(n)则是从这个节点到达目的地的一个估算值(也称为启发式函数)[^2]。为了使计算更加精确并加快收敛速度,通常会选择合适的启发方式来定义h(n)。 #### 数据结构设计 对于每一个可能成为路径一部分的位置都会创建一个`Node`对象表示它,并记录下三个重要属性:位置坐标、累计开销以及预估剩余路程长度。此外还包括指向父级节点的链接以便回溯最终路线图[^4]: ```cpp struct Point { int x, y; Point(int _x, int _y): x(_x), y(_y){} }; struct Node { Point point; double g, h, f; Node *parent; Node(Point pt, double costToStart, double estimatedCostToEnd, Node* prev = nullptr) : point(pt), g(costToStart), h(estimatedCostToEnd), f(g + h), parent(prev) {} }; ``` 这里采用欧氏距离作为两个相邻顶点间边权度量标准之一,即直线上两点间的直线距离。 #### 实现流程 - 初始化开放列表OpenList和关闭列表CloseList为空集; - 将初始状态加入OpenList; - 当OpenList不为空时循环执行以下操作直到找到目标或者无法继续探索为止: - 从未处理过的候选集中选取具有最小f值得元素node_current移至ClosedList; - 对于所有邻接未访问过的新结点new_node, 如果新结点不在OpenList也不在ClosedList,则将其添加入OpenList并将current设为其前驱; 若已经在OpenList里存在相同坐标的旧版本old_version且经由current前往更优(即新的g较小),则更新其前置关系及相应费用。 一旦达到终点或遍历结束仍未发现可行方案,则返回所获得的最佳路径或是报告失败消息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值