a*算法初步(源代码)

A*寻路算法,循序渐进,附完整源码 A*寻路算法—循序渐进(附完整源码) 用途 ​ A*寻路算法的一般用途即为灵活地寻找初始点到目标点的最短路径。 概述 ​ 灵活是A*算法更为注重的特性,可以任意添加障碍物,可以对不同地形的寻路损耗赋予不同的权重,可以设置优先级等等。最短路的算法有很多,Dijkstra,BFS(广度优先搜索)等等,本文着重介绍基于BFS实现的A星寻路算法。 BFS算法原理 ​ 在介绍A星算法前,先介绍一下BFS求最短路的方法。广度优先搜索主要用到的是队列,求最短路的基本思路即为,每走一步都遍历以当前格子的九宫格范围内满足条件 阅读详情

关于a*算法的文章和代码有很多,这里是我整理的一份源代码,从别人的例子中修改过来的。在这个代码示例中加入了地图信息对寻址结果的影响,可以用在包含不同种类的地形信息的地图中寻址。由于代码可以调试,你可以看清楚每一个步骤是怎么做的,在这里我就不多做讲解了。
#include <windows.h>
#include <stdio.h>

#define COLS 3 //地图
#define ROWS 3
#define TOTAL_TILES 9

#define TileNum( x, y ) ( y * COLS + x + 1 ) //判断是地图上的第几个格子

struct NODE {
 long f,h,i; //在这里,我增加了一个i函数,主要用于地图信息
 int g;
 int x,y;
 int NodeNum;
 struct NODE *Parent;
 struct NODE *Child[8];       /* a node may have upto 8+(NULL) children. */
 struct NODE *NextNode;       /* for filing purposes */
};

struct NODE *OPEN;
struct NODE *CLOSED;

int TileMap[TOTAL_TILES] = { /  
1, 1, 1, /
1, 2, 1, /
1, 1, 1
};
//地图信息,目前由(0,0)点到(2,2)点的寻址结果是(0,0)->(1,1)->(2,2)。如果中间的那个2修改成4,表明不能行走或者是沼泽路面行走困难,寻址结果是(0,0)->(0,1)->(1,2)->(2,2)。

struct STACK {
    struct NODE *NodePtr;
    struct STACK *NextStackPtr;
};
struct STACK *Stack;

void Push(struct NODE *Node)
{
    struct STACK *tmp;
    tmp = ( struct STACK *)calloc(1,sizeof(struct STACK));
    tmp->NodePtr = Node;
    tmp->NextStackPtr = Stack->NextStackPtr;
    Stack->NextStackPtr = tmp;
}

struct NODE *Pop()
{
    struct NODE *tmp;
    struct STACK *tmpSTK;
    tmpSTK = Stack->NextStackPtr;
    tmp = tmpSTK->NodePtr;
    Stack->NextStackPtr = tmpSTK->NextStackPtr;
    free( tmpSTK );
    return( tmp );
}

struct NODE *CheckOPEN(int tilenum)
{
 struct NODE *tmp = OPEN->NextNode;
 while( tmp ) {
  if( tmp->NodeNum == tilenum )
   return( tmp );
  else
   tmp = tmp->NextNode;
 }
 return( NULL );
}

struct NODE *CheckCLOSED(int tilenum)
{
 struct NODE *tmp = CLOSED->NextNode;
 while( tmp ) {
  if( tmp->NodeNum == tilenum )
   return( tmp );
  else
   tmp = tmp->NextNode;
 }
 return( NULL );
}

void PropagateDown(struct NODE *Old)
{
 int c,g;
 struct NODE *Child, *Father;

 g = Old->g;
 for( c = 0; c < 8; c ++ ) {
  if( ( Child = Old->Child[c] ) == NULL ) break;
  if( g + 1 < Child->g ) {
   Child->g = g + 1;
   Child->f = Child->g + Child->h + Child->i;
   //Child->f = Child->g + Child->h;
   Child->Parent = Old;
   Push( Child );
  }
 }
 while( Stack->NextStackPtr != NULL ) {
  Father = Pop();
  for( c = 0; c < 8; c ++ ) {
   if( ( Child = Father->Child[c] ) == NULL ) break;
   if( Father->g + 1 < Child->g ) {
    Child->g = Father->g + 1;
    Child->f = Child->g + Child->h + Child->i;
    //Child->f = Child->g + Child->h;
    Child->Parent = Father;
    Push( Child );
   }
  }
 }
}

void Insert(struct NODE *Successor)
{
 struct NODE *tmp1,*tmp2;
 long f;

 if(OPEN->NextNode == NULL) {
  OPEN->NextNode = Successor;
  return;
 }

 f = Successor->f;
 tmp1 = OPEN;
 tmp2 = OPEN->NextNode;
 while( ( tmp2 != NULL ) && ( tmp2->f < f ) ) {
  tmp1 = tmp2;
  tmp2 = tmp2->NextNode;
 }
 Successor->NextNode = tmp2;
 tmp1->NextNode = Successor;
}

void GenerateSucc(struct NODE *BestNode,long x, long y, long dx, long dy)
{
 int g, TileNumS, c;
 struct NODE *Old,*Successor;

 TileNumS = TileNum( x, y );
 //g = BestNode->g + TileMap[TileNumS];
 g = BestNode->g + 1;

 if( ( Old = CheckOPEN(TileNumS) ) != NULL ) {
  for( c = 0; c < 8; c ++ ) {
   if( BestNode->Child[c] == NULL ) break;
  }
  BestNode->Child[c] = Old;
  if( g < Old->g ) {
   Old->Parent = BestNode;
   Old->g = g;
   Old->f = g + Old->h + Old->i;
   //Old->f = g + Old->h;
  }
 }
 else if( ( Old = CheckCLOSED(TileNumS) ) != NULL ) {
  for( c = 0; c < 8; c ++ ) {
   if( BestNode->Child[c] == NULL ) break;
  }
  BestNode->Child[c] = Old;
  if( g < Old->g ) {
   Old->Parent = BestNode;
   Old->g = g;
   //Old->f = g + Old->h;
   Old->f = g + Old->h + Old->i;
   PropagateDown( Old );
  }
 }
 else {
  Successor = (struct NODE *)calloc(1,sizeof( struct NODE ));
  Successor->Parent = BestNode;
  Successor->NodeNum = TileNumS;
  Successor->g = g;
  //Successor->h = abs( x - dx ) + abs( y - dy );
  Successor->h = ( x - dx ) * ( x - dx ) + ( y - dy ) * ( y - dy );
  Successor->i = TileMap[Successor->NodeNum-1];
  Successor->f = g + Successor->h + Successor->i;
  //Successor->f = g + Successor->h;
  Successor->x = x;
  Successor->y = y;
  Insert(Successor);
  for( c = 0; c < 8; c ++ ) {
   if( BestNode->Child[c] == NULL ) break;
  }
  BestNode->Child[c]=Successor;
 }
}

void GenerateSuccessors(struct NODE *BestNode,long dx,long dy)
{
 long x,y;

 /* Upper-Left  */
 x = BestNode->x - 1; y = BestNode->y - 1;
 if( x >= 0 && y >= 0 )
  GenerateSucc(BestNode,x,y,dx,dy);

 /* Upper       */
 x = BestNode->x; y = BestNode->y - 1;
 if( y >= 0 )
  GenerateSucc(BestNode,x,y,dx,dy);

 /* Upper-Right */
 x = BestNode->x + 1; y = BestNode->y - 1;
 if( x < COLS && y >= 0 )
  GenerateSucc(BestNode,x,y,dx,dy);

 /* Right       */
 x = BestNode->x + 1; y = BestNode->y;
 if( x < COLS )
  GenerateSucc(BestNode,x,y,dx,dy);

 /* Lower-Right */
 x = BestNode->x + 1; y = BestNode->y + 1;
 if( x < COLS && y < ROWS )
  GenerateSucc(BestNode,x,y,dx,dy);

 /* Lower       */
 x = BestNode->x; y = BestNode->y + 1;
 if( y < ROWS )
  GenerateSucc(BestNode,x,y,dx,dy);

 /* Lower-Left  */
 x = BestNode->x - 1; y = BestNode->y + 1;
 if( x >= 0 && y < ROWS )
  GenerateSucc(BestNode,x,y,dx,dy);

 /* Left        */
 x = BestNode->x - 1; y = BestNode->y;
 if( x >= 0 )
  GenerateSucc(BestNode,x,y,dx,dy);
}

struct NODE *ReturnBestNode(void)
{
 struct NODE *tmp;
 tmp = OPEN->NextNode;
 OPEN->NextNode = tmp->NextNode;
 tmp->NextNode = CLOSED->NextNode;
 CLOSED->NextNode = tmp;
 return(tmp);
}

struct NODE *FindPath(long sx, long sy, long dx, long dy)
{
 struct NODE *Node, *BestNode;
 int TileNumDest = TileNum(dx,dy);
 OPEN = (struct NODE *)calloc(1,sizeof( struct NODE ));
 CLOSED = (struct NODE *)calloc(1,sizeof( struct NODE ));

 Node=(struct NODE *)calloc(1,sizeof( struct NODE ));
 Node->NodeNum = TileNum(sx,sy);
 Node->g = 0;
 //Node->h = abs( sx - dx ) + abs( sy - dy );
 Node->h = ( sx - dx ) * ( sx - dx ) + ( sy - dy ) * ( sy - dy );
 Node->i = TileMap[Node->NodeNum-1];
 Node->f = Node->g + Node->h + Node->i;
 //Node->f = Node->g + Node->h;
 Node->x = sx;
 Node->y = sy;

 OPEN->NextNode=Node;
 for (;;) {
  BestNode = (struct NODE *)ReturnBestNode();
  if( BestNode->NodeNum == TileNumDest ) break;
  GenerateSuccessors( BestNode, dx, dy );
 }
 return BestNode;
};

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
 Stack=( struct STACK *)calloc(1,sizeof(struct STACK));
 struct NODE * Path = FindPath( 0, 0, 2, 2 );
 return 0;
}

虽然用上面的算法可以找到目的地址,但是目前有几个问题:
1)效率问题:当起点到终点的路径不存在的时候,a*的花费比较大,应该加如预寻址算法或者改进当前算法。
2)当地图中不能走的地方边边角角较多的时候,寻址的结果中折线较多,此时可以寻求其次优解,将路径美化。
3)寻址方向目前有8个,对应于2D的八个方向,感觉应该能扩展到3D空间当中,做一个3D的a*寻址。3D寻址的时候应该是26个方向。

A*算法求解迷宫问题(算法讲解与证明、python实现与可视化) A*算法是一种有序搜索算法,其特点在于对估价函数的定义上。对于一般的有序搜索,总是选择f值最小的节点作为扩展节点。因此,f是根据需要找到一条最小代价路径的观点来估算节点的,所以,可考虑每个节点n的估价函数值f(n)有两个分量:从起始节点到节点n的代价g(n)以及从节点n到达目标节点的代价h(n),即f(n)=g(n)+h(n)。 迷宫问题是实验心理学中一个古典问题。迷宫从入口到出口可能有若干条通路,本实验要求求出从入口到出口的最短路径。 阅读详情

相关推荐

Python A*算法的简单实现

总起 A*算法常用于游戏的寻路中,用于求解静态路网中的最短路径,是最有效的直接搜索方法。 这次正好花了几天时间学习了一下Python,便拿这个算法做了一下练习。这篇文章也会对其思路做一个简单介绍。 文章中的源码可以在 GitHub - anguangzhihen/PythonTest 中的AStarTest.py找到。 算法思路 A*算法实际是由广度优先遍历和Dijkstra算法演变而来的: 1.广度优先遍历主要是通过从起点依次遍历周围的点而寻找最优的路径; 2.Dijkstra基

暗光之痕的博客 1万+

Navigation中A*算法源码解释

A*算法原理 A*算法原理在之前的文章中也有提到,这次主要就是和Navigation中对应起来。 A*算法原理 A*源码 示例图 nx_ = 6, ny_ = 6; 其中A为起始点,(1,2)。B为goal_i 为(4,4)。 calculatePotential 函数是对堆中Pentential值最小的索引值取出,然后进行下一次的更新。 其中toIndex函数返回值为 start_x + nx_*start_y; 即索引 queue_.clear(); //首先将堆清空 //x,y点是全部数据的第几

lovebc的博客 2221

实验三 基于A*算法寻路迷宫

代码如下

weixin_45986866的博客 3985

混合A*源码解读(c++)

基于ros中通过slam建立的栅格地图,使用混合A*进行路径规划。 首先是run_hybrid_astar.cpp: #include "hybrid_a_star/hybrid_a_star_flow.h" #include "3rd/backward.hpp" #include <ros/ros.h> namespace backward { backward::SignalHandling sh; } int main(int argc, char **argv) { ros:

hooksten的博客 2912

A* 算法实现及代码下载(多种方式实现,加路径修正)

A*算法的介绍在下面这篇文章中说的很详细了,就不在这阐述了,这篇文章主要是介绍自己的一些理解,一些重点的解释,和效果展示。同样给出了代码编写的思路。代码会给下载链接。 A*算法可参考文章(介绍的很好):http://www.cppblog.com/christanxw/archive/2006/04/07/5126.html 代码已上传: 1)从txt文本读取地图命令

lmnxjf的专栏 7411

【自动驾驶轨迹规划之A*算法】

1 A*算法简介 A*算法是一种静态路网中求解最短路径有效方法,也是解决许多搜索问题的有效算法。算法中的距离估算值与实际值越接近,最终搜索速度越快。A*算法的最大特点在于有启发性。 2 A*算法原理及流程 ...

weixin_65089713的博客 5169

路径规划算法之A*算法(附代码及函数功能和参数详细注释)

A*(A star)算法是一种在图或网络中寻找从起始节点到目标节点的最短路径的启发式搜索算法。A* 算法结合了 Dijkstra 算法的最短路径搜索和贪心算法的启发式搜索,因此在许多情况下比其他算法更高效地找到最优路径。它常用于路径规划、游戏中的路径查找以及人工智能领域的图搜索问题。A* 算法的主要思想是维护两个集合:一个是已探索的节点集合,另一个是待探索的节点集合。算法在每一步选择待探索集合中的节点,计算该节点的代价(包括实际代价和启发式代价),然后选取代价最小的节点进行探索。

acanab的博客 4216

详细介绍用MATLAB实现基于A*算法的路径规划(附完整的代码,代码逐行进行解释)(一)--------A*算法简介和环境的创建

   本系列文章主要介绍基于A*算法的路径规划的实现,并使用MATLAB进行仿真演示。    一、 A*算法简介       A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法,也是解决许多搜索问题的有效算法。算法中的距离估算值与实际值越接近,最终搜索速度越快。      公式表示为: f(n)=g(n)+h(n),其中, f(n) 是从初始状态经由状态n到目标状态的代价估计,g(n) 是在状态空间中从初始状态到状态n的实际代价,h(n) 是从状态n到目标状态的最佳路径的估计代价。

慕羽★的博客 7万+

A*算法

Amit's A star Page中译文   译序 这篇文章很适合A*算法的初学者,可惜网上没找到翻译版的。本着好东西不敢独享的想法,也为了锻炼一下英文,本人译了这篇文章。 由于本人英文水平非常有限,六级考了两次加一块不超过370分,因此本译文难免存在问题。不过也算是抛砖引玉,希望看到有更多的游戏开发方面的优秀译作出现,毕竟中文的优秀资料太少了,中国的游戏开发者的路不好走

coutamg的博客 3万+

ROS环境下A*路径规划算法源代码解析

A* 算法最早于 20 世纪 60 年代在人工智能领域被提出,是启发式搜索算法中的一种,主要用于解决路径规划问题。它通过评估路径的代价来估计从起始点到目标点的最小代价路径。该算法广泛应用于游戏开发、机器人导航、网络路由以及各种需要最优路径计算的场合。A算法之所以受到青睐,是因为其具备如下特性:可以找到最优路径,效率高,且扩展性好。此外,A算法还具有良好的可定制性,可以根据不同应用的需求对启发函数进行调整,以达到更佳的性能表现。

weixin_42591908的博客 1198

A*算法改进程序

借鉴了原程序,稍加改进,提供了一种新思路,跟大家交流

15数码问题(A*算法)

一、题目  设计一个启发函数,利用A*算法求解15数码问题。 初始状态 5 1 2 4 9 6 3 8 13 15 10 11 14 0 7 12 目标状态 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1...

lph-China的博客 2万+

A*算法源码

A*算法的具体实现,为了以后扩展做了一下封装,可以不继承现在的类,直接用,对核心代码没有影响

A*算法总结

源代码传送门 文章目录A*算法导言利用A*算法解决八数码问题八数码问题 比较两种估计函数测试对比验证h1(n)的单调性以及验证凡A*算法挑选出来求后继的点n必定满足 `h(ni)≤1+h(nj)`利用A*算法求解九数码问题能否达到目标状态的判断方法 A*算法 A* 算法,A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法,也是解决许多搜索问题的有效算法。算法中的距离估算...

lllllyt的博客 2534

A*算法 C#源代码

此为用C#写的A*算法源代码 using System; using System.Collections.Generic; using System.Text; using System.Drawing; namespace EtSoft.AStarLib { public class AStar { private StarNodeCollection openList = new StarNodeCollection(); private StarNodeCollection closeList = new StarNodeCollection(); public StarNode currentNode = null; #region 构造函数 /// <summary> /// 使用指定的地图对象、起点和终点初始化A星算法 /// </summary> /// <param name="map">地图对象</param> public AStar(Map map) { this.map = map; } /// <summary> /// /// </summary> /// <param name="map">地图对象</param> /// <param name="start">起点坐标</param> /// <param name="end">终点坐标</param> public AStar(Map map, Point start, Point end) : this(map) { this.start = new StarNode(start); this.end = new StarNode(end); openList.Add(new StarNode(start)); //AddStartNodeToOpenList(this.start); } /// <summary> /// /// </summary> /// <param name="map">地图对象</param> /// <param name="startX">起点X坐标</param> /// <param name="startY">起点Y坐标</param> /// <param name="endX">终点X坐标</param> /// <param name="endY">终点Y坐标</param> public AStar(Map map, int startX, int startY, int endX, int endY) : this(map, new Point(startX, startY), new Point(endX, endY)) { } #endregion #region 属性 protected Map map; /// <summary> /// 地图数据 /// </summary> public Map Map { get { return map; } set { map = value; } } private StarNode start = null; /// <summary> /// 起点坐标,如果没有设置起点,返回null /// </summary> public StarNode Start { get { return start; } set { start = value; openList.Clear(); openList.Add(start); //AddNodeToOpenList(start); } } private StarNode end = null; /// <summary> /// 终点坐标,如果没有设置终点,返回null /// </summary> public StarNode End { get { return end; } set { end = value; } } private StarNodeCollection path; /// <summary> /// 返回路径节点集合,没有路径则返回null /// </summary> public StarNodeCollection Path { get { return path; } } private bool allDirection = false; /// <summary> /// true,允许八方向寻路 /// </summary> public bool AllDirection { get { return allDirection; } set { allDirection = value; } } #endregion /// <summary> /// 开始寻路 /// </summary> public void StartSearchPath() { if (start == null) throw new InvalidNodeException(InvalidNodeTypes.NoStart); if (end == null) throw new InvalidNodeException(InvalidNodeTypes.NoEnd); path = null; openList.Clear(); closeList.Clear(); currentNode = start; SearchPath(currentNode); } //寻路递归,受保护的虚方法,允许在子类重写寻路算法 protected virtual void SearchPath(StarNode starNode) { //currentNode = starNode; openList.Remove(starNode); closeList.Add(starNode); AddNodeToOpenList(); if (closeList.Contains(end)) { //如果终点在关闭列表中,找到路径 StarNode node=starNode.Parent; path = new StarNodeCollection(); do { path.Add(node); node = node.Parent; } while (node != null && !node.Equals(start)); path.Reverse(); return; } else if (openList.Count == 0) { //终点不在关闭列表,开放列表已空,没有可通行的路径 return; } currentNode = GetNextNode(); //迭代过程 SearchPath(currentNode); } /// <summary> /// 获得当前节点的下一个最佳节点 /// </summary> /// <returns></returns> public StarNode GetNextNode() { openList.SortByF(); return openList[0]; } /// <summary> /// 把当前点周围可通过的点加入到开放列表中 /// </summary>

ClassAStart(经典A*算法C++版)

初识A*算法和深入A*算法中提到的源程序,也是最经典的A* C++源代码。

A*算法简单实现(C语言)

简单的A*算法,后续考虑更复杂情况,一个C文件即可,VS,linux等都可以直接编译运行。后面首先考虑加上图形化界面(地图可以自己输入确定也考虑下) A*算法原理 这个很简单就不多说了,根据f = g + h。像是欧几里得距离,绝对距离等等,还有周围8节点以及4节点(16节点)对算法的影响也都是同样的道理,简单修改即可 算法流程 //算法流程 //构建地图 //把起点放入open list //w...

weixin_42352795的博客 4255

A*算法源码(这是简单版本,更优版本已经上传)

A星寻路算法(A*算法)源码实现,用MFC程序模拟动态寻路过程。只实现了最简单的A*算法,MFC消息处理的也不好,仅作参考。

上一篇: 建立自己的3D模型文件
dfman
博客等级 码龄24年 1粉丝 18原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值