220 likes | 389 Views
MOI 培訓班提高組 搜索. 澳門電腦學會. 搜索樹. 初始狀態. 搜索路徑. 可能性結點. 目標結點. 深度優先搜索. 先完全搜索其中一種可能,再搜索其他 找到的答案未必一定是最優解 相對節省記憶體的使用 通過 Backtrack 及遞歸完成. 深度優先搜索算法. DeepSearch (Stage) IF Stage = EndStage THEN FindOneAnswer ELSE FOREACH child of Stage DO BEGIN Mark child as searched
E N D
MOI 培訓班提高組搜索 澳門電腦學會
搜索樹 初始狀態 搜索路徑 可能性結點 目標結點
深度優先搜索 • 先完全搜索其中一種可能,再搜索其他 • 找到的答案未必一定是最優解 • 相對節省記憶體的使用 • 通過 Backtrack 及遞歸完成
深度優先搜索算法 DeepSearch (Stage) IF Stage = EndStage THEN FindOneAnswer ELSE FOREACH child of Stage DOBEGIN Mark child as searched DeepSearch (child) Unmark child END END
八后問題 • 在一國際象棋棋盤上放入八隻皇后,使其相互之間不能攻擊
八后問題算法 Queen (row) IF row > 8 THEN PrintBoard; ELSE FOR i:=1 TO 8 DO IF Safe(row, i) THENBEGIN Board[row,i] := Marked; Queen(row+1); Board[row,i] := UnMarked; END
走迷宮 Maze (r,c) IF Destination(r,c) = TRUE THEN Done ELSE Map[r,c] := Visiting; FOR i:=1 TO 4 DO IF Map[r+dirr[i],c+dirc[i]] = FreeCell THEN Maze (r+dirr[i], c+dirc[i])
dirr := (0, 0, 1, -1); dirc := (1, -1, 0, 0);
廣度優先搜索 • 前於某一個結點,先完全搜索其所有可能的一下代 • 一代一代地搜 • 找到的必是最優解 • 通過 Queue 來完成 • 可能出現 Queue 空間不足的情況
廣度優先搜索算法概述 LevelSearch; PutInQueue (Stage); Finish := FALSE; WHILENOT QueueEmpty AND NOT Finish DOBEGIN RemoveFromQueue(Stage); SetStageOf(Stage, Visited); IF IsTargetStage(Stage) THEN Finish := TRUE ELSEFOREACH Child of Stage DO BEGIN IF StageOf(Child) = NotVisited THENBEGIN SetStageOf(Child, InQueue); PutInQueue(Child); END; END; END;
走迷宮 Maze PutInQeueu(StartRow, StartCol); Map[StartRow, StartCol] := 1; Finish := FALSE; WHILENOT QueueEmpty ANDNOT Finish DOBEGIN GetFromQueue(r, c); IF r=EndRow AND c=EndCol THEN Finish := TRUE; ELSE FOR i:=1 TO 4 DOBEGIN nr := r + dirr[i]; nc := c + dirc[i]; IF Map[nr,nc] = 0 THENBEGIN PutInQueue(nr, nc); Map[nr, nc] := Map[r,c] + 1; END; END END
類似問題 • 跳馬問題: • 在一個國際象棋的棋盤上的左上角放了一隻馬,問這隻馬最少要走多少步才走到棋盤的右下角? • 雙馬跳問題: • 在一個國際象棋的棋盤上的左上角及右下角分別放兩隻馬,若每一步進行時,兩隻馬都是同時走的話,且每隻馬可以選擇停留不動,問這兩隻馬最少走多少步才會跳進同一格中?這一個的位置是在哪裏?
等價搜索 • 是廣度搜索的一種 • Queue不再單是 FIFO,而是 “優先隊”,即先排優先次序,再排先後次序 • 要決定一個優先值函數
“優先隊” • “優先隊”通常通過一種名為 Heap 的數據結構來實行 • Heap 是一個滿二叉樹,除了最底一層外,它的每層都是滿的 • Heap 通常是一個一維陣列來表現 • Heap 的要求是 H[i] <= H[2*i] 及 H[i] <= H[2*i+1](若 2*i 或 2*i+1 存在的話) • Heap 值最小的一個是 H[1] • 這裡我們假設數值越小越優先
C G F B E D I H A J A B C D E F G H I J 0 1 2 3 4 5 6 7 8 9 10 11 12 13 Heap 的矩陣表示方式 左子樹位置 2i 右子樹位置 (2i+1) 父結點位置 i/2
24 16 68 19 21 31 24 21 19 68 16 26 13 32 65 13 65 32 26 31 插入 insert14 原插入的位置
16 31 21 68 16 14 19 24 31 21 19 68 24 32 13 26 65 13 26 65 32 最後真正插入的位置
16 68 19 21 31 14 16 14 68 19 21 19 19 26 32 65 32 26 65 13 31 移除(最頂的一個) Delete 13 移除外空出來的位置 理想的空出位置
16 68 21 19 16 14 19 19 21 19 14 68 65 32 32 65 26 26 31 31 將子樹中較細值的一個向上移
16 14 68 21 19 16 19 68 19 21 19 14 26 65 31 32 32 65 26 31 31
剪枝 • 搜索中的剪枝就是將一些沒有可能(或可能性較低)的子樹除去不理 • 剪枝方法: • 極值剪枝 • 函數剪枝
廣度優先搜索算法加剪枝 LevelSearch; PutInQueue (Stage); Finish := FALSE; WHILENOT QueueEmpty DOBEGIN RemoveFromQueue(Stage); SetStageOf(Stage, Visited); IF IsTargetStage(Stage) THEN Finish := TRUE ELSEFOREACH Child of Stage DO BEGIN SetStageOf(Stage, Visited); IF StageOf(Child) = NotVisited THENBEGIN IF PossibleValue(Child) > PreSetValue THEN SetStageOf(Child, InQueue); PutInQueue(Child); END; END; END;