A* Search Algorithm

写在前面:第一次写博客,以后想把遇到的有意思的算法或者小知识记录下来。纯原创,部分图片来自课堂PPT,出自UCR,CS170课件。转载请声明出处。

算法简介

A* Search 是一种启发式搜索算法,该算法内置一个函数来表达当前状态和目标状态的差值。举个栗子,8-puzzle问题(一个游戏,目标是将对应数字的版块放到对应位置)。当前状态是下图

目标状态:

如果我们以两个状态有多少不符合启发函数,那么这里的启发函数的值是
1(PS:这里我们排除了空白格,图中当前态和目标态就一个‘8’不同)

接下来会详细介绍A算法并以8-puzzle游戏左右一个例子来说明该算法,在引入A search前,我会先简单介绍两个算法,Uniform Cost Search和Hill climbing Search。启发函数选择的是Manhattan距离,详解看下图。(h(n)就是启发函数)

先说说Hill climbing Search,该算法也是一种启发式搜索算法,思路很简单,直接使用Manhattan距离。在下面的例子中,这个算法运行的很好。(h(n)是启发函数)

这个算法运行的很快,可是会遇到问题。有时候该算法在一些状态会陷入找不到解的状态

另一种Uniform Cost Search算法,该算法更简单每次在拓展节点的时候,拓展最廉价的点(该点的耗费是到这个点的路径的累积消耗,拓展累积消耗最小的点)。该算法运行效率较低,但是可以保证每次找到一个解。

背景介绍完毕。接下来进入A*算法,这个算法结合了Uniform Cost Search和Hill climbing Search。将到达该节点的累积消耗g(n)和该节点到达目标节点的差h(n)作为启发函数

下图是一个A算法的例子:这是一个迷宫问题,初始状态是粉色的点,目标状态是蓝色的点。将粉点移动到蓝点即可。图中的树说明了用A树的搜索过程。H(n)依然使用Manhattan距离

说到这,A算法的基本概念已经介绍完毕。一下附上A算法的实现代码(Python)。以解决8-puzzle问题作为背景。

实现代码

import numpy as np
import Queue
import copy
DEFAULT_PUZZLE = np.array([1,2,3,4,8,0,7,6,5]).reshape((3,3))
GOAL_STATE = np.array([1,2,3,4,5,6,7,8,0]).reshape((3,3))
STATE_TABLE = dict() # store the state already checkclass Node():''':description: define the Node class'''def __init__(self,puzzle,depth,total_cost,blank_index_i,blank_index_j):self.puzzle = puzzleself.depth = depthself.total_cost = total_costself.blank_index_i = blank_index_iself.blank_index_j = blank_index_jdef get_depth(self):return self.depthdef get_puzzle(self):return self.puzzledef get_total_cost(self):return self.total_costdef get_blank_index_i(self):return self.blank_index_idef get_blank_index_j(self):return self.blank_index_jdef __lt__(self, other):return self.total_cost < other.total_costdef Init_input_puzzle():''':description:Initializing the input puzzle matrix, and choose the algorithm:input: None:return:puzzle: the puzzle need to solvedkey:  the choice of algorithmblank_index_i : the blank block indexblank_index_j : the blank block index'''print "Welcome to Geyeshui's 8-Puzzle solver"key = input("Inpute 1 to use the defualt puzzle, or 2 to enter your own puzzle: \n")if key == 1:puzzle = DEFAULT_PUZZLEelse:print "Enter your puzzle use a zero to represent the blank"puzzle_input = []for i in range(3):row = raw_input("Enter the "+str(i+1)+"th row, use SPACE bewtween numbers: \n")puzzle_input = puzzle_input + [eval(i) for i in row.split()]puzzle = np.array(puzzle_input).reshape((3,3))print "Enter your choice of algorithm"print "1.Uniform cost search"print "2.A* with the Misplaced title heuristic"key = input("3.A* with the Manhattan distance heuristic \n")# find the blank indexfor i in range(3):for j in range(3):if puzzle[i][j]==0:blank_index_i = iblank_index_j = jreturn puzzle, key, blank_index_i, blank_index_jdef Get_heuristic_cost(key,puzzle):''':description:according the algorithm you choice return the corresponding h(n) value:inpute:key : the algorithm index numberpuzzle : the puzzle needed to estimate the h(n):return:h_n : the h(n) value'''h_n = 0if key == 1:h_n=0elif key ==2:for i in range(3):  # calculate the misplace number, excluding the blank.for j in range(3):if puzzle[(i,j)] != GOAL_STATE[(i,j)]:if i==2 and j==2:continueelse:h_n = h_n+1else:for i in range(3): # calculate the manhattan distancefor j in range(3):num = puzzle[(i,j)]if num==0:continueelse:index_num_i = (num-1)/3index_num_j = (num-1)%3h_n = h_n + (abs(i-index_num_i)+abs(j-index_num_j))return h_ndef Is_goal_state(puzzle):''':description: return Ture if the puzzle is the goal state, False otherwise:input:puzzle: the puzzle needs to be check:return:Ture: if puzzle is the goal stateFalse: if it is not'''if sum(sum(puzzle==GOAL_STATE))==9:return Trueelse:return Falsedef Move_up(puzzle,index_i,index_j):''':description:move up the blank block if it can.:parampuzzle: the puzzle which needs the operation:return:puzzle: puzzle after move upTrue: if it can move upFalse: if it is illegal to move up'''if index_i>0:puzzle[index_i-1][index_j],puzzle[index_i][index_j] \= puzzle[index_i][index_j],puzzle[index_i-1][index_j]if STATE_TABLE.get(str(puzzle),0) == 1:return None,Falseelse:STATE_TABLE[str(puzzle)] = 1return puzzle,Trueelse:return None,Falsedef Move_down(puzzle,index_i,index_j):''':description:move down the blank block if it can.:parampuzzle: the puzzle which needs the operation:return:puzzle: puzzle after move downTrue: if it can move downFalse: if it is illegal to move down'''if index_i<2:puzzle[index_i+1][index_j],puzzle[index_i][index_j] \= puzzle[index_i][index_j],puzzle[index_i+1][index_j]if STATE_TABLE.get(str(puzzle),0) == 1:return None,Falseelse:STATE_TABLE[str(puzzle)] = 1return puzzle,Trueelse:return None,Falsedef Move_left(puzzle,index_i,index_j):''':description:move left the blank block if it can.:parampuzzle: the puzzle which needs the operation:return:puzzle: puzzle after move leftTrue: if it can move leftFalse: if it is illegal to move left'''if index_j>0:puzzle[index_i][index_j-1],puzzle[index_i][index_j] \= puzzle[index_i][index_j],puzzle[index_i][index_j-1]if STATE_TABLE.get(str(puzzle),0) == 1:return None,Falseelse:STATE_TABLE[str(puzzle)] = 1return puzzle,Trueelse:return None,Falsedef Move_right(puzzle,index_i,index_j):''':description:move right the blank block if it can.:parampuzzle: the puzzle which needs the operation:return:puzzle: puzzle after move rightTrue: if it can move rightFalse: if it is illegal to move right'''if index_j<2:puzzle[index_i][index_j+1],puzzle[index_i][index_j] \= puzzle[index_i][index_j],puzzle[index_i][index_j+1]if STATE_TABLE.get(str(puzzle),0) == 1:return None,Falseelse:STATE_TABLE[str(puzzle)] = 1return puzzle,Trueelse:return None,Falseif __name__ == '__main__':ans = None# key is the choice index of algorithmpuzzle, key, blank_index_i, blank_index_j= Init_input_puzzle()STATE_TABLE[str(puzzle)] = 1global_step = 0 # store the how many iteration we runsize_of_pq = 0 # store the max size of priority_queuepq = Queue.PriorityQueue()pq.put(Node(puzzle,0,Get_heuristic_cost(key,puzzle),blank_index_i,blank_index_j))while not pq.empty():size_of_pq = max(size_of_pq,pq.qsize())node = pq.get()global_step = global_step + 1print node.get_puzzle()if Is_goal_state(node.get_puzzle()):ans = nodebreakelse:blank_index_i = node.get_blank_index_i()blank_index_j = node.get_blank_index_j()up_puzzle, up_flag = Move_up(copy.deepcopy(node.get_puzzle()),blank_index_i,blank_index_j)down_puzzle, down_flag = Move_down(copy.deepcopy(node.get_puzzle()),blank_index_i,blank_index_j)right_puzzle, right_flag = Move_right(copy.deepcopy(node.get_puzzle()),blank_index_i,blank_index_j)left_puzzle, left_flag = Move_left(copy.deepcopy(node.get_puzzle()),blank_index_i,blank_index_j)if up_flag==True:pq.put(Node(up_puzzle,node.get_depth()+1,node.get_depth()+1+Get_heuristic_cost(key,up_puzzle),blank_index_i-1,blank_index_j))if down_flag==True:pq.put(Node(down_puzzle,node.get_depth()+1,node.get_depth()+1+Get_heuristic_cost(key,down_puzzle),blank_index_i+1,blank_index_j))if right_flag==True:pq.put(Node(right_puzzle,node.get_depth()+1,node.get_depth()+1+Get_heuristic_cost(key,right_puzzle),blank_index_i,blank_index_j+1))if left_flag==True:pq.put(Node(left_puzzle,node.get_depth()+1,node.get_depth()+1+Get_heuristic_cost(key,left_puzzle),blank_index_i,blank_index_j-1))print ans.get_puzzle(),ans.get_depth(),global_step,size_of_pq

以上就是A* Search Algorithm, 有什么说的不对的地方欢迎指正

A* Search Algorithm相关推荐

  1. 2016 UESTC Training for Search Algorithm String I - 谭爷剪花布条 KMP

    I - 谭爷剪花布条 Time Limit: 3000/100MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit ...

  2. 集束搜索(Beam Search Algorithm )

    看计算机科学中最重要的32个算法,其中有个是集束搜索(又名定向搜索,Beam Search)--最佳优先搜索算法的优化.使用启发式函数评估它检查的每个节点的能力.不过,集束搜索只能在每个深度中发现前m ...

  3. 人工智能之集束搜索Beam Search Algorithm

      集束搜索是属于人工智能基础知识中的知情搜索,知情搜索是基于启发法的一种搜索方法,由爬山法-->最陡爬坡法-->最佳优先搜索法-->集束搜索,逐步优化算法 通过爬山简单来说下这几种 ...

  4. Crow search algorithm(乌鸦搜索算法)

    今天我准备和大家分享一下我读Crow search algorithm(乌鸦搜索算法 )这篇文章的心得: 原文链接 这篇文章通过对乌鸦的智能行为进行分析,提出了一种新的元启发式优化器,称为乌鸦搜索算法 ...

  5. 智能优化算法之松鼠算法(Squirrel search algorithm)

    文章目录 背景 Squirrel search algorithm(SSA) SSA Random initialization(随机初始化) Fitness evaluation(适应值评价) So ...

  6. 闪电搜索算法,Lightning search algorithm

    1.闪电搜索算法,Lightning search algorithm Shareef H, Ibrahim AA, Mutlag A H. Lightning search algorithm[J] ...

  7. SRPG游戏开发(二十三)第七章 寻路与地图对象 - 一 A*寻路算法(A* Search Algorithm)

    返回总目录 第七章 寻路与地图对象(Pathfinding and Map Object) 这一章主要进行寻路与地图对象的部分工作. 第七章 寻路与地图对象(Pathfinding and Map O ...

  8. sparrow search algorithm(麻雀搜索算法)

    Jiankai Xue & Bo Shen (2020) A novel swarm intelligence optimization approach: sparrow search al ...

  9. 麻雀搜索算法SSA(Sparrow Search algorithm)

    文章目录 前言 数学模型 前言 麻雀搜索算法是2020提出的一种新的优化算法,出自东华大学xue和shen的论文:A novel swarm intelligence optimization app ...

最新文章

  1. 【转】ibatis的简介与初步搭建应用
  2. redis 之 sds (二) char []
  3. 利用jdom生成XML文件
  4. Java泛型编程基础
  5. HDU1862 EXCEL排序【排序】
  6. JQuery常用功能的性能优化
  7. AQS源码阅读笔记(一)
  8. 物理路径与虚拟路径 及Web Server
  9. 工作292:修改父子组件传值错误
  10. Mysql存储引擎中InnoDB与Myisam的区别
  11. 对于一组给定的叶子结点_高糊图片可以做什么?Goodfellow等人用它生成一组合理图像...
  12. 万由nas系统安装MySQL_ESXi安装万由OS(U-NAS 3.0.9)
  13. Vissim 基础教程和技巧
  14. python 入门教程
  15. 递推DP UVA 473 Raucous Rockers
  16. php获取index.php,index.php · 阿彪/PHP去抖音水印解析-非接口(获取抖音无水印URL地址) - Gitee.com...
  17. Android Zxing识别图片二维码识别率低
  18. flutter Dart Mixin后关于调用super的理解
  19. 美团大规模微服务通信框架及治理体系OCTO核心组件开源
  20. GB(国标)字典大全

热门文章

  1. 开心消消乐java下载_开心消消乐下载_开心消消乐下载最新iPhone版-太平洋下载中心...
  2. 这四个微信小技巧,职场人一定要学会
  3. 实现在 .net 中使用 HttpClient 下载文件时显示进度
  4. cocos植物大战僵尸(三)游戏场景:地图滚动
  5. 实战派来了!聊聊百度智能运维的“前世今生” | 技术沙龙
  6. application.yml与bootstrap.yml的区别
  7. 关于Trunk封装的协议和模式。如何配置trunk
  8. APP性能测试--内存测试
  9. 华科2020计算机专业录取线,华中科技大学2020录取分数线是多少
  10. 如何通俗的理解beam search?