記憶化搜尋路徑_Java實現
阿新 • • 發佈:2018-12-23
這是一個簡單的生存遊戲,你控制一個機器人從一個棋盤的起始點(0,0) 走到棋盤的終點(5,5) 。
規則如下:
1. 機器人一開始在棋盤的起始點並有起始點所標有的能量。2. 機器人只能向右或者向下走,並且每走一步消耗一單位能量。
3. 機器人不能在原地停留。
4. 當機器人選擇了一條可行路徑後,當他走到這條路徑的終點時,他將只有終點所標記的能量。
如map圖,機器人一開始在(0,0) 點,並擁有4 單位能量,灰色方塊表示他所能到達的點,如果他在這次路徑選擇中選擇的終點是(1,3)點,當他到達(1,3) 點時將擁有1 單位的能量,並開始下一次路徑選擇,直到到達(5,5) 點。我們的問題是機器人有多少種方式從起點走到終點。
當機器人走到(1,3)時,他只有兩種選擇:1.走(1,4),然後繼續向終點走。2.走(2,3),然後繼續向終點走。那麼也就是說,機器人在(1,3)到終點的走法,就是(1,4)到終點的走法加(2,3)到終點的走法,那麼(1,4)(2,3)到終點的走法有多少種呢?留給遞迴去完成,最終終點臨邊的點到終點只有一步。
當前點到終點的走法=其能到達所有的點到終點的走法的和
通過儲存每一個點到終點的走法,使已計算過的資料能讓後面的計算直接呼叫前面的結果使用,摒棄掉大量的重複計算,這就是記憶化搜尋。
public class 記憶化搜尋 { static int[][] map={{4,5,6,6,4,3},//初始化地圖 {2,2,3,1,7,2}, {1,1,4,6,2,7}, {5,8,4,3,9,5}, {7,6,6,2,1,5}, {3,1,1,3,7,2}}; static int[][] dp={{-1,-1,-1,-1,-1,-1},//初始化記憶表,全初始化為-1,終點初始化為1 {-1,-1,-1,-1,-1,-1},//表中存放的是當前位置到終點的走法數量 {-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1,-1}, {-1,-1,-1,-1,-1, 1}}; public static void main(String[] args) { System.out.println(dfs(0,0));//求地圖左上角到右下角終點的走法數量 } public static int dfs(int x,int y){ if(dp[x][y]>=0)//因為地圖被初始化都是-1,所以dp表中大於等於零的點,都說明已經計算過走法了 return dp[x][y];//直接return,使用之前計算過的結果,避免了大量的重複計算。 dp[x][y]=0;//計算之初,先假定當前點到終點走法為零,便於累和 /* * 下面兩層for迴圈遍歷所有當前點能夠到達的點,當前點到終點的走法數量=其所有子節點到終點的走法的和。 * 這是動態規劃思想,當前點到某一個子節點只有一種走法,那麼通過當前子節點為媒介到終點的走法就是子節點到終點的走法。 * 那麼當前點到終點的所有走法,就是其所有子節點到終點的走法的和! * 不必揪心於,其子節點到終點的走法,讓遞迴去完成,反正遞迴的盡頭是終點上下左右的點,到終點只有1種走法。 * */ for(int i=0;i<=map[x][y];i++) for(int j=0;j<=map[x][y]-i;j++) if(x+i>=0 && y+j>=0 && x+i<6 && y+j<6){//判斷地圖越界 dp[x][y]=dp[x][y]+dfs(x+i,y+j); //遞迴累和 } return dp[x][y]; } }