這篇文章主要介紹了PHP實現基於回溯法求解迷宮問題的方法,結合實例形式詳細分析了回溯法的原理、實現步驟與解決迷宮問題的相關操作技巧,需要的朋友可以參考下
本文實例講述了PHP實作基於回溯法求解迷宮問題的方法。分享給大家供大家參考,具體如下:
引言
#最近在leetcode上看了一些演算法題,有些看著很簡單的很常用的東西,竟然一下子想不出來怎麼求解,比如說:實現sqrt函數,求數組的排列。如果高數學的不好,這些看似簡單的問題,第一次碰到也會感覺很難求解,當然了,今天要說的是這樣一個問題,求解迷宮的所有解,這個問題的求解用到了回溯法的思想,不了解這個思想的話,很多稍微複雜點的問題都很難解了。
問題描述
這個問題是在實在瞎逛的時候碰到的,具體哪裡記不太清楚了。
1 1 1 1
0 1 0 1
#0 1 0 1
0 1 1 0 1
如何解決
解決這個問題的一個方案就是回溯法,先一起看看回溯法(百度百科)的定義: 回溯法(探索與回溯法)是一種選優搜尋法,又稱為試探法,依選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為“回溯點”。我的想法:
1. 將上面的迷宮進行座標化,左上角是(0,0),右下角是(3,3),其他點分散在座標系中2. 從(0,0)開始
3. 從給定的座標點開始,先向右搜索,是1的話繼續,是0的話向下搜索,搜索前記錄目前已經搜尋過的座標
4. 當座標等於(3,3)的時候就是一個回溯點了,這個時候也回傳
5. 只要不越界,重複第三步驟
<?php $nums = [ [1,1,1,1,1,1], [0,1,0,1,0,1], [0,1,0,1,0,1], [0,1,1,1,1,1] ]; function getRet($data, $x, $y, &$result=[], $record) { $snapshort = []; $xL = count($data) - 1; $yL = count($data[0]) - 1; if($x > $xL || $y > $yL) { //跑到迷宫不存在的空间了,这种事情绝对不能发生 return; } if($data[$x][$y] == "0") { //是0的话停止继续前进,退回上一状态 return; } elseif($data[$x][$y] == "1") { //是1的话,记录最新的坐标到当前已找到的路径中,继续向前搜索 //如果到达出口,记录答案并回溯 $snapshort = array_merge($record, [[$x, $y]]); if($x == $xL && $y == $yL) { $result[] = array_merge($record, [[$x, $y]]); return; } } else { return; } //向有搜索 //这里的$snapshort保存当前搜索位置的状态,等到下次回溯到这里的时候会用到 getRet($data, $x, ++$y, $result, $snapshort); //向下搜索 getRet($data, ++$x, --$y, $result, $snapshort); } //看个例子 $result = []; getRet($nums, 0, 0, $result, []); foreach ($result as $pos) { foreach ($pos as $xy) { echo "({$xy[0]},{$xy[1]}) => "; } echo "end\n"; }輸出結果
(0,0)=>(0,1)=>(0,2)=>(0,3)=>(0,4)=>(0,5)=>(1,5)=>(2,5)=>(3,5)=>end (0,0)=>(0,1)=>(0,2)=>(0,3)=>(1,3)=>(2,3)=>(3,3)=>(3,4)=>(3,5)=>end (0,0)=>(0,1)=>(1,1)=>(2,1)=>(3,1)=>(3,2)=>(3,3)=>(3,4)=>(3,5)=>end
以上是PHP使用回溯法解決迷宮問題詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!