实验8 搜索技术

实验8 搜索技术

一、实验目的
(1)掌握搜索技术的相关理论,能根据实际情况选取合适的搜索方法;
(2)进一步熟悉盲目搜索技术,掌握其在搜索过程中的优缺点;
(3)掌握启发式搜索的思想,能针对实际问题选取合适的评价函数;
(4)掌握问题归约的解决问题的思想,掌握与或图的搜索技术并能应用;
(5)深入理解博弈树搜索方法,并能应用于对弈类问题;
(6)根据自身情况,能选择合适的编程语言,实现启发式搜索、博弈树搜索方法、α-β剪枝算法,并能应用于实际AI问题。

二、实验内容
选择一种编程语言(最好为python或java),编程实现下面题目要求。
1、八数码难题
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格可用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局,找到一种启发式移动方法,实现从初始布局到目标布局的转变,并与实验7 的盲目移动方法对比。
在这里插入图片描述

1、需求分析
在一个3×3的九宫格棋盘上,摆有8个正方形方块,每一个方块都标有1~8中的某一个数字。棋盘中留有一个空格,要求按照每次只能将与空格相邻的方块与空格交换的原则,将任意摆放的数码盘(初始状态)逐步摆成某种给定的数码盘的排列方式(目标状态)。

2、数据结构、功能模块设计与说明
运用启发式搜索,利用问题拥有启发信息引导搜索,以达到减小搜索范围、降低问题复杂度的目的。在启发式搜索过程中,要对Open表进行排序,这就要有一种方法来计算待扩展结点有希望通向目标结点的不同程度,人们总是希望找到最有可能通向目标结点的待扩展结点优先扩展。一种最常用的方法是定义一个评价函数对各个结点进行计算,其目的就是用来估算出“有希望”的结点。用f来标记评价函数,用f(n)表示结点n的评价函数值,并用f来排列等待扩展的结点,然后选择具有最小f值的结点作为下一个要扩展的结点。
A*算法是一种有序搜索算法,其特点在于对评价函数的定义上。这个评估函数f使得在任意结点上其函数值f(n)能估算出结点S到结点n的最小代价路径的代价与从节点n到某一目标节点的最小代价路径的代价的总和,也就是说f(n)是约束通过结点n的一条最小代价路径的代价的估计。

3、核心代码(不要将全部代码贴在报告上)与测试结果说明
核心代码:
定义A*算法

def A_start(start, end, distance_fn, generate_child_fn, time_limit=10):# 创建起始状态结点和目标状态结点对象,并分别计算其哈希值root = State(0, 0, start, hash(str(BLOCK)), None)end_state = State(0, 0, end, hash(str(GOAL)), None)# 检查起始状态是否就是目标状态,如果是,则直接输出提示信息if root == end_state:print("start == end !")# 将起始状态结点加入到OPEN表中,并对OPEN表进行堆化操作OPEN.append(root)heapq.heapify(OPEN)# 创建一个哈希集合,用于存储已经生成的状态结点的哈希值,并将起始状态结点的哈希值添加到集合中node_hash_set = set()node_hash_set.add(root.hash_value)# 记录算法开始的时间start_time = datetime.datetime.now()# 进入主循环,直到OPEN表为空(搜索完成)或达到时间限制while len(OPEN) != 0:top = heapq.heappop(OPEN)# 如果当前结点就是目标状态结点,则直接输出路径if top == end_state:return print_path(top)# 产生孩子节点,孩子节点加入OPEN表generate_child_fn(cur_node=top, end_node=end_state, hash_set=node_hash_set,open_table=OPEN, dis_fn=distance_fn)# 记录当前时间cur_time = datetime.datetime.now()# 超时处理,如果运行时间超过了设定的时间限制,则输出超时提示信息并返回if (cur_time - start_time).seconds > time_limit:print("Time running out, break !")print("Number of nodes:", SUM_NODE_NUM)return -1# 如果循环结束时OPEN表为空,则表示没有找到路径,输出提示信息并返回-1print("No road !")  # 没有路径return -1

定义曼哈顿距离计算函数

def manhattan_dis(cur_node, end_node):  # 定义一个名为manhattan_dis的函数,接受两个参数cur_node(当前结点)和end_node(目标结点)# 获取当前结点和目标结点的状态矩阵cur_state = cur_node.stateend_state = end_node.statedist = 0N = len(cur_state)  # 获取状态矩阵的大小,假设为N# 遍历状态矩阵中的每个位置for i in range(N):for j in range(N):# 如果当前结点的值与目标结点的值相等,则跳过当前位置,因为这个位置已经在目标状态中if cur_state[i][j] == end_state[i][j]:continuenum = cur_state[i][j]  # 获取当前结点在状态矩阵中的值# 如果当前结点的值为0(空白格),则将目标位置设置为状态矩阵的右下角if num == 0:x = N - 1y = N - 1# 如果当前结点的值不为0,则根据当前结点的值计算其目标位置,假设目标位置为(x,y)else:x = num / Ny = num - N * x - 1# 计算当前结点与目标位置之间的曼哈顿距离,并累加到总距离中dist += (abs(x - i) + abs(y - j))# 返回计算得到的曼哈顿距离作为当前结点到目标结点的估计代价
return dist

生成子结点函数

def generate_child(cur_node, end_node, hash_set, open_table, dis_fn):# 如果当前结点就是目标结点,则直接将目标结点假如OPEN表,并返回,表示已经找到了解if cur_node == end_node:heapq.heappush(open_table, end_node)return# 获取当前结点状态矩阵的大小num = len(cur_node.state)# 遍历当前结点状态矩阵的每一个位置for i in range(0, num):for j in range(0, num):# 如果当前位置不是空格,则跳过,因为空格是可以移动的位置if cur_node.state[i][j] != 0:continue# 遍历当前位置的四个邻居位置,即上下左右四个方向for d in direction:x = i + d[0]y = j + d[1]if x < 0 or x >= num or y < 0 or y >=num:continue# 记录生成的结点数量global SUM_NODE_NUMSUM_NODE_NUM += 1# 交换空格和邻居位置的数字,生成一个新的状态矩阵state = copy.deepcopy(cur_node.state)state[i][j], state[x][y] = state[x][y], state[i][j]# 计算新状态矩阵的哈希值,并检查是否已经在哈希集合中存在,如果存在则表示已经生成过相同的状态,跳过h = hash(str(state))if h in hash_set:continue# 将新状态的哈希值添加到哈希集合中,计算新状态结点的gn(从起始结点到当前结点的代价)和hn(当前结点到目标结点的估计代价)hash_set.add(h)gn = cur_node.gn + 1hn = dis_fn(cur_node, end_node)# 创建新的状态结点对象,并将其加入到当前结点的子结点列表中,并将其加入到OPEN表中。node = State(gn, hn, state, h, cur_node)cur_node.child.append(node)heapq.heappush(open_table, node)

结果:
在这里插入图片描述

4、实验存在的问题与体会
学会了用A算法解决搜索问题,在搜索的时候比之前的盲目搜索用时更少,在其他搜索问题上用A算法也可以比盲目搜索更有效率,但前提是找到合适的估计函数。

2、编程实现一字棋游戏人机对弈,在九宫格棋盘上人机轮流在棋盘上摆各自的棋子,每次一枚,谁先取得三子一线结果的一方获胜。 (请用极小极大值搜索算法或α-β剪枝算法实现)
在这里插入图片描述

1、需求分析
用极小极大值搜索算法或α-β剪枝算法编程实现一字棋游戏人机对弈,在九宫格棋盘上人机轮流在棋盘上摆各自的棋子,每次一枚,谁先取得三子一线结果的一方获胜。
2、数据结构、功能模块设计与说明
关于核心判断部分 maxmin()解释:

该函数根据当前游戏状态的得分,计算出下一步应该走的位置。该函数的参数如下:

board:表示当前的游戏状态,是一个 3x3 的二维数组。
depth:表示搜索的深度,即预测未来多少步。
alpha:表示当前最好的评分(对于 maximizing 玩家来说),初始化为负无穷。
beta:表示当前最好的评分(对于 minimizing 玩家来说),初始化为正无穷。
maximizing:表示当前是轮到哪个玩家走棋,True 表示 maximizing 玩家,False 表示 minimizing 玩家。
该函数的返回值包括两个元素:

best_score:表示当前的最优得分。
best_move:表示当前应该走的位置。
在函数内部,首先使用 check_win 和 check_tie 函数判断当前游戏状态,如果存在胜负或平局,则返回对应的得分。如果还没有到达搜索的深度,则进入下一步的搜索。

如果当前是 maximizing 玩家,则使用 for 循环遍历棋盘中所有空位,对于每个空位,都假设 maximizing 玩家会走这个位置,并计算下一步的得分。如果得分比当前最优得分更好,则更新最优得分和最优位置。同时,更新 alpha 的值为当前最优得分和 alpha 中的最大值。如果 beta 的值小于或等于 alpha,则可以停止搜索并返回结果。

如果当前是 minimizing 玩家,则与 maximizing 玩家的情况类似,只是更新的是 beta 的值。
最终返回当前的最优得分和最优位置。

3、核心代码(不要将全部代码贴在报告上)与测试结果说明
核心代码:
minmax函数

# 极大极小/α-β剪枝算法
def minmax(board, depth, alpha, beta, maximizing):if check_win(board, "X"):return -10, Noneif check_win(board, "O"):return 10, Noneif check_tie(board):return 0, Noneif maximizing:best_score = -math.infbest_move = Nonefor row in range(3):for col in range(3):if board[row][col] == " ":board[row][col] = "O"score, _ = minmax(board, depth - 1, alpha, beta, False)board[row][col] = " "if score > best_score:best_score = scorebest_move = (row, col)alpha = max(alpha, best_score)if beta <= alpha:breakreturn best_score, best_moveelse:best_score = math.infbest_move = Nonefor row in range(3):for col in range(3):if board[row][col] == " ":board[row][col] = "X"score, _ = minmax(board, depth - 1, alpha, beta, True)board[row][col] = " "if score < best_score:best_score = scorebest_move = (row, col)beta = min(beta, best_score)if beta <= alpha:breakreturn best_score, best_move

结果:
在这里插入图片描述

4、实验存在的问题与体会
掌握了极大极小值搜索算法和α-β算法的算法思想。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/73367.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

区块链知识点2

1.用非对称加密方式传输对称加密的密钥 2.数字签名&#xff1a;私钥加密&#xff0c;公钥解密 3.RSA由于计算较大&#xff0c;通常用于数字签名和密钥交换&#xff0c;而非直接的数据加密。 4.签名过程 发送方A将消息用Hash算法产生一个消息摘要(Message Digest) 发…

消费级显卡上ollama部署QwQ32B

ollama部署QwQ32B QwQ32B硬件要求 魔改2080ti 的 22G 显存差不多够用 ollama中的是Q4_K_M量化模型 硬件配置模型推理模型高效微调模型全量微调显存占用最低配置显存占用最低配置显存占用最低配置FP_1664GRTX3090&#xff0a;4&#xff08;94G&#xff09;92GRTX3090&#xff0a…

万字长文详解嵌入式电机软件开发

目录 第一章:嵌入式电机概述 1.1 电机类型:选对 “主角” 有多重要? 1.2 嵌入式系统特点:硬件的 “灵魂” 靠什么支撑? 第二章:开发环境搭建 2.1 硬件平台选择:给 “大脑” 找个好载体 2.1.1 ARM Cortex 系列:全能选手 2.1.2 AVR 微控制器:简约而不简单 2.1.3 …

python-54-使用环境变量库python-dotenv进行应用程序配置参数的管理

文章目录 1 python-dotenv简介1.1 十二因素原则1.1.1 引言1.1.2 背景1.1.3 十二因素1.2 python-dotenv概述2 python-dotenv应用2.1 文件.env2.2 方式一load_dotenv()2.3 方式二dotenv_values()2.4 指定配置文件路径3 Flask结合dotenv3.1 Flask的config3.2 结合使用4 代码中的配…

How to introduce a new product in English?

How to introduce a new product in English? References Introducing a new product Forever: Yeah, sure. Today I am glad to announce [əˈnaʊns] that our new App has made it through the final testing stage. The name of the new App is on-device Stable Diffus…

数字电路 | 触发器 / 单稳态触发器 / 双稳态触发器

注&#xff1a;本文为 “数字电路 | 触发器” 相关文章合辑。 如有内容异常&#xff0c;请看原文。 未整理。 数字电路基础 — 触发器 Oliver-H 已于 2024-04-07 15:06:25 修改 触发器&#xff08;Flip-Flop&#xff09; 也是数字电路中的一种具有记忆功能的逻辑元件。触发…

SSM基础专项复习5——Maven私服搭建(2)

系列文章 1、SSM基础专项复习1——SSM项目整合-CSDN博客 2、SSM基础专项复习2——Spring 框架&#xff08;1&#xff09;-CSDN博客 3、SSM基础专项复习3——Spring框架&#xff08;2&#xff09;-CSDN博客 4、SSM基础专项复习4——Maven项目管理工具&#xff08;1&#xff…

【Java 基础(人话版)】进制转换

进制的简单介绍 整数可以使用四种不同的进制表示方式&#xff1a; 二进制 (Binary)&#xff1a;由 0 和 1 组成&#xff0c;满 2 进 1&#xff0c;以 0b 或 0B 开头表示。十进制 (Decimal)&#xff1a;由 0-9 组成&#xff0c;满 10 进 1&#xff0c;是最常用的数值表示方式。…

11.anaconda中的jupyter使用、及整合dataspell

目录 概述jupyterjupyter notebook1.生成配置文件修改notebook保存目录问题问题2&#xff0c;无法获取token 安装 DataSpell注意配置运行环境DataSpell 使用 概述 前置安装如有问题&#xff1a; 1.Python、anaconda介绍、安装及使用 jupyter jupyter notebook 1.生成配置文…

蓝桥杯 之 回溯之充分剪枝

文章目录 买瓜最大数字 在蓝桥杯当中&#xff0c;对于回溯是属于一个必考的问题&#xff0c;但是除了回溯的几个基本的问题&#xff0c;如果通过剪枝来提前删去无效的分支&#xff0c;以大大减少时间复杂度是需要我们进一步思考的问题&#xff01;回溯的基本问题&#xff1a; 回…

【春招笔试】2025.03.13-蚂蚁春招笔试题

题目总结 题目一:区间未出现的最小值之和 1️⃣:统计全为1的子数组数量和全为0的子数组数量,利用公式计算 2️⃣:利用数学公式 n(n+1) - 2N0 - N1 计算最终答案 难度:中等 这道题目的关键在于理解 mex 的概念,并发现对于只含 0 和 1 的数组,mex 值只可能是 0、1 或 2。…

iOS 模块化架构设计:主流方案与实现详解

随着 iOS 工程规模的扩大&#xff0c;模块化设计成为提升代码可维护性、团队协作效率和开发灵活性的关键。本文将探讨为什么需要模块化&#xff0c;介绍四种主流的模块化架构方案&#xff08;协议抽象、依赖注入、路由机制和事件总线&#xff09;&#xff0c;并通过代码示例和对…

太速科技-636-基于FMC的Kintex XCKU060高性能PCIe载板

基于FMC的Kintex XCKU060高性能PCIe载板 一、板卡概述 板卡主控芯片采用Xilinx 公司的 Kintex UltraScale系列FPGA XCKU060-2FFVA1156。板载 2 组 64bit 的DDR4 SDRAM&#xff0c;每组容量2GB&#xff0c;可稳定运行在2400MT/s。支持PCIE Gen3 x8模式及一路FMC HPC接口。同…

【Spring Cloud】 核心组件全解析与 2024 【微服务框架】选型指南

《Spring Cloud 核心组件全解析与 2024 微服务框架选型指南》 第一部分&#xff1a;Spring Cloud 核心组件及功能速查表 组件名称核心功能一句话总结详细功能说明Eureka服务注册与发现的“通讯录”Server存储服务节点信息&#xff0c;Client自动注册和拉取列表&#xff0c;实现…

SAP SD学习笔记31 - 销售BOM

上一篇讲 前受金处理(预付款处理)。 SAP SD学习笔记29 - 前受金处理(预收款处理)_fplt 付款申请与sd 数据表的关联关系-CSDN博客 本章继续讲SAP SD模块的其他知识&#xff1a;销售BOM。 销售BOM在现场还是会用到的。 目录 1&#xff0c;销售BOM概要 2&#xff0c;受注BOM的…

动态路径规划——01背包问题讲解和通过滚动数组优化

如果没有动态路径规划基础的兄弟可以出去了&#xff0c;这个题目有两个问题 第一问讲解&#xff1a; 1.定义状态表示 刚开始我做的时候根据我的经验定义了一个状态表示dp[i]表示从1到i个物品中选择的最大价值&#xff0c;但是这个状态表示有一个明显的问题&#xff0c;我怎么知…

Java程序的逻辑控制

目录 1、顺序结构2、分支结构2.1、if 语句2.2、switch 语句 3、循环结构3.1、while 语句3.2、break3.3、continue3.4、for 循环3.5、do while 语句 1、顺序结构 顺序结构比较简单&#xff0c;按照代码书写的顺序一行一行执行。如果调整代码的书写顺序, 则执行顺序也发生变化。…

【鸿蒙开发】Hi3861学习笔记- GPIO之LED

00. 目录 文章目录 00. 目录01. GPIO概述02. 硬件设计03. 软件设计04. 实验现象05. 附录 01. GPIO概述 GPIO&#xff08;General-purpose input/output&#xff09;即通用型输入输出。通常&#xff0c;GPIO控制器通过分组的方式管理所有GPIO管脚&#xff0c;每组GPIO有一个或多…

你的完美主义:从缺陷到超能力

所属专栏&#xff1a;《逻辑辨证系列》 前情回顾&#xff1a; 《完美还是完成》&#xff08;一&#xff09;&#xff1a;完成还是完美—完成大于完美 时间、机会、情绪成本 先完成 … 本期&#xff1a; 《完美还是完成》&#xff08;二&#xff09;&#xff1a;你的完美主…

438.找出字符串中所有字母异位词

题目&#xff1a; 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 示例 1: 输入: s "cbaebabacd", p "abc" 输出: [0,6] 解释: 起始索引等于 0 的子串是 "cba&q…