运动规划入门 | 2. 白话A*,从原理到Matlab实现

3985
107
2020年4月28日 17时44分

书接上回,上一次我们讲完了Dijkstra,如果小伙伴们有印象的话,肯定还记得在上一篇的文末,我们提到了Dijkstra的致命缺点:处理大地图时效率低下。那么今天我们就来看看Dijkstra的近亲A*究竟做出了哪些改变来解决效率问题?

 

1

 

1. A*原理详解

我们知道,Dijkstra之所以效率低下,就是因为Dijkstra对地图里所有的相邻栅格都“一视同仁”,所以Dijkstra在运行的时候会花费很多精力去访问一些对规划结果没有贡献的节点。形象地说,Dijkstra就像是洪水一般四处扩散,缺乏目的性。而A*恰恰就是在目的性这一点上下了功夫,在我看来A*就是一波有目的、有梦想的洪水,它知道自己该往哪个地方流。

 

那么A*究竟是做了什么改变而变得高效的呢?

1.1 路径规划中的贪婪算法

由于实际上A*可以看成Dijkstra和贪婪算法的结合体,使得A*同时具备了Dijkstra和贪婪算法的优势。所谓贪婪算法没有一种固定的形式,算法的重点在于你贪婪的策略。在路径规划中的贪婪算法说白了就是:每次都朝着四周离终点最近的点移动(离终点的总代价值最小)。那么显而易见的,在贪婪算法在做路径规划时,每次考虑的都是当前位置的四周范围内的最优解,这是一种局部最优解,贪婪算法的优势在于可以迅速地找到终点完成规划,缺点是:很可能规划出来的并不是全局最优的路径,某种意义上来说,这是一种牺牲“精度”换取“速度”的规划方式。

 

下图是贪婪算法在20*20的地图中的表现:

 

2

 

1.2 A*的“智慧”来源:评价函数和启发函数

前面我们说了A*可以看作Dijkstar和贪婪算法的结合,Dijkstar在规划中注重的是当前节点到起点的总代价值,也称后退代价。而贪婪算法注重的是当前节点到终点的总代价值,也称前进代价。那么所谓的结合实际上就是说,A*同时考虑到了后退代价和前进代价。从表达式上看就是:后退代价+前进代价

 

下式中的g(n)表示当前节点的后退代价,h(n)表示当前节点的前进代价,但是更多人称h(n)为启发函数。而右边的f(n)则被称为评价函数。

 

3

 

评价函数将会计算当前节点的后退、前进代价的总和,这个数值表明这个节点在规划中的重要程度,或者说是优先考虑程度。在A*中节点的评价函数返回值越小就表明该节点的重要性越高,或者说更应该被优先考虑。A*算法在每轮迭代中都会选择未完成列表中评价函数返回值最小的节点。那么有了评价函数的介入,A*算法看待节点的态度就不再是“一视同仁”了,根据评价函数的结果,A*会将节点分“三六九等”,那么A*就获得了目的性。

 

我们先来琢磨琢磨Dijkstar的代价函数为什么不具备目的性,老规矩举个例子:在一个九宫格里,假设中心的那一格是起点,那么对整个九宫格运行代价函数后得到的结果就会像下面这样:起点的代价值为0,因为只需要移动一次能到达所以跟起点相邻的4个方格的代价值是1,以此类推,四个角上的代价值就为2。

 

4

 

上面这个例子乍一看好像没啥问题,但是当我们将网格扩大到5*5,并且加入了终点G,如下图所示:右下角的节点作为终点,如果按照Dijkstar的代价函数来看的话,其余三个角上的节点相对起点的代价是一样的,都是4。但是考虑到搜索算法的效率,这三个角的方向都是在远离终点G,简直就是“南辕北辙”。朝着这三个方向进行的探索都是在做无用功。这便是Dijkstar的盲目性,由于其盲目性,所以Dijkstar会做很多无用的搜索。但是并不是说这种盲目的搜索是不可取的。盲目搜索的优点在于:Dijkstar可以尽可能多地探索地图,当我们修改终点的位置时,Dijkstar不需要做过多的重复规划,由于先前第一次探索的时候已经完成了带有父节点的代价地图,在实际地图没有发生改变的前提下,生成的代价地图是可以重复使用的。

 

5

 

但是为了满足大部分情况下我们更希望规划算法能够快速地给出特定的解的需求,于是A*的评级函数便有了其用武之地。

 

1.3 启发函数的选择

和盲目搜索相对的,这种有目的性的搜索被称为启发式搜索(Heuristically Search)。启发式搜索存在的意义就是:缩小搜索范围,提高搜索的目的性,提高效率。

 

前面说过A*是Dijkstar和贪婪算法的组合,那么g(n)和h(n)占f(n)的比重就决定了A*的行为,假如h(n)占更高的比重,那么A*就表现得更像贪婪算法,假如g(n)占更高的比例,那么A*就表现得更像Dijkstar。

 

举个极端例子,当我们设h(n) = 0的时候,A*便会退化回Dijkstar。当我们设g(n) = 0时,A*就变成了贪婪算法。所以权衡好g(n)和h(n)的比例是至关重要的。我们一般会通过修改启发函数来调节A*的行为。那怎么样才算好的行为呢?好的规划行为无法两个要点:能找到最优解的前提下,效率最高。比如Dijkstar的规划行为就属于能找到最优解,但是效率不高。而贪婪算法恰好相反,效率高,但是不能保证找到最优解。

 

题外话:A算法和A*算法的区别,其实两者的评价函数形式均为:f(n) = g(n)+h(n),只不过A*是选择了“最优启发函数“的A算法。也就是说A*是A算法中”最优的“。所以A*是A算法的子集。但是一般情况下我们并不会刻意区分这两者,所以全文就统称为A*。

 

那么我们该如何得到一个合适的启发函数呢?(注:讨论“启发函数的选择”的这部分内容会涉及比较多的概念问题,总体来说比较绕。如果是只想了解A*如何实现的小伙伴,可以跳过这部分内容,从曼哈顿距离开始看)

 

一个好的启发函数需要满足几个约束:1.满足可纳性;2.满足一致性;3.目标状态的h(n) = 0

 

1.4 什么叫可纳性?

如果从起点到终点有一条路径,而搜索算法一定能在有限步内终止并找到一个最优解(代价最低),则这个搜索算法称为可采纳的(可纳)。A*算法要满足可纳性是有条件的,它需要满足:

 

6

 

其中h*(n)表示最小前进代价,也就是当前节点到终点的最小距离(比如直线距离)。该不等式表明了一个事实:启发函数不能高估当前节点到终点的距离。

 

1.5 什么叫一致性?

一致性的意思就是:对每个节点n的任意后继节点n’,节点n的估计前进代价不大于从n到n’的总代价与n’的估计前进代价之和。其表达式如下,其中c(n,n’)表示两点之间的代价值。

 

7

 

实际上这就是一道三角不等式:

 

8

 

该表达式可以通过下面的化简,变为f(n’) >= f(n),所以一致性也就是在表示一个约束:当前节点的总评价值不大于任意后继节点的总评价值。

 

9

 

在A*中,只要h(n)满足一致性,那么h(n)必然满足可纳性。证明过程过于繁琐,此处就不再赘述。小伙伴们就把它看成一个定理吧。

 

1.6 曼哈顿距离(Manhattan Distance)

在只允许上下左右移动的栅格地图中,我们一般使用曼哈顿距离作为启发函数,用于估算两点之间的距离。因为曼哈顿距离即满足一致性和“h(goal) = 0“的特性,而且算法简单,计算成本低。

 

曼哈顿距离的定义式如下,其实就是将两点的坐标差值相加。

 

10

 

那么使用曼哈顿距离作为启发函数,根据上面我们举例的5*5地图,对其执行评分函数将会是什么结果呢?下图的等式右边第一个矩阵表示的是g(n)(后退代价)的各个值,第二个矩阵表示的是曼哈顿距离(前进代价)的各个值,两个矩阵相加后得到等式右边的矩阵f(n),可以看到,f(n)的矩阵的值带有很强的方向性,当我们使用这个矩阵作为代价地图,在此基础上执行类似之前Dijkstar一样的的迭代的话,其实就是A*了。

 

11

 

1.7 其他启发函数

当然,启发函数不单单曼哈顿距离一种,常见的还有欧式距离、切比雪夫距离等等。

 

欧式距离就是我们最熟悉的两点间距离的计算方式:

 

12

 

而切比雪夫距离就是找出x,y坐标差值中较大的那个值:

 

13

 

2. A*的Matlab实现

上一篇中我们已经讲过如何构建网络占用地图,所以这里就不再赘述。我们直接来看看算法流程图

 

2.1 流程图

14

对比上一篇的Dijkstar流程,可以发现两者是非常相似的,A*只是多了一个NodeFList用于储存节点的评价函数值F和Heuristic函数用于计算启发值,并且在每轮迭代中A*都是挑选未完成列表中F值最小的节点作为CurrentNode。

 

2.2 启发函数的实现

实际上按照前面提到过的启发函数来看,像曼哈顿距离、欧式距离这些,其实都不难用Matlab实现出来。但是我在实现代码的时候加入了一个之前没有提到过参数scale。之前说过,启发值h(n)占评价值的比例不同会导致不同的A*行为。而这个额外加入的参数就是用来放缩我们的启发值,从而调节启发值的比例的。后面我们会为小伙伴们对比不同scale值导致的不同现象。

 

15

2.3 核心代码

老样子,需要完整matlab源码的小伙伴可以在评论区找我要,我发邮箱。

while true
[min_node_cost, current_node_index] = min(node_f_list(:));
if(min_node_cost == inf || current_node_index == destination_index)
plan_succeeded = true;
break;
end
node_f_list(current_node_index) = inf;
map(current_node_index) = Finished;
[x,y] = ind2sub(MapSize, current_node_index);
for k = 0:3 % four direction
if(k == 0)
adjacent_node = [x-1,y];
elseif (k == 1)
adjacent_node = [x+1,y];
elseif (k == 2)
adjacent_node = [x,y-1];
elseif(k == 3)
adjacent_node = [x,y+1];
end

if((adjacent_node(1) > 0 && adjacent_node(1) <= MapSize(1)) && (adjacent_node(2) > 0 && adjacent_node(2) <= MapSize(2))) % make sure the adjacent_node don't exceeds the map
if(map(adjacent_node(1),adjacent_node(2)) ~= Obstacle && map(adjacent_node(1),adjacent_node(2)) ~= Finished)
if(node_g_list(adjacent_node(1),adjacent_node(2)) > min_node_cost + 1 )
node_g_list(adjacent_node(1),adjacent_node(2)) = node_g_list(current_node_index) + 1;
node_f_list(adjacent_node(1),adjacent_node(2)) = node_g_list(adjacent_node(1),adjacent_node(2)) + Heuristic(adjacent_node, destination, Heuristic_scale);
if(map(adjacent_node(1),adjacent_node(2)) == Origin)
parent_list(adjacent_node(1),adjacent_node(2)) = 0; % Set the parent 0 if adjacent_node is the origin.
else
parent_list(adjacent_node(1),adjacent_node(2)) = current_node_index; %Set the parent current_node_index
end
if(map(adjacent_node(1),adjacent_node(2)) ~= Unfinished)
map(adjacent_node(1),adjacent_node(2)) = Unfinished; % Mark the adjacent_node as unfinished
end
end
end
end
end
end

 

 

2.4 效果对比

这是A*在20*20的地图上的效果

 

2020_Astar_animation

 

这是Dijkstra在20*20的地图上的效果

 

2020_Dstar_animation

 

从返回的结果上看,两者都找到了最优的路径,路径长30。但是从迭代次数上来看,Dijkstra迭代了235次,但是A*只迭代了153次。从动画上也能看到,和Dijkstra的盲目搜索不同,A*向外扩展到一定位置就停止了蔓延。因此可以看出,A*的效率更高。

 

18

 

现在,让我们换个大一点的地图看看效果。我们换成100*100的地图

 

A*的表现如下

 

17

 

Dijkstra的表现如下

 

22

 

可见,在更大的地图上的表现差异更加明显了,两者都找到相同的最优路径,A*经历了1938次迭代,但是Dijkstra却经历了4235次迭代。从两者扩展的节点数量来看,Dijkstra也比A*多扩展了许多节点。

 

19

 

我记得前面我还提了一嘴,说不同的启发值占比会导致A*不同的行为。那这里我们多做一个启发值不同的效果对比:

在代码中的A*函数里,这个Heuristic_scale就是用来设置启发函数的scale值的。我们原本的代码将其设置为1。也就是说启发值等于曼哈顿距离。

 

20

 

假设我们将其增大一点点,就一点点,比如0.001。那么会得到什么样的效果呢?

 

21

 

Emmmmmm, 好像也没什么太大的区别。

 

23

 

让我们看看迭代次数和路径长度:

 

24

 

可以看见相比上一次的1938次,这一回好像确实是稍微减少了迭代次数,不过路径长度变成了134,明显不是最优路径。这些特征确实满足了贪婪算法的特性。但是权衡之下,似乎得不偿失。等等,别急,让我们来看看另一种情况。

 

现在,我们将终点改为[100,100],也就是在最右下角。这回再看看会不会产生不同的情况。

 

哦豁,这就太不一样了。可以看到,算法的探索行为几乎就是直奔目的地而去的

 

25

 

从迭代次数上看,仅仅只有199次,路径长度跟Dijkstra的结果一样也是198。

 

26

 

当我们多改变几次终点值后,我们会发现这时的A*确实表现得更像贪婪算法。迭代次数减少,但是不一定每次都能找到最优路径。所以当我们增大启发值的占比,其实就是在提高算法的运行效率,但是降低了准确度。这却决于实际的场景,毕竟不是每个场景都要求路径最优,有些情况下更希望算法快速地找到一条比较好的路径,而不是花较高的计算成本来找到最优路径。

 

至于降低启发值的比例会产生什么样的结果,那就是启发值的占比越低,A*表现得就越像Dijkstra。虽然会找到最优解,但是也会花费更多的计算成本。

 

经过以上对比以后,我在想,A*经历几千次迭代才后能在100*100的地图中完成规划,虽然现代计算机硬件已经能支持这样级别的运算,在我们的matlab演示代码中,假如关闭动画显示,我们会发现即使是几千次的迭代,实际上也只花费了几百毫秒的时间。但是那假如我们用的地图更大A*是否还能胜任呢?有没有别的办法,可以不需要对地图的栅格一一遍历就能完成路径规划呢?

 

答案是有,下一篇,我们就来说说PRM(概率路线图),这种方法不需要对地图的栅格进行一一遍历就能完成规划。

 

发表评论

后才能评论

评论列表(107条)

  • 9fl8f_3253 2020年12月2日 下午2:15

    您好 老师 想求这几种算法matlab 代码 邮箱506931901@qq.com

  • rrqmb_7093 2020年11月29日 下午8:40

    老师您好呀,我可以求一份源代码嘛?非常感谢嗷!zsk@alu.cau.edu.cn

  • fihqx_8279 2020年11月9日 下午2:35

    老师您好,这是我最近看到的最详细易懂的A*讲解,希望能仔细拜读一下您的源码!谢谢老师!2895736276@qq.com

  • 26y4t_2626 2020年10月26日 下午9:14

    老师,您好。最近再学习了解路径规划这一部分。觉得老师您的博客写的很好,可以发一下Matlab的源码吗,万分感谢。邮箱号1093581716@qq.com

  • mwuaa_2635 2020年10月22日 上午10:23

    最近在做路径规划,可以麻烦老师分享一下代码吗?zhubike@sjtu.edu.cn。万分感谢!

    • tloinny 回复 mwuaa_2635 2020年10月25日 上午8:30

      邮件已发,注意查收,祝您生活愉快!

  • Oscar 2020年10月13日 下午8:27

    老师,您好!我最近在学习Motion Planning,请问可以发一份源代码吗?万分感谢您!18249516788@163.com

    • tloinny 回复 Oscar 2020年10月16日 上午11:19

      邮件已发,注意查收,祝您生活愉快!

  • 7djip_6698 2020年10月13日 下午5:19

    老师 能发一下源码吗? 邮箱:875193130@qq.com 感谢!

    • tloinny 回复 7djip_6698 2020年10月16日 上午11:20

      邮件已发,注意查收,祝您生活愉快!

  • lz0xm_7859 2020年10月9日 下午2:32

    老师您好,我刚开始路径规划的学习,觉得您的博客写得很好,希望您能发一下matlab源码,邮箱1048321360@qq.com,非常感谢

    • tloinny 回复 lz0xm_7859 2020年10月10日 上午12:34

      邮件已发,注意查收,祝您生活愉快!

  • lve93_5025 2020年10月8日 下午6:12

    1219800199@qq.com谢谢楼主,写的很详细,希望可以学习下具体的算法,非常感谢

  • 黏土 2020年10月7日 下午4:43

    老师,想问一下为什么第二十三行是
    node_g_list(adjacent_node(1),adjacent_node(2)) > min_node_cost + 1
    这里min_node_cost不是从node_f_list取的吗,和node_g_list的值比较总觉得有些奇怪
    我尝试在前面加了一行min_node_cost = node_g_list(current_node_index)
    好像运行结果也没什么区别,不知道是哪里理解出了问题?

    • tloinny 回复 黏土 2020年10月8日 上午9:31

      抱歉,最近一直比较忙,难以及时回复。我回去看了一下代码,您说得没错,这确实是一处错误。因为当初是A*是从Dijkstar修改过来的,这个变量没有处理好。感谢指正!!!

    • 黏土 回复 tloinny 2020年10月8日 下午4:59

      所以这一行应该怎么写呢?从我对算法的理解来看是比较两点的评价函数值,也就是node_f_list中的值,但此时node_f_list中的值还未更新,不知应该怎么改呢

    • tloinny 回复 黏土 2020年10月9日 上午9:14

      [min_node_f, current_node_index] = min(node_f_list(:));
      current_node_g = node_g_list(current_node_index);
      修改这两处变量就可以了,算法本身的逻辑是没问题的。min_node_f是用于判定迭代是否结束,current_node_g是当前节点的g值,用来判断与当前节点相邻的节点是否需要被更新,比如相邻节点尚未被访问过时,其g值为inf,那么node_g_list(adjacent_node(1),adjacent_node(2)) > current_node_g + 1必然判定为真,那么该相邻节点就会被更新。或者如果找到一条更近的后退路径时,也会判定为真,也会更新相邻节点。

    • 黏土 回复 tloinny 2020年10月10日 下午10:24

      就是f只是判断迭代的顺序,是否更新是看g而不是f是吗

    • tloinny 回复 黏土 2020年10月11日 上午10:19

      可以这么理解

  • kumzy_9571 2020年10月6日 下午5:16

    老师,麻烦您发一下源代码,万分感谢!2316011738@qq.com

  • p6klk_3778 2020年9月16日 下午9:20

    老师,麻烦您发一下源代码,这是第二课 嘻嘻 matthew_sjtu@163.com

  • szgkw_9785 2020年9月16日 下午8:12

    老师你好,求发代码!!1581844212@qq.com

  • 灬ぺо僤蒓 2020年9月16日 下午7:50

    老师您好,我正在学习路径规划相关的算法,希望您能发一下代码,十分感谢。
    邮箱:634898201@qq.com

  • Asura 2020年9月15日 下午8:24

    老师您好,我最近在了解路径规划的相关问题,已经了解了Dijkstra算法,希望能从您这里获得A*算法的matlab代码,我好慢慢研读,非常感谢!!

    792432709@qq.com

    • tloinny 回复 Asura 2020年9月16日 上午8:57

      邮件已发,注意查收,祝您生活愉快!

  • ནམ་མཁའ་དྲི་མ 2020年9月14日 下午4:14

    老师您好,我正在进行路径规划知识的学习,可以的话希望您能发一份dijkstar和A*的matlab源码,非常感谢!!
    邮箱:676149876@qq.com

  • Sodium 2020年9月4日 下午9:26

    老师您好,正在进行路径规划知识的学习,希望您能发一份dijkstar和A*的matlab源码,非常感谢!!
    邮箱:lz9522@outlook.com

    • tloinny 回复 Sodium 2020年9月5日 下午9:38

      邮件已发,注意查收,祝您生活愉快!

  • dhvdm_5325 2020年8月26日 下午3:45

    您好老师,我刚接触ROS和路径规划算法的知识,如果可以的话能否发一下这几种算法的matlab的源码,感激不尽!xzwsdyx@163.com

  • bx6xz_1790 2020年8月18日 下午5:44

    老师你好,刚进行路径规划的学习,麻烦发一下matlab源码,邮箱wangmin2012bj@163.com,十分感谢

    • tloinny 回复 bx6xz_1790 2020年8月19日 上午10:23

      邮件已发,注意查收,祝您生活愉快!

  • 无论你在哪我都会去找你 2020年7月24日 上午10:33

    老师您好,我正在学习路径规划相关的算法,您目前提及的这四种算法都很有帮助,可以请您发一下代码嘛,邮箱:xhma1998@163.com,十分感谢。

  • lmz 2020年7月22日 下午3:42

    老师您好,我正在学习路径规划相关的算法,希望您能发一下代码,邮箱:564450412@qq.com,十分感谢。

    • tloinny 回复 lmz 2020年7月23日 上午12:24

      邮件已发,注意查收,祝您生活愉快!

  • vxfo0_1261 2020年7月18日 下午3:44

    老师您好,我正在学习路径规划相关的算法,希望您能发一下代码,邮箱:873508297@qqc.om,十分感谢。

  • thuur_8070 2020年7月10日 上午12:53

    请问matlab代码输入参数不足是什么情况?好多函数都是输入参数不足,有点无力去改了,

    • tloinny 回复 thuur_8070 2020年7月12日 下午5:45

      我猜你是因为直接运行函数导致的参数不足的错误警告,matlab里直接点击运行function的话肯定会导致参数不足啊,因为function是需要你在代码中调用的,所以这并不是什么代码错误,只是你使用的方式有误罢了,你直接运行run.m就可以了

  • gv0sd_8176 2020年7月7日 下午9:26

    老师你好,刚进行路径规划的学习,麻烦发一下matlab源码,邮箱2052832778@qq.com

  • q3ggw_2595 2020年7月5日 下午6:09

    老师您好,可以发下完整matlab源码学习一下嘛,邮箱790524354@qq.com

  • 子衿 2020年7月1日 下午4:45

    老师您好,我刚开始学习ROS,想对路径规划做进一步的学习工作,想要一下源代码,谢谢老师。邮箱3204129559@qq.com。

  • 弓长益达 2020年6月30日 上午11:37

    老师您好,路径规划学习中,非常渴望得到a*和dijkstra的源代码,邮箱:1395745488@qq.com。非常感谢您的帮助!

  • 天道酬勤 2020年6月29日 下午2:16

    老师您好,我是一名大一的学生,目前也在学习路径规划知识,想问下老师能发下贪婪算法的源代码么?学生的邮箱是dmuzzy@163.com,非常感谢老师!

  • vaqjl_8782 2020年6月22日 下午6:07

    老师您好,目前在学习路径规划相关算法,希望能获得A*算法和dijkstra算法的源代码,邮箱1142011940@qq.com。非常感谢您的帮助!

  • 无花果 2020年6月20日 下午8:27

    老师您好,SLAM学习中,希望得到A*和dijkstra的源代码,邮箱是1518161708@qq.com。万分感谢。

    • tloinny 回复 无花果 2020年6月21日 下午2:20

      邮件已发,注意查收,祝您生活愉快!

  • Captain 2020年6月12日 下午5:16

    老师您好,路径规划学习中,非常渴望得到a*和dijkstra的源代码,邮箱:295001288@qq.com。非常感谢您的帮助!

    • tloinny 回复 Captain 2020年6月12日 下午11:12

      邮件已发,注意查收,祝您生活愉快!

  • 一见天 2020年6月9日 下午9:28

    老师您好,路径规划学习中,非常渴望得到a*和dijkstra的源代码,邮箱:541034902@qq.com。非常感谢您的帮助!

  • j7plj_5510 2020年6月8日 下午5:00

    老师您好,路径规划学习中,非常渴望得到a*和dijkstra的源代码,邮箱:zhucj991@qq.com。非常感谢您的帮助!

  • 古月的小迷弟 2020年6月8日 下午2:58

    老师您好,这是我的邮箱908526512@qq.com谢谢您 求A*算法

  • ri95w_5628 2020年6月7日 下午9:26

    老师你好,这是我的邮箱:2195454567@qq.com. 谢谢!

  • May丶 2020年6月7日 下午8:40

    老师您好,求a*和dijkstra的源代码,邮箱:923047247@qq.com。非常感谢您的帮助!

    • tloinny 回复 May丶 2020年6月11日 下午2:01

      邮件已发,注意查收,祝您生活愉快!

    • May丶 回复 tloinny 2020年6月15日 上午8:22

      谢谢老师,老师后续会跟新智能算法、神经网络/深度学习之类的新颖的路径规划算法吗?

  • gxzny_8645 2020年6月5日 下午5:15

    老师您好,求a*和dijkstra的源代码,邮箱:853805285@qq.com。谢谢!

  • 低声细语 2020年6月4日 下午2:21

    老师您好,求a*和dijkstra的源代码,邮箱:865884611@qq.com。十分感谢!

  • fho4e_0026 2020年5月26日 下午8:07

    感谢楼主 http://www.1824225660@qq.com 请问一下A*算法有什么可以优化的地方吗?

  • yoowiwi 2020年5月21日 下午6:02

    老师您好,求这两节的源代码!谢谢!邮箱:yww0610@qq.com

  • 诗是诗 2020年5月20日 上午10:51

    老师您好,求a*和dijkstra的源代码,邮箱:474216070@qq.com。谢谢!

    • tloinny 回复 诗是诗 2020年5月20日 下午10:35

      邮件已发,注意查收,祝您生活愉快!

  • bku9a_4899 2020年5月17日 下午11:16

    2537522644@qq.com,a*和dijkstra的源代码能发一份吗,十分感谢

  • zqkqu_7991 2020年5月13日 上午1:06

    写的很好,学到了很多。期待大佬的下篇著作

  • Rene 2020年5月12日 下午12:48

    老师您好,求a*和dijkstra的源代码,邮箱:1196461170@qq.com。谢谢!

    • tloinny 回复 Rene 2020年5月12日 下午1:33

      邮件已发,注意查收,祝您生活愉快!

    • Rene 回复 tloinny 2020年5月12日 下午1:49

      谢谢老师!

  • ~终究意难平 2020年5月12日 上午3:54

    您好,同求一份源代码,邮箱:2303835477@qq.com 。非常感谢!

  • hello 2020年5月10日 下午8:01

    楼主,求一份代码,526091944@qq.com,谢谢您

    • tloinny 回复 hello 2020年5月10日 下午9:08

      邮件已发,注意查收,祝您生活愉快!

    • hello 回复 tloinny 2020年5月15日 上午9:35

      感谢,内容太好了,期待下一篇

  • Willzoe 2020年5月7日 上午9:29

    您好,我有几个问题想要请教:
    1. willzoe@foxmail.com,这是我的邮箱,希望得到一份仿真代码;
    2.当我使用navigation的global_planner / GlobalPlanner的时候,可以正常地使用dijkstra算法,但是当我使用A*算法的时候(use_dijkstra:false),会提示错误NO PATH,请问您知道如何解决吗?我在这里详细地描述了我遇到的问题:https://answers.ros.org/question/350510/some-errors-when-using-globalplanner/

    • tloinny 回复 Willzoe 2020年5月7日 下午12:55

      邮件已发,注意查收,祝您生活愉快!

  • 2294607094 2020年5月7日 上午1:12

    大佬,可以加个微信吗,想请您帮个小忙,非常感谢。17302233229😀

  • 2294607094 2020年5月7日 上午1:07

    m17302233229@163.com写的很好,谢谢楼主

  • dtvee_6515 2020年5月6日 下午12:09

    楼主辛苦,烦请发下代码。690064483@qq.com

  • nuf4j_7912 2020年5月5日 下午8:28

    楼主,可以也发我一份代码学习下吗,非常感谢,谢谢zengpiaoyang123@163.com

  • 渐行渐远 2020年5月3日 下午2:39

    可以发我一份代码吗?学习学习,非常感谢,sunjixing1996@163.com

  • vcoey_9313 2020年5月2日 上午2:08

    楼主可以发下完整matlab源码学习一下嘛,邮箱786795803@qq.com

  • u3oey_0531 2020年5月1日 上午10:27

    楼主可以发下完整matlab源码学习一下嘛,邮箱yxwq6318@163.com

  • il7ir_9039 2020年4月30日 下午6:20

    楼主可以发下完整matlab源码学习一下嘛,邮箱1076225146@qq.com