一,A*算法设计思想

A*算法(A-star)是一种寻路算法,主要用于游戏、机器人等领域。

它的设计思想是将最短路径搜索问题转化为一个优化问题,通过计算每个节点的评分(f(n) = g(n) + h(n))来寻找最优路径。

以下是 A*算法的设计思想:

1. 引入启发式函数(h(n)):

A*算法使用一个启发式函数来估计从当前节点到目标节点的距离。

启发式函数越好,搜索速度越快。

通常情况下,启发式函数为曼哈顿距离(曼哈顿距离是指两点在网格上沿着网格线走的距离之和)。

2. 优先级队列

A*算法使用一个优先级队列(开启列表)来存储待处理的节点。

队列中的节点按照评分(f(n))从高到低排列。

这样,每次迭代都可以优先处理评分最高的节点,从而保证搜索的速度和效率。

3. 扩展节点

A*算法从当前节点开始,遍历其所有相邻节点。

对于每个相邻节点,检查它是否在关闭列表中(表示已经访问过),如果不在关闭列表中,则将其加入开启列表,并更新其父节点和评分。

4. 关闭列表

A*算法使用一个关闭列表来记录已访问过的节点。

每次扩展节点时,都需要检查新节点是否在关闭列表中。

如果在,则忽略该节点,继续处理其他相邻节点。

5. 停止条件

A*算法在找到目标节点或开启列表为空时停止搜索。

找到目标节点时,意味着找到了一条从起始节点到目标节点的最短路径。

6. 回溯法

当开启列表为空时,搜索失败。

此时,可以使用回溯法(如 Dijkstra 算法)从起始节点开始,重新寻找一条路径。

这种情况下,A*算法退化为 Dijkstra 算法。

二,题目需求

应用启发式搜索算法A 解决以下八数码问题:

初始状态:

目标状态:

三,代码实现

完整代码,需要下载pygame库,直接使用,运行可以查看动画演示效果。

import heapq
from copy import deepcopy
import time
import pygame # 定义启发式函数,使用当前状态与目标状态,棋子的错位数作为估价值
def heuristic(move_state, goal_state):
err_num = 0
for i in range(3):
for j in range(3):
if move_state[i][j] != goal_state[i][j]:
err_num += 1
return err_num # 根据当前状态,获取可移动方向
def get_moves(state, g):
# 获取空缺位(或0值)坐标
x, y = None, None
for i in range(3):
for j in range(3):
if state[i][j] == 0:
x, y = i, j
break
moves = []
if x > 0:
new_state = deepcopy(state)
# 空位与它左侧1位交换,左侧数字右移
new_state[x][y], new_state[x - 1][y] = new_state[x - 1][y], new_state[x][y]
moves.append((new_state, g + 1))
if x < 2:
new_state = deepcopy(state)
# 空位与它右侧1位交换,右侧数字左移
new_state[x][y], new_state[x + 1][y] = new_state[x + 1][y], new_state[x][y]
moves.append((new_state, g + 1))
if y > 0:
new_state = deepcopy(state)
# 空位与它下面1位交换,下面数字上移
new_state[x][y], new_state[x][y - 1] = new_state[x][y - 1], new_state[x][y]
moves.append((new_state, g + 1))
if y < 2:
new_state = deepcopy(state)
# 空位与它上面1位交换,上面数字下移
new_state[x][y], new_state[x][y + 1] = new_state[x][y + 1], new_state[x][y]
moves.append((new_state, g + 1))
return moves # A星算法搜索
def a_star_search(initial_state, goal_state):
f, g, h = 0, 0, 0
open_set = [(f, initial_state)]
close_set = set()
# 从哪里来字典,记录节点来源,当成父节点
come_from = {}
while open_set:
f, current_state = heapq.heappop(open_set)
if current_state == goal_state:
data = []
current_state = tuple(map(tuple, current_state))
# 从目标点向起点遍历路径
while current_state in come_from:
# 将当前点的位置加入路径
data.append(current_state)
# 将当前点设为从哪里来的节点,继续向上遍历
current_state = come_from[current_state]
# 将起始点的位置也加入路径
data.append(tuple(map(tuple, initial_state)))
# 将路径反转,因为我们是从目标向起点遍历的,所以需要反转得到真正的路径
return data[::-1] close_set.add(tuple(map(tuple, current_state)))
for move, g in get_moves(current_state, g):
if tuple(map(tuple, move)) not in close_set:
come_from[tuple(map(tuple, move))] = tuple(map(tuple, current_state))
h = heuristic(move, goal_state)
f = g + h
heapq.heappush(open_set, (f, move))
return None # 打印网格地图
def grid_print(grid):
for line in grid:
print(line) # 定义网格矩阵长宽
map_size = (3, 3)
# 定义屏幕一个格子大小
CELL_SIZE = 200
# 定义屏幕宽高大小
WIDTH, HEIGHT = map_size[0] * CELL_SIZE, map_size[1] * CELL_SIZE # 定义颜色
WHITE = (255, 255, 255)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
BLACK = (0, 0, 0) # 绘制主地图,棋盘数字
def draw_grid(pygame, screen, num_states):
# 填充屏幕背景为白色
screen.fill(WHITE)
for i in range(0, WIDTH, CELL_SIZE):
pygame.draw.line(screen, BLACK, (i, 0), (i, HEIGHT))
for i in range(0, HEIGHT, CELL_SIZE):
pygame.draw.line(screen, BLACK, (0, i), (WIDTH, i))
# 字体
font = pygame.font.Font(None, 48)
for i in range(3):
for j in range(3):
# 数字值
num_text = str(num_states[j][i])
if num_text == '0':
# 写数字
text = font.render(num_text, True, RED)
else:
# 写数字
text = font.render(num_text, True, BLUE)
screen.blit(text, (i * CELL_SIZE + CELL_SIZE / 2, j * CELL_SIZE + CELL_SIZE / 2)) # 绘制A*算法找到的路径,动画演示
def draw_a_star_path(initial_state, goal_state):
# 执行A*算法,寻找最优路径
path_states = a_star_search(initial_state, goal_state)
print("绘制网格地图和最优路径:")
# 返回搜索路径和Open、Close表的内容
i = 0
for path in path_states:
grid_print(path)
print(f"======={i}=======")
i += 1 print("绘制A*算法找到的路径地图:")
# 初始化 Pygame
pygame.init() # 创建一个窗口(屏幕)对象
screen = pygame.display.set_mode((WIDTH, HEIGHT))
# 窗口描述
pygame.display.set_caption("A星算法-8数码问题-动画演示")
# 循环刷新地图,显示最优路径
for num_states in path_states:
# 绘制主地图,棋盘数字
draw_grid(pygame, screen, num_states)
# 更新显示屏幕
pygame.display.flip()
time.sleep(1)
# 退出 Pygame
pygame.quit() if __name__ == "__main__":
# 八数码初始状态
initial_state = [
[2, 8, 3],
[1, 6, 0],
[7, 5, 4]
] # 八数码最终状态
goal_state = [
[1, 2, 3],
[8, 0, 4],
[7, 6, 5]
]
# 绘制A*算法找到的路径,动画演示
draw_a_star_path(initial_state, goal_state)

四,运行动画效果

==========结束==========

人工智能-A*算法-八数码问题的更多相关文章

  1. A*算法 -- 八数码问题和传教士过河问题的代码实现

    前段时间人工智能的课介绍到A*算法,于是便去了解了一下,然后试着用这个算法去解决经典的八数码问题,一开始写用了挺久时间的,后来试着把算法的框架抽离出来,编写成一个通用的算法模板,这样子如果以后需要用到 ...

  2. noj 算法 八数码问题

    描述 在九宫格里放在1到8共8个数字还有一个是空格,与空格相邻的数字可以移动到空格的位置,问给定的状态最少需要几步能到达目标状态(用0表示空格):1 2 34 5 67 8 0   输入 输入一个给定 ...

  3. HDU 1043 八数码(A*搜索)

    在学习八数码A*搜索问题的时候须要知道下面几个点: Hash:利用康托展开进行hash 康托展开主要就是依据一个序列求这个序列是第几大的序列. A*搜索:这里的启示函数就用两点之间的曼哈顿距离进行计算 ...

  4. A*算法解决八数码问题 Java语言实现

    0X00 定义 首先要明确一下什么是A*算法和八数码问题? A*(A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法也是一种启发性的算法,也是解决许多搜索问题的有效算法.算法中的距离估 ...

  5. HUD 1043 Eight 八数码问题 A*算法 1667 The Rotation Game IDA*算法

    先是这周是搜索的题,网站:http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=6041 主要内容是BFS,A*,IDA*,还有一道K短路的,.. ...

  6. HDU 1043 Eight 八数码问题 A*算法(经典问题)

    HDU 1043 Eight 八数码问题(经典问题) 题意 经典问题,就不再进行解释了. 这里主要是给你一个状态,然后要你求其到达\(1,2,3,4,5,6,7,8,x\)的转移路径. 解题思路 这里 ...

  7. Java实现 蓝桥杯 算法提高 八数码(BFS)

    试题 算法提高 八数码 问题描述 RXY八数码 输入格式 输入两个33表格 第一个为目标表格 第二个为检索表格 输出格式 输出步数 样例输入 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 ...

  8. 八数码难题之 A* 算法

    人生第一个A*算法-好激动-- 八数码难题--又称八数码水题,首先要理解一些东西: 1.状态可以转化成整数,比如状态: 1 2 3 4 5 6 7 8 0 可以转化成:123456780这个整数 2. ...

  9. 【C++算法设计】八数码问题

    八数码问题 [题意] 编好为1~8的8个正方形滑块摆成3行3列(一个格子为空),如图所示 每次可以移动空格相邻的滑块到空格,要计算出能移动出目标局面的最小步数,如无法达到则输出-1. [分析] 我们可 ...

  10. 【算法】BFS+哈希解决八数码问题

    15拼图已经有超过100年; 即使你不叫这个名字知道的话,你已经看到了.它被构造成具有15滑动砖,每一个从1到15上,并且所有包装成4乘4帧与一个瓦块丢失.让我们把丢失的瓷砖“X”; 拼图的目的是安排 ...

随机推荐

  1. 关于Qt国产化系统开发的几点总结

    随着国产化的兴起,各种国产系统和国产数据库等逐渐进入开发者的世界,科普几个要点. 中标麒麟neokylin基于fedora. 银河麒麟kylin早期版本比如V2基于freebsd,新版本V4.V10基 ...

  2. Qt编写地图综合应用42-离线轮廓图

    一.前言 离线轮廓图使用起来,就没有在线轮廓图方便了,在线的可以直接传入名称拿到,离线的只能自己绘制了,一般需要用区域轮廓图下载器将你需要的区域下载好对应的js文件,其实就是一堆坐标点集合数组,这些数 ...

  3. Qt编写可视化大屏电子看板系统19-横向柱状图

    一.前言 横向柱状图的绘制这玩意当初还着实花费了一些时间,因为从v1版本开始,默认XY坐标轴是没有交换位置的处理的,也只有垂直的柱状图,要想换成横向的柱状图必须是自己拿到数据重新绘制,数据值的设置一般 ...

  4. lottie-web动画库在HTML5页面中和在vue项目中的两种使用方式

    本文主要介绍lottie-web动画库在HTML5页面中和在vue项目中的两种使用方式. 1.在HTML5页面中的使用方式 具体使用步骤详见下面的代码: <!DOCTYPE html> & ...

  5. IM通讯协议专题学习(十):初识 Thrift 序列化协议

    本文由字节跳动技术团队杨晨曦分享,本文有修订和改动. 1.引言 本文将带你一起初步认识Thrift的序列化协议,包括Binary协议.Compact协议(类似于Protobuf).JSON协议,希望能 ...

  6. 跟着源码一起学:手把手教你用WebSocket打造Web端IM聊天

    本文作者芋艿,原题"芋道 Spring Boot WebSocket 入门",本次有修订和改动. 一.引言 WebSocket如今在Web端即时通讯技术应用里使用广泛,不仅用于传统 ...

  7. SpringBoot原理深入及源码剖析(二) 自定义Starter及SpringBoot执行原理

    自定义Starter SpringBoot starter机制 SpringBoot由众多starter组成(一系列的自动化配置的starter插件),SpringBoot之所以流行,也是因为star ...

  8. WPF 怎么利用behavior优雅的给一个Datagrid添加一个全选的功能

    前言:我在迁移旧项目代码的时候发现别人写很多界面都涉及到一个DataGrid的全选,但是每个都写的很混乱,现在刚好空闲下来,写一个博客, 给部分可能不太会写这个的同学讲一下,怎么实现全选功能,并且可以 ...

  9. 微服务实战系列(五)-注册中心Eureka与nacos区别-copy

    1. 场景描述 nacos最近用的比较多,介绍下nacos及部署吧,刚看了下以前写过类似的,不过没写如何部署及与eureka区别,只展示了效果,补补吧. 2.解决方案 2.1 nacos与eureka ...

  10. w3cschool-HBase官方文档-2数据模型

    HBase数据模型 2018-03-03 15:20 更新 HBase数据模型 在 HBase 中,数据模型同样是由表组成的,各个表中又包含数据行和列,在这些表中存储了 HBase 数据.在本节中,我 ...