實驗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.pswp.cn/diannao/73367.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73367.shtml
英文地址,請注明出處:http://en.pswp.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…