import numpy as np
from queue import Queue
class State:
def __init__(self, state, directionFlag=None, parent=None, f=0):
self.state = state
self.direction = ['up', 'down', 'right', 'left']
if directionFlag:
self.direction.remove(directionFlag)
self.parent = parent
self.f = f
self.expanded_nodes = 0 # 初始化扩展节点数
self.generated_nodes = 0 # 初始化生成节点数
def getDirection(self):
return self.direction
def setF(self, f):
self.f = f
return
# 打印结果
def showInfo(self):
for i in range(len(self.state)):
for j in range(len(self.state)):
print(self.state[i, j], end=' ')
print("\n")
print('->')
return
# 获取0点
def getZeroPos(self):
postion = np.where(self.state == 0)
return postion
# 曼哈顿距离 f = g + h,g=1,如果用宽度优先的评估函数可以不调用该函数
def getFunctionValue(self):
cur_node = self.state.copy()
fin_node = self.answer.copy()
dist = 0
N = len(cur_node)
for i in range(N):
for j in range(N):
if cur_node[i][j] != fin_node[i][j]:
index = np.argwhere(fin_node == cur_node[i][j])
x = index[0][0] # 最终x距离
y = index[0][1] # 最终y距离
dist += (abs(x - i) + abs(y - j))
return 0
# 切比雪夫距离作为评估函数
# def getFunctionValue(self):
# cur_node = self.state.copy()
# fin_node = self.answer.copy()
# dist = 0
# N = len(cur_node)
#
# for i in range(N):
# for j in range(N):
# if cur_node[i][j] != fin_node[i][j]:
# index = np.argwhere(fin_node == cur_node[i][j])
# x = index[0][0] # 最终x距离
# y = index[0][1] # 最终y距离
# dist += max(abs(x - i) , abs(y - j))
# return dist +1
def nextStep(self):
if not self.direction:
return []
subStates = []
boarder = len(self.state) - 1
# 获取0点位置
x, y = self.getZeroPos()
# 向左
if 'left' in self.direction and y > 0:
s = self.state.copy()
tmp = s[x, y - 1]
s[x, y - 1] = s[x, y]
s[x, y] = tmp
news = State(s, directionFlag='right', parent=self)
news.setF(news.getFunctionValue())
subStates.append(news)
# 向上
if 'up' in self.direction and x > 0:
# it can move to upper place
s = self.state.copy()
tmp = s[x - 1, y]
s[x - 1, y] = s[x, y]
s[x, y] = tmp
news = State(s, directionFlag='down', parent=self)
news.setF(news.getFunctionValue())
subStates.append(news)
# 向下
if 'down' in self.direction and x < boarder:
# it can move to down place
s = self.state.copy()
tmp = s[x + 1, y]
s[x + 1, y] = s[x, y]
s[x, y] = tmp
news = State(s, directionFlag='up', parent=self)
news.setF(news.getFunctionValue())
subStates.append(news)
# 向右
if self.direction.count('right') and y < boarder:
# it can move to right place
s = self.state.copy()
tmp = s[x, y + 1]
s[x, y + 1] = s[x, y]
s[x, y] = tmp
news = State(s, directionFlag='left', parent=self)
news.setF(news.getFunctionValue())
subStates.append(news)
# 返回F值最小的下一个点
subStates.sort(key=compareNum)
return subStates[0]
def nextSteps(self):
if not self.direction:
return []
subStates = []
boarder = len(self.state) - 1
# 获取0点位置
x, y = self.getZeroPos()
# 向左
if 'left' in self.direction and y > 0:
s = self.state.copy()
tmp = s[x, y - 1]
s[x, y - 1] = s[x, y]
s[x, y] = tmp
news = State(s, directionFlag='right', parent=self)
news.setF(news.getFunctionValue())
subStates.append(news)
# 向上
if 'up' in self.direction and x > 0:
# it can move to upper place
s = self.state.copy()
tmp = s[x - 1, y]
s[x - 1, y] = s[x, y]
s[x, y] = tmp
news = State(s, directionFlag='down', parent=self)
news.setF(news.getFunctionValue())
subStates.append(news)
# 向下
if 'down' in self.direction and x < boarder:
# it can move to down place
s = self.state.copy()
tmp = s[x + 1, y]
s[x + 1, y] = s[x, y]
s[x, y] = tmp
news = State(s, directionFlag='up', parent=self)
news.setF(news.getFunctionValue())
subStates.append(news)
# 向右
if self.direction.count('right') and y < boarder:
# it can move to right place
s = self.state.copy()
tmp = s[x, y + 1]
s[x, y + 1] = s[x, y]
s[x, y] = tmp
news = State(s, directionFlag='left', parent=self)
news.setF(news.getFunctionValue())
subStates.append(news)
# 返回F值最小的下一个点
subStates.sort(key=compareNum)
return subStates
def a_star_search_efficiency(self):
open_list = []
open_list.append(self)
closed_list = []
while open_list:
current_node = open_list.pop(0)
closed_list.append(current_node)
current_node.expanded_nodes += 1 # 更新扩展节点数
if (current_node.state == current_node.answer).all():
return current_node.expanded_nodes, current_node.generated_nodes
next_states = current_node.nextSteps()
for next_state in next_states:
if next_state not in open_list and next_state not in closed_list:
open_list.append(next_state)
next_state.generated_nodes += 1 # 更新生成节点数
return current_node.expanded_nodes, current_node.generated_nodes
# A* 迭代
def solve(self):
openTable = Queue() # 使用队列代替列表
closeTable = []
openTable.put(self) # 入队
while not openTable.empty(): # 队列非空时循环
n = openTable.get() # 出队
closeTable.append(n)
self.expanded_nodes = len(closeTable)
subStates = n.nextSteps()
for subState in subStates:
path = []
if (subState.state == subState.answer).all():
while subState.parent and subState.parent != originState:
path.append(subState.parent)
subState = subState.parent
path.reverse()
return path
for state in subStates: # 将子节点入队
openTable.put(state)
else:
return None, None
# openList
# openTable = []
# # closeList
# closeTable = []
# openTable.append(self)
# while len(openTable) > 0:
# # 下一步的点移除open
# n = openTable.pop(0)
# # 加入close
# closeTable.append(n)
#
人工智能A*算法求解八数码问题(python语言实现)
需积分: 0 90 浏览量
更新于2024-01-20
1
收藏 4KB ZIP 举报
在本文中,我们将深入探讨如何使用人工智能中的A*算法来解决经典的八数码问题,并通过Python编程语言实现这一过程。八数码问题,又称滑动拼图游戏,是一个在二维网格上移动数字方块以达到特定目标排列的游戏。在这个问题中,我们通常会有一个3x3的网格,其中有一个空格,目标是将所有数字从1到8按照升序排列。
A*算法是一种有效的路径搜索算法,它结合了最佳优先搜索(如Dijkstra算法)和启发式搜索。A*的核心在于使用启发式函数来估计从当前状态到达目标状态的最佳路径的成本。在八数码问题中,我们通常使用两种启发式函数:曼哈顿距离和切比雪夫距离。
曼哈顿距离衡量的是每个数字与其目标位置在行和列上的差异总和。例如,如果一个数字在目标位置上方两行、右侧一列,其曼哈顿距离为2 + 1 = 3。这个函数简单直观,但在某些情况下可能不是最优的。
切比雪夫距离则考虑行和列的绝对差异的最大值。同样以上述情况为例,切比雪夫距离为2,因为2是2和1的最大值。切比雪夫距离在网格环境中表现良好,因为它允许更灵活的移动策略。
在Python实现A*算法时,我们需要创建一个节点类来表示拼图的状态,包括当前状态、父节点以及启发式成本。我们还需要一个优先队列来存储待评估的节点,按照他们的总成本(实际成本加上启发式成本)进行排序。搜索过程中,每次从队列中取出成本最低的节点,检查是否达到目标状态,如果不是,则生成所有可能的子节点并更新它们的成本和父节点信息,然后将子节点放入队列。
宽度优先搜索(BFS)是另一种解决八数码问题的方法,它通过优先探索离初始状态近的节点来寻找解决方案。在BFS中,所有节点按距离从初始状态的步数排序。虽然BFS在某些情况下可能会比A*算法更耗时,但它保证找到最短的解,而A*则可能更快地找到解决方案,但不一定是步数最少的。
在Python代码实现中,我们可以使用`heapq`库来管理优先队列,`collections`库中的`deque`来实现宽度优先搜索的队列。同时,我们需要一个数据结构来存储已经访问过的节点,以避免重复搜索。
总结来说,"人工智能A*算法求解八数码问题(python语言实现)"这个主题涵盖了以下几个关键知识点:
1. 八数码问题的定义和目标
2. A*算法的原理及其在路径搜索中的应用
3. 曼哈顿距离和切比雪夫距离作为启发式函数
4. Python编程实现A*算法的步骤,包括节点表示、优先队列和搜索过程
5. 宽度优先搜索(BFS)的概念和比较
通过理解和实现这些内容,你可以深入理解人工智能在解决复杂问题中的能力,并掌握一种实用的算法来解决实际问题。
kanfoker
- 粉丝: 26
- 资源: 1
最新资源
- 《登飞来峰》教学设计.docx
- 《登飞来峰》教学设计与反思.docx
- 《登幽州台歌》课件.pptx
- (178914818)基于STM32的DS18B20温度传感器应用程序
- (177818802)基于Django和Hadoop集群进行的大数据分析平台.zip
- rocketmq-client-cpp-2.2.0编译的5个文件
- (179049424)CNN卷积神经网络Python的代码实现
- PM的matlab代码
- IMG_20241226_170144.jpg
- html+css 圣诞树html网页代码 圣诞节代码html飘雪花
- (177098236)可直接运行,脉冲雷达测速测距的matlab程序,雷达测距matlab代码
- 经典力学教材:Goldstein, Poole, Safko 第三版的详细解析与应用
- (176438242)毕业设计,采用Hadoop+Hive构建数据仓库,使用django+echarts构建前端web网站对业务指标进行可视化呈现
- Java基础知识点总结与实战指南PDF版
- (179458240)鲁棒优化- C&CG算法求解两阶段鲁棒优化
- chrom Axure插件