zoukankan      html  css  js  c++  java
  • A*算法与8数字谜题(参见《算法》P226习题2.5.32)

        A*算法的目的是找到一条从起始状态到最终状态的最短路径。

        在A*算法中,需要在每个点计算启发函数:f(S) = g(S) + h(S),其中g(S)是从起点到S点的距离,h(S)是对从S点到终点的最短距离的估计值。

        如果把g(S)当作深度,又令h(S) = 0,则A*算法就变成了BFS

        A*算法对BFS的改进在于把BFS所用到的队列改成按启发函数值排列的优先队列。

        假设从状态S抵达终点的最短距离为H(S),那么启发函数中的h(S)必须满足h(S)<= H(S)。在此基础上,h和实际的距离越接近,需要计算的节点就越少,效果就越好。如果h(S) = 0,此时A*算法就变成了BFS,效果最差。

     

        在解8数字谜题时,如果按照BFS的思路,我们每次扩展四个节点,分别是空格上移、下移、左移和右移(当然,大多数节点是无法完全扩展这四个方向的),一层层搜索之后,若发现了目标状态,则从目标状态节点开始向父节点回溯,由此就可以得到一个步数最少的解法了。但是BFS是盲目的,因此在搜索过程中它搜索了很多意义不大的节点。于是我们开始设计一个加入了一定启发信息的A*算法(其思路类似于分支限界),代码如下(参见P223 2.5.4.6小节)

     

    A*()
    {
    	// open表,用优先队列实现,用来保存待扩展的节点(改进自BFS中的队列)。
    	PriorityQueue open;
        
    	// closed表,用HASH表或者其他能够高效检索的数据结构实现,用来保存已经扩展过的节点(可以考察一个状态是否已经被产生过)。
    	SymbolTable closed;
    
    	open.Add(起始节点);
         
        while(!PriorityQueueEmpty(open))
        {
    		// 从open表中弹出一个最优的待扩展节点
            S = PriorityQueueDeleteMax(open)); 
    
            closed.Insert(S);
             
            // 如果S就是目标状态则结束
            if(S == GOAL)
            {
                return OVER;
            }
             
            // 尝试扩展S的所有子节点
            while(childS = S.nextChild())
            {
                // 如果当前节点尚未被产生过
                if(!closed.isInclude(childS))
                {
                    // 则将这个节点添加到open表中
                    PriorityQueueInsert(open,childS);
                }
            }
        }
    }
    

     

      

     

     

     

     

  • 相关阅读:
    [Vue]使用 vue-i18n 切换中英文
    轻松实现Ecshop商城多语言切换
    关于ecshop的mobile里user.php登录和注册验证码不显示
    ecshop用户中心菜单选项显示内容标签
    ECSHOP的JS文件代入问题
    在PHP中gmtime()与time()区别
    ECSHOP中 {insert name='ads' id=$ads_id num=$ads_num}含义
    ECshop 迁移到 PHP7版本时遇到的兼容性问题,ecshopphp7
    App开放接口api安全性—Token签名sign的设计与实现
    台湾拼音对照表
  • 原文地址:https://www.cnblogs.com/laifeiyao/p/3475098.html
Copyright © 2011-2022 走看看