97. 小明逛公園,Floyd 算法,127. 騎士的攻擊,A * 算法

97. 小明逛公園

Floyd 算法

dijkstra,?bellman_ford 是求單個起點到單個終點的最短路徑,dijkstra無法解決負權邊的問題,?bellman_ford解決了負權邊的問題,但二者都是基于單起點和單終點。

而Floyd 算法旨在解決多個起點到多個終點的最短路徑問題,且Floyd 算法對邊的權值正負沒有要求,都可以處理Floyd 算法采用的是動態規劃的思想,那涉及到動態規劃就需要用到動態規劃五部曲了。

  • 1. dp定義

dp[i][j][k] 表示 節點i 到 節點j 以[1...k] 集合中的一個節點為中間節點的最短距離

k 是指取?區間[1,k] 中的一個節點作為中間節點;節點i 到 節點j 的最短路徑中 一定是經過很多節點,那么這個集合用[1...k] 來表示。

  • 2. dp初始化

剛開始進來時,每條邊的關系進來時都不需要經過中間節點,因此輸入的邊的關系用dp[i][j][0]進行初始化。

  • 3. dp遞推公式

當到達節點k時,此時有兩種狀態,一種是經過節點k,另外一種是不經過中間節點k。

  1. 經過節點k,那此時dp[i][j][k] = dp[i][k][k-1] + dp[k][j][k-1]
  2. 不經過中間節點k,那此時dp[i][j][k] = dp[i][j][k-1]

求的是最小距離,因此dp[i][j][k] = min(?dp[i][j][k-1] + dp[k][j][k-1],?dp[i][j][k-1])

補充:節點1 到 節點9 的最短距離 是不是可以由 節點1 到節點5的最短距離 + 節點5到節點9的最短距離組成呢?即 grid[1][9] = grid[1][5] + grid[5][9]。

  • 4. 遍歷順序

由于初始化得到的是一個平面,且遞推公式是往上去進行遞推的,因此需要三個循環去進行遞推,k處于外循環,i,j構成內循環。即先平面再高度的方式去進行遞推。

  • 5. 打印dp

Code:


if __name__ == "__main__":scenery_size, road_size = map(int, input().split())length = scenery_size + 1# 1. dp數組定義dp = [ [[float('inf')]*length for _ in range(length)] for _ in range(length) ]     ##先構造一個二維數組,再外封遍歷從而構成三維數組# 2. dp初始化for _ in range(road_size):u, v, w = map(int, input().split())dp[u][v][0] = w         dp[v][u][0] = w         ## 無向圖Q = int(input())plan = []for _ in range(Q):start, end = map(int, input().split())plan.append([start,end])# 3. 遞推公式# dp[i][j][k] = min(dp[i][j][k-1], dp[i][k][k-1]+dp[k][j][k-1])# 4.遍歷順序for k in range(1, length):for i in range(1,length):for j in range(1,length):dp[i][j][k] = min(dp[i][j][k-1], dp[i][k][k-1]+dp[k][j][k-1])# 5. 打印dp數組for i in range(len(plan)):  ## 結果輸出start = plan[i][0]end = plan[i][1]if dp[start][end][scenery_size] != float('inf'):print(dp[start][end][scenery_size])else:print(-1)

其他:

  • dp = [ [[float('inf')]*length for _ in range(length)] for _ in range(length) ]

先構造 length 個list, 然后每個list里面存儲的是一個二維矩陣。

  • Floyd的算法是基于點的角度去進行計算的,因此適合于稠密圖(邊多),不適合稀疏圖(邊少)。也就說當你圖中有1萬個點,但只有一條邊時,此時用這個算法就不合適。(計算時間復雜度O(n^3), n是節點數目)

127. 騎士的攻擊

A * 算法

關鍵:啟發式函數,來確定廣搜的方向。

A * 算法其實就是個改進版的廣搜,其與BFS的區別如下。BFS是每次都往四面八方去進行搜索,而A*會計算當前離終點的距離去判斷要往那個方向進行廣搜,從而極大減少了廣搜的次數。

由于每次BFS都是選取dis最小的一個元素進行下一次BFS,因此需要用到小頂堆

dis = cur_dis + remaining_dis(通過引入這個變量來明確遍歷的方向)

  • cur_dis: 表示從起點出發到當前節點時已走過的步數。(題目要求是輸出步數,而不是距離)
  • remaining_dis:當前節點 到 終點的距離。
  • dis 與?cur_dis ?呈正相關,當dis有最小時,此時cur_dis有最小。

如何計算、保存 cur_dis,并通過小頂堆對dis進行排序,通過堆頂元素來指導BFS的方向是這道題的關鍵。??

Code

from collections import deque
import heapq
import mathdirections = [[2,1],[-2,1],[1,2],[-1,2],[2,-1],[-2,-1],[1,-2],[-1,-2]]def caculate_dis(point_1, point_2):     ## 計算當前點到終點的距離return ((point_1[0] - point_2[0]) ** 2 + (point_1[1] - point_2[1]) ** 2) ** 0.5    ### **2 表示平方, ** 0.5 表示sqrt(),即開根def A_star(start, end):dis = -1length = 1001q = [ (caculate_dis(start, end), start) ]   ## 隊列內存儲一個元組,元組包含了距離信息和起點位置。在小頂堆中會優先對元組中靠左的元素進行排序heapq.heappush(q, (caculate_dis(start, end), start))step = {start: 0}       ## 一個字典,來記錄從起點到當前節點所走過的距離。數組不能作為key值while q:        ## q是一個隊列,跟BFS的思路一樣dis, cur = heapq.heappop(q)     ## 推出小頂堆的堆頂if cur == end:      ## 當前節點抵達終點return step[cur]for x_move, y_move in directions:new_x = cur[0] + x_movenew_y = cur[1] + y_moveif new_x < 1 or new_x > 1000 or new_y < 1 or new_y > 1000:continuenew = (new_x, new_y)step_new = step[cur] + 1  #計算起點到當前節點所走過的距離,每走一次加一次if step_new < step.get(new, float('inf')):  ## 不存在new這個key時,輸出inf。 如果從起點出發有走更少的距離抵達目前這個點,則不更新step[new] = step_new  # 記錄從起點到當前節點所走過的距離heapq.heappush(q, (caculate_dis(new, end)+step[new], new))if __name__ == "__main__":test_num = int(input())for _ in range(test_num):start_x, start_y, end_x, end_y = map(int, input().split())start = (start_x, start_y)end = (end_x, end_y)min_List = A_star(start, end)print(min_List)
from collections import defaultdict
import math
import heapqdirections = [ [2,1], [2,-1],[1,2], [1, -2],[-2,1], [-2,-1],[-1,2], [-1,-2],]def caculate_dis(cur, end):         ## 這里不能改精度,會影響搜索dis = math.sqrt((cur[0] - end[0])**2 + (cur[1] - end[1])**2)return disdef A_star(start, end):queue = [(caculate_dis(start,end), start)]heapq.heappush(queue, (caculate_dis(start,end), start))step = {}step[start] = 0while queue:dis, cur = heapq.heappop(queue)if cur == end:return disfor x_move, y_move in directions:new_x = cur[0] + x_movenew_y = cur[1] + y_moveif new_x < 1 or new_x > 1000 or new_y < 1 or new_y > 1000:continuenew = (new_x, new_y)step_new = step[cur] + 1if step_new < step.get(new, float('inf')):step[new] = step_newheapq.heappush(queue, ((caculate_dis(new, end)+step_new),new))## 浮點數+整數 = 浮點數,后續堆result結果進行int轉換就行if __name__ == "__main__":test_num = int(input())for _ in range(test_num):start_x, start_y, end_x, end_y = map(int, input().split())start = (start_x, start_y)end = (end_x, end_y)min_result = A_star(start, end)print(int(min_result))

注意:

  • 為什么需要這個判斷 if step_new < step.get(new, float('inf'))

因為走到同一個節點下所用的步數可以步數,但我么要求的是所用步數最少的。如上,只有紅色箭頭是所花步數是最少的。

  • 另外由于A*算法具有一定的方向性(小頂堆+dis實現),因此每次BFS只會選取一個更靠近終點的點進行下一次BFS,故不會存在因為重復遍歷而出現死循環的問題。

缺點:

  • 小頂堆內維護了很多元組,但實際用到的時候只是使用到了堆頂。如果在一次路徑搜索中,大量不需要訪問的節點都在隊列里,會造成空間的過度消耗。
  • A*算法只擅長給出明確的目標 然后找到最短路徑。如果給出 多個可能的目標,然后在這多個目標中 選擇最近的目標,則A * 就不擅長了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/96568.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/96568.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/96568.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

?崩壞世界觀中的安全漏洞與哲學映射:從滲透測試視角解構虛擬秩序的脆弱性?

?崩壞世界觀&#xff1a;游戲中的世界&#xff0c;是真實&#xff0c;也是虛幻的&#xff01;對于游戲中的NPC角色而言&#xff0c;TA們生存的世界&#xff0c;是真實的&#xff01;對于游戲玩家而言&#xff0c;游戲中的世界&#xff0c;是虛擬的&#xff01;通過沉浸式的游戲…

【離線安裝】CentOS Linux 7 上離線部署Oracle 19c(已成功安裝2次)

1.部署參考鏈接&#xff1a; CentOS 7 rpm方式離線安裝 Oracle 19chttps://blog.csdn.net/Vampire_1122/article/details/123038137?fromshareblogdetail&sharetypeblogdetail&sharerId123038137&sharereferPC&sharesourceweixin_45806267&sharefromfrom…

小白向:Obsidian(Markdown語法學習)快速入門完全指南:從零開始構建你的第二大腦(免費好用的筆記軟件的知識管理系統)、黑曜石筆記

一、認識Obsidian&#xff1a;不只是筆記軟件的知識管理系統 1.1 什么是Obsidian Obsidian是一個基于本地存儲的知識管理系統&#xff0c;它將你的所有筆記以純文本Markdown格式保存在電腦本地。這個名字來源于黑曜石——一種火山熔巖快速冷卻形成的玻璃質巖石&#xff0c;象…

攻防世界—Confusion1—(模板注入ssti)

一.解題在login和register的頁面中發現這個文件路徑接下去就找有什么點可以利用二.ssti通過題目信息可知是一只蛇把一只大象纏繞起來了&#xff0c;蛇代表python&#xff0c;大象代表php這邊通過python可以推測可能是模板注入&#xff0c;這邊我看其他的解題是說通過看報文信息…

【Protues仿真】基于AT89C52單片機的超聲波測距

目錄 1 HCSR04超聲波測距傳感器 1.1 基本參數 1.2 引腳說明 1.3 工作原理&#xff08;時序圖&#xff09; 2 基于AT89C52單片機的超聲波測距電路原理圖 2.1 硬件連接說明 2.2 工作原理 3 基于AT89C52單片機的超聲波測距控制程序 3.1.1 初始化設置 3.1.2 超聲波測距原…

LLM - Agent核心架構:四大“身體”部件

文章目錄一、Agent核心架構&#xff1a;四大“身體”部件1. 核心大腦&#xff1a;大型語言模型&#xff08;LLM&#xff09;2. 記憶系統&#xff1a;短期與長期記憶3. 工具箱&#xff08;Toolkit&#xff09;&#xff1a;從“思想家”到“行動家”4. 驅動循環&#xff08;Engin…

html-docx-js 導出word

2025.08.23今天我學習了如何將html頁面內容導出到word中&#xff0c;并保持原有格式&#xff0c;效果如下&#xff1a;代碼如下&#xff1a;1&#xff1a;列表頁面按鈕<el-button type"warning" plain icon"el-icon-download" size"mini" cli…

Science Robotics 通過人機交互強化學習進行精確而靈巧的機器人操作

機器人操作仍然是機器人技術中最困難的挑戰之一&#xff0c;其方法范圍從基于經典模型的控制到現代模仿學習。盡管這些方法已經取得了實質性進展&#xff0c;但它們通常需要大量的手動設計&#xff0c;在性能方面存在困難&#xff0c;并且需要大規模數據收集。這些限制阻礙了它…

Dism++備份系統時報錯[句柄無效]的解決方法

當使用Dism進行系統備份時遇到“[句柄無效]”的錯誤&#xff0c;這通常是由于某些文件或目錄的句柄無法正確訪問或已被占用所導致。以下是一種有效的解決方法&#xff1a;一、查看日志文件定位日志文件&#xff1a;首先&#xff0c;打開Dism軟件所在的目錄&#xff0c;并找到其…

華為/思科/H3C/銳捷操作系統操作指南

好的,這是一份針對 華為(VRP)、思科(IOS/IOS-XE)、H3C(Comware)和銳捷(Ruijie OS) 這四大主流網絡設備廠商操作系統的對比操作指南。本指南將聚焦于它們的共性和特性,幫助你快速掌握多廠商設備的基本操作。 四大網絡廠商操作系統綜合操作指南 一、 核心概念與模式對…

一文讀懂 DNS:從域名解析到百度訪問全流程

目錄 前言 一、什么是 DNS&#xff1f;—— 互聯網的 “地址簿” 為什么需要 DNS&#xff1f; DNS 的核心參數 二、DNS 解析原理&#xff1a;遞歸與迭代的協作 1. 兩種核心查詢方式 2. 完整解析流程&#xff08;以www.baidu.com為例&#xff09; 緩存清理命令 三、DNS …

初試Docker Desktop工具

文章目錄1. 概述2. 下載3. 安裝4. 注冊5. 登錄6. 啟動7. 容器8. 運行容器8.1 運行容器的鏡像8.2 獲取示例應用8.3 驗證Dockerfile文件8.4 拉取Alpine精簡鏡像8.5 創建鏡像8.6 運行容器8.7 查看前端9. 訪問靜態資源9.1 本地靜態資源9.2 創建服務器腳本9.3 修改Dockerfile文件9.4…

百度披露Q2財報:營收327億,AI新業務收入首超百億

8月20日&#xff0c;百度發布2025年第二季度財報&#xff0c;顯示季度總營收327億元&#xff0c;百度核心營收263億元&#xff0c;歸屬百度核心凈利潤74億元&#xff0c;同比增長35%。受AI驅動&#xff0c;涵蓋智能云在內的AI新業務收入增長強勁&#xff0c;首次超過100億元&am…

【字母異位分組】

思路 核心思路&#xff1a;使用排序后的字符串作為鍵&#xff0c;將原始字符串分組 鍵的選擇&#xff1a;對于每個字符串&#xff0c;將其排序后得到標準形式作為鍵分組存儲&#xff1a;使用哈希表&#xff0c;鍵是排序后的字符串&#xff0c;值是對應的原始字符串列表結果構建…

高防cdn如何緩存網頁靜態資源

為什么需要優化網頁靜態資源的緩存&#xff1f; 網頁靜態資源包括圖片、CSS、JavaScript等文件&#xff0c;它們通常體積大、訪問頻繁。在網頁訪問過程中&#xff0c;如果每次都從源服務器請求這些靜態資源&#xff0c;會導致網絡延遲和帶寬消耗。而優化網頁靜態資源的緩存&am…

使用Pandas進行缺失值處理和異常值檢測——實戰指南

目錄 一、缺失值處理 1.1 缺失值的識別 1.2 刪除缺失值 1.3 填充缺失值 二、異常值檢測 2.1 異常值的定義 2.2 常用檢測方法 IQR&#xff08;四分位數間距&#xff09;法 Z-score&#xff08;標準分數&#xff09;法 三、實戰案例&#xff1a;基因表達數據預處理 四…

B.30.01.1-Java并發編程及電商場景應用

摘要 本文深入探討了Java并發編程的核心概念及其在電商系統中的實際應用。從基礎并發機制到高級并發工具&#xff0c;結合電商業務場景中的典型問題&#xff0c;如高并發秒殺、庫存管理、訂單處理等&#xff0c;提供了實用的解決方案和最佳實踐。 1. Java并發編程基礎 1.1 并發…

怎樣避免游戲檢測到云手機?

以下是一些可能避免游戲檢測到云手機的方法&#xff1a;云手機可能會因網絡配置等因素出現一些異常網絡行為&#xff0c;如網絡延遲的規律性變化等&#xff0c;在使用云手機玩游戲時&#xff0c;盡量保持網絡行為的穩定性和自然性&#xff0c;避免短時間內頻繁切換網絡連接&…

文件上傳 --- uploadlabs靶場

目錄 1 前端和js校驗 抓包改包 2 . 2.1 .htaccess&#xff08;偽靜態&#xff09; 2.2 %00截斷 &#xff08;php5.2&#xff09; 2.3 user_init_ 2.4 3 圖片碼防御 4 競爭型漏洞 思路&#xff1a; 容易出現的問題: 1 前端和js校驗 關閉JS的代碼&#xff0c;上傳PHP…

漢化版本 k6 dashboard

目前官方提供的 dashboard 只有英文版本&#xff0c;國內使用不方便&#xff0c;因此 fork 了下官方倉庫&#xff0c;添加了漢化版本 https://github.com/kinghard7/xk6-dashboardhttps://github.com/kinghard7/xk6-dashboard安裝 xk6 構建程序&#xff1a;go install go.k6.i…