A* Search Algorithm
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相关推荐
- 2016 UESTC Training for Search Algorithm String I - 谭爷剪花布条 KMP
I - 谭爷剪花布条 Time Limit: 3000/100MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit ...
- 集束搜索(Beam Search Algorithm )
看计算机科学中最重要的32个算法,其中有个是集束搜索(又名定向搜索,Beam Search)--最佳优先搜索算法的优化.使用启发式函数评估它检查的每个节点的能力.不过,集束搜索只能在每个深度中发现前m ...
- 人工智能之集束搜索Beam Search Algorithm
集束搜索是属于人工智能基础知识中的知情搜索,知情搜索是基于启发法的一种搜索方法,由爬山法-->最陡爬坡法-->最佳优先搜索法-->集束搜索,逐步优化算法 通过爬山简单来说下这几种 ...
- Crow search algorithm(乌鸦搜索算法)
今天我准备和大家分享一下我读Crow search algorithm(乌鸦搜索算法 )这篇文章的心得: 原文链接 这篇文章通过对乌鸦的智能行为进行分析,提出了一种新的元启发式优化器,称为乌鸦搜索算法 ...
- 智能优化算法之松鼠算法(Squirrel search algorithm)
文章目录 背景 Squirrel search algorithm(SSA) SSA Random initialization(随机初始化) Fitness evaluation(适应值评价) So ...
- 闪电搜索算法,Lightning search algorithm
1.闪电搜索算法,Lightning search algorithm Shareef H, Ibrahim AA, Mutlag A H. Lightning search algorithm[J] ...
- SRPG游戏开发(二十三)第七章 寻路与地图对象 - 一 A*寻路算法(A* Search Algorithm)
返回总目录 第七章 寻路与地图对象(Pathfinding and Map Object) 这一章主要进行寻路与地图对象的部分工作. 第七章 寻路与地图对象(Pathfinding and Map O ...
- sparrow search algorithm(麻雀搜索算法)
Jiankai Xue & Bo Shen (2020) A novel swarm intelligence optimization approach: sparrow search al ...
- 麻雀搜索算法SSA(Sparrow Search algorithm)
文章目录 前言 数学模型 前言 麻雀搜索算法是2020提出的一种新的优化算法,出自东华大学xue和shen的论文:A novel swarm intelligence optimization app ...
最新文章
- 【转】ibatis的简介与初步搭建应用
- redis 之 sds (二) char []
- 利用jdom生成XML文件
- Java泛型编程基础
- HDU1862 EXCEL排序【排序】
- JQuery常用功能的性能优化
- AQS源码阅读笔记(一)
- 物理路径与虚拟路径 及Web Server
- 工作292:修改父子组件传值错误
- Mysql存储引擎中InnoDB与Myisam的区别
- 对于一组给定的叶子结点_高糊图片可以做什么?Goodfellow等人用它生成一组合理图像...
- 万由nas系统安装MySQL_ESXi安装万由OS(U-NAS 3.0.9)
- Vissim 基础教程和技巧
- python 入门教程
- 递推DP UVA 473 Raucous Rockers
- php获取index.php,index.php · 阿彪/PHP去抖音水印解析-非接口(获取抖音无水印URL地址) - Gitee.com...
- Android Zxing识别图片二维码识别率低
- flutter Dart Mixin后关于调用super的理解
- 美团大规模微服务通信框架及治理体系OCTO核心组件开源
- GB(国标)字典大全
热门文章
- 开心消消乐java下载_开心消消乐下载_开心消消乐下载最新iPhone版-太平洋下载中心...
- 这四个微信小技巧,职场人一定要学会
- 实现在 .net 中使用 HttpClient 下载文件时显示进度
- cocos植物大战僵尸(三)游戏场景:地图滚动
- 实战派来了!聊聊百度智能运维的“前世今生” | 技术沙龙
- application.yml与bootstrap.yml的区别
- 关于Trunk封装的协议和模式。如何配置trunk
- APP性能测试--内存测试
- 华科2020计算机专业录取线,华中科技大学2020录取分数线是多少
- 如何通俗的理解beam search?