A星算法理解_a星算法例题

A星算法理解_a星算法例题A星算法理解1.选择A星算法的原因为了进行路径规划算法是不可回避的:启发式搜索算法是比较常规的一类算法就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无谓的搜索路径,提高了效率。在启发式搜索中,对位置的估价是十分重要的。采用了不同的估价可以有不同的效果。启发中的估价是用估价函数表示的,如:f(n)=g(n)+h(n)。g…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

A星算法理解

1.选择A星算法的原因

为了进行路径规划算法是不可回避的:启发式搜索算法是比较常规的一类算法就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无谓的搜索路径,提高了效率。在启发式搜索中,对位置的估价是十分重要的。采用了不同的估价可以有不同的效果。启发中的估价是用估价函数表示的,如:f(n) = g(n) + h(n) 。g(n)为起点到当前位置的实际路径长度,h(n)为所在位置到终点的最佳路径的估计距离。前面说每次会优先向终点方向进行移动,就是因为估价函数所导致的。h(n)=0时,意味着此时是盲目搜索,当h(n)越复杂,即约束的条件越多,耗费的时间就越多,而减少约束条件,则可能得到的并不是最优路线。在A算法中,估价函数为f(n)=g(n)+h*(n)。这里面的h*(n)的附加条件为h*(n)<=h‘(n),h’(n)为n到目标的直线最短距离,也就说A*算法中挑选的启发函数是最优的,也正是如此,所找到的路径是最短路径。

2.启发函数的选择问题

有时候经过简单的对比,很容易得出曼哈顿距离作为启发函数,搜索效率最高,并得出曼哈顿距离最好的结论。可是在实际情况下,我们不仅要考虑搜索效率,也要考虑最优性,所以大多情况下选择対角距离作为启发函数。

3.算法流程图

在这里插入图片描述

4.算法实现步骤

  1. 启发式函数

    double Manhattan_dist,Euclidean_dist,Diagonal_dist;
    Eigen::Vector3i diff=node2->index-node1->index;
    double dx,dy,dz;
    dx=abs(diff(0));
    dy=abs(diff(1));
    dz=abs(diff(2));
    Manhattan_dist=dx+dy+dz;
    Euclidean_dist=sqrt(diff.dot(diff));
    float dmin = min(dx, min(dy, dz));
    float dmax = max(dx, max(dy, dz));
    float dmid = dx + dy + dz - dmin - dmax;
    Diagonal_dist=(1.732 - 1.414) * dmin + (1.414 - 1) * dmid +  dmax;
    // tie breaker
    hue=Diagonal_dist*1.00001;
    return Euclidean_dist;

  1. 将起始节点放入OPEN表里
startPtr -> gScore = 0;
    startPtr -> fScore = getHeu(startPtr,endPtr);
    //STEP 1: finish the AstarPathFinder::getHeu , which is the heuristic function
    startPtr -> id = 1; 
    startPtr -> coord = start_pt;
    openSet.insert( make_pair(startPtr -> fScore, startPtr) );
  1. 当主循环不为空时
while ( !openSet.empty() )
  1. 将代价值最小的点从open表转移到close表中,并将原表中的点删除
// openSet.begin()->second->cameFrom=currentPtr;
        currentPtr=openSet.begin()->second;//acending order
        //move it to closeset at once
        currentPtr->id=-1;

// closeSet.insert(make_pair(openSet.begin()->first,openSet.begin()->second));
        openSet.erase(openSet.begin());
        GridNodeMap[currentPtr->index[0]][currentPtr->index[1]]
                [currentPtr->index[2]]=currentPtr;

  1. 如果当前点是目标点,路径成功结束。
// if the current node is the goal 
        if( currentPtr->index == goalIdx ){ 
   
            ros::Time time_2 = ros::Time::now();
            terminatePtr = currentPtr;
            ROS_WARN("[A*]{sucess} Time in A* is %f ms, path cost if %f m", (time_2 - time_1).toSec() * 1000.0, currentPtr->gScore * resolution );            
            return;
        }
        //get the succetion
  1. 对扩展节点进行扩展子节点
 *        
        */         
        for(int i = 0; i < (int)neighborPtrSets.size(); i++){ 
   
            /* * * Judge if the neigbors have been expanded please write your code below IMPORTANT NOTE!!! neighborPtrSets[i]->id = -1 : expanded, equal to this node is in close set neighborPtrSets[i]->id = 1 : unexpanded, equal to this node is in open set * */
            neighborPtr=neighborPtrSets[i];


            if(neighborPtr -> id == 0){ 
    //discover a new node, which is not in the closed set and open set
                /* * * STEP 6: As for a new node, do what you need do ,and then put neighbor in open set and record it please write your code below * */
                neighborPtr -> gScore=edgeCostSets[i];
                neighborPtr -> fScore = getHeu(neighborPtr,endPtr)+edgeCostSets[i];
                neighborPtr ->id=1;//open
                neighborPtr->cameFrom=currentPtr;
                openSet.insert( make_pair(neighborPtr -> fScore, neighborPtr) );
                //update map
                GridNodeMap[neighborPtr->index[0]][neighborPtr->index[1]]
                        [neighborPtr->index[2]]=neighborPtr;
                continue;
            }
            else if(neighborPtr -> id ==1){ 
    //this node is in open set and need to judge if it needs to update, the "0" should be deleted when you are coding
                /* * * STEP 7: As for a node in open set, update it , maintain the openset ,and then put neighbor in open set and record it please write your code below * */
                if(neighborPtr->gScore>edgeCostSets[i])
                    neighborPtr->gScore=edgeCostSets[i];
                neighborPtr -> fScore = getHeu(neighborPtr,endPtr)+neighborPtr->gScore;

                continue;
            }
            else if(neighborPtr -> id ==-1){ 
   //this node is in closed set: it is impossible that node in closeset will be suceession
                /* * please write your code below * */
// ROS_ERROR("NOOOO");
                continue;
            }
        }

    }
  1. 由当前点获取路径上的所有点
while(terminatePtr!=nullptr)
    { 
   
        gridPath.push_back(terminatePtr);
        terminatePtr=terminatePtr->cameFrom;
        if(gridPath.size()>100)
        { 
   
            ROS_ERROR("dead loop!!");
            break;
        }
    }
    for (auto ptr: gridPath)
        path.push_back(ptr->coord);
        
    reverse(path.begin(),path.end());

    return path;

一个具有注脚的文本。1


  1. 注脚的解释
    小白一枚 ↩︎

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/185132.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux解压zip多种命令,Linux常用几种打包、压缩、解压命令,(备用)

    linux解压zip多种命令,Linux常用几种打包、压缩、解压命令,(备用)01-.tar格式解包:[*******]$tarxvfFileName.tar打包:[*******]$tarcvfFileName.tarDirName(注:tar是打包,不是压缩!)02-.gz格式解压1:[*******]$gunzipFileName.gz解压2:[*******]$gzip-dFileName.gz压缩:[*******]$gzipFile…

    2022年6月1日
    41
  • CAS原理详解_外燃机工作原理

    CAS原理详解_外燃机工作原理CAS简介CAS的意思是compareandswap,比较并交换。CAS的引入是为了解决java锁机制带来的性能问题。锁机制存在以下问题:(1)在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。(2)一个线程持有锁会导致其它所有需要此锁的线程挂起。(3)如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能风险。解决线程安全问题volatile是不错的机制,但是volatile不能保证原子性。因此对于同步最终还是要回到锁机制上来。独占锁

    2022年10月16日
    1
  • windows下如何安装Composer?

    windows下如何安装Composer?

    2021年10月21日
    49
  • 21.2 日志格式

    21.2 日志格式大部分商用和开源的HTTP应用程序都支持以一种或多种常用格式进行日志记录。很多这样的应用程序都支持管理者配置日志格式,创建自定义的格式。应用程序支持管理者使用这些更标准的格式的主要好处之一就在于,可以充分利用那些已构建好的工具处理这些日志,并产生基本的统计信息。有很多开源包和商用包都可用来压缩日志,以进行汇报。使用标准格式,应用程序及其管理员就都可以利用这些包了。1.常见日志格式现在,最

    2022年6月10日
    34
  • 防不胜防,你可能访问了一个被克隆的网站什么意思_浏览被黑客攻击的网站

    防不胜防,你可能访问了一个被克隆的网站什么意思_浏览被黑客攻击的网站我们来看一下以下这2个网址:http://www.lcbc.com.cn、http://www.baiud.com,在此之前大家有没有发现有什么异样?仔细一看,大家会发现…

    2025年9月11日
    7
  • html psd设计图,根据PSD登陆页面设计稿切图制作HTML网页全过程

    html psd设计图,根据PSD登陆页面设计稿切图制作HTML网页全过程切图的目的是把PSD设计稿转换为HTML页面。记得自己当时学习切图时,网上切图相关的文章是不少,但是大都是讲怎么使用切片工具把一张图片分割成多张图片,然后存储为Web使用格式,并且都比较简单和零碎,并不能满足我的要求。因此只能自己不断尝试,今天分享给大家“如何根据PSD设计稿通过PS切图和DIV+CSS布实现HTML页面”,希望能帮助到大家。实例:下面通过一个简单的登陆页面PSD设计稿来演示转化为…

    2022年6月10日
    88

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号