PHP樹產生迷宮及A*自動尋路演算法

來源:互聯網
上載者:User

標籤:演算法   遍曆   

PHP樹產生迷宮及A*自動尋路演算法

迷宮演算法是採用樹的深度遍曆原理,這樣產生的迷宮相當的細,而且死胡同數量相對較少!
任意兩點之間都存在唯一的一條通路。
至於A*尋路演算法是最福士化的一全自動尋路演算法
完整代碼已上傳,http://download.csdn.net/detail/hello_katty/8885779 ,此處做些簡單解釋,還需要大家自己思考動手。廢話不多說,貼上帶代碼迷宮產生類:
/** 產生迷宮類 * @date 2015-07-10 * @edit http://www.lai18.com * @version 1 **/class Maze{    // Maze Create    private $_w;    private $_h;    private $_grids;    private $_walkHistory;    private $_walkHistory2;    private $_targetSteps;    // Construct    public function Maze() {        $this->_w = 6;        $this->_h = 6;        $this->_grids = array();    }    // 設定迷宮大小    public function set($width = 6, $height = 6) {        if ( $width > 0 ) $this->_w = $width;        if ( $height > 0 ) $this->_h = $height;        return $this;    }    // 取到迷宮    public function get() {        return $this->_grids;    }    // 產生迷宮    public function create() {        $this->_init();        return $this->_walk(rand(0, count($this->_grids) -1 ));    }    // 擷取死胡同點    public function block($n = 0, $rand = false) {        $l = count($this->_grids);        for( $i = 1; $i < $l; $i++ ) {            $v = $this->_grids[$i];            if ( $v == 1 || $v == 2 || $v == 4 || $v == 8 ) {                $return[] = $i;            }        }        // 隨機取點        if ( $rand ) shuffle($return);         if ( $n == 0 ) return $return;         if ( $n == 1 ) {            return array_pop($return);        } else {            return array_slice($return, 0, $n);        }    }    /**    產生迷宮的系列函數    */    private function _walk($startPos) {        $this->_walkHistory = array();        $this->_walkHistory2 = array();        $curPos = $startPos;        while ($this->_getNext0() != -1) {            $curPos = $this->_step($curPos);            if ( $curPos === false ) break;        }        return $this;    }    private function _getTargetSteps($curPos) {        $p = 0;        $a = array();        $p = $curPos - $this->_w;        if ($p > 0 && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {            array_push($a, $p);        } else {            array_push($a, -1);        }        $p = $curPos + 1;        if ($p % $this->_w != 0 && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {            array_push($a, $p);        } else {            array_push($a, -1);        }        $p = $curPos + $this->_w;        if ($p < count($this->_grids) && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {            array_push($a, $p);        } else {            array_push($a, -1);        }        $p = $curPos - 1;        if (($curPos % $this->_w) != 0 && $this->_grids[$p] === 0 && ! $this->_isRepeating($p)) {            array_push($a, $p);        } else {            array_push($a, -1);        }        return $a;    }    private function _noStep() {        $l = count($this->_targetSteps);        for ($i = 0; $i < $l; $i ++) {            if ($this->_targetSteps[$i] != -1) return false;        }        return true;    }    private function _step($curPos) {        $this->_targetSteps = $this->_getTargetSteps($curPos);        if ( $this->_noStep() ) {            if ( count($this->_walkHistory) > 0 ) {                $tmp = array_pop($this->_walkHistory);            } else {                return false;            }            array_push($this->_walkHistory2, $tmp);            return $this->_step($tmp);        }        $r = rand(0, 3);        while ( $this->_targetSteps[$r] == -1) {            $r = rand(0, 3);        }        $nextPos = $this->_targetSteps[$r];        $isCross = false;        if ( $this->_grids[$nextPos] != 0)            $isCross = true;        if ($r == 0) {            $this->_grids[$curPos] ^= 1;            $this->_grids[$nextPos] ^= 4;        } elseif ($r == 1) {            $this->_grids[$curPos] ^= 2;            $this->_grids[$nextPos] ^= 8;        } elseif ($r == 2) {            $this->_grids[$curPos] ^= 4;            $this->_grids[$nextPos] ^= 1;        } elseif ($r == 3) {            $this->_grids[$curPos] ^= 8;            $this->_grids[$nextPos] ^= 2;        }        array_push($this->_walkHistory, $curPos);        return $isCross ? false : $nextPos;    }    private function _isRepeating($p) {        $l = count($this->_walkHistory);        for ($i = 0; $i < $l; $i ++) {            if ($this->_walkHistory[$i] == $p) return true;        }        $l = count($this->_walkHistory2);        for ($i = 0; $i < $l; $i ++) {            if ($this->_walkHistory2[$i] == $p) return true;        }        return false;    }    private function _getNext0() {        $l = count($this->_grids);         for ($i = 0; $i <= $l; $i++ ) {            if ( $this->_grids[$i] == 0) return $i;        }        return -1;    }    private function _init() {        $this->_grids = array();        for ($y = 0; $y < $this->_h; $y ++) {            for ($x = 0; $x < $this->_w; $x ++) {                array_push($this->_grids, 0);            }        }        return $this;    }}

A*尋路演算法

/** 尋路演算法 * @date 2015-07-10 * @edit http://www.lai18.com * @version 1 **/class AStar{    // A-star    private $_open;    private $_closed;    private $_start;    private $_end;    private $_grids;    private $_w;    private $_h;    // Construct    public function AStar(){        $this->_w = null;        $this->_h = null;        $this->_grids = null;    }    public function set($width, $height, $grids) {        $this->_w = $width;        $this->_h = $height;        $this->_grids = $grids;        return $this;    }    // 迷宮中尋路    public function search($start = false, $end = false) {        return $this->_search($start, $end);    }    /**    自動尋路 - A-star 演算法       */    public function _search($start = false, $end = false) {        if ( $start !== false ) $this->_start = $start;        if ( $end !== false ) $this->_end = $end;        $_sh = $this->_getH($start);        $point[‘i‘] = $start;        $point[‘f‘] = $_sh;        $point[‘g‘] = 0;        $point[‘h‘] = $_sh;        $point[‘p‘] = null;        $this->_open[] = $point;        $this->_closed[$start] = $point;        while ( 0 < count($this->_open) ) {            $minf = false;            foreach( $this->_open as $key => $maxNode ) {                if ( $minf === false || $minf > $maxNode[‘f‘] ) {                    $minIndex = $key;                }            }            $nowNode = $this->_open[$minIndex];            unset($this->_open[$minIndex]);            if ( $nowNode[‘i‘] == $this->_end ) {                $tp = array();                while( $nowNode[‘p‘] !== null ) {                    array_unshift($tp, $nowNode[‘p‘]);                    $nowNode = $this->_closed[$nowNode[‘p‘]];                }                array_push($tp, $this->_end);                break;            }            $this->_setPoint($nowNode[‘i‘]);        }        $this->_closed = array();        $this->_open = array();        return $tp;    }    private function _setPoint($me) {        $point = $this->_grids[$me];        // 所有可選方向入隊列        if ( $point & 1 ) {            $next = $me - $this->_w;            $this->_checkPoint($me, $next);        }        if ( $point & 2 ) {            $next = $me + 1;            $this->_checkPoint($me, $next);        }        if ( $point & 4 ) {            $next = $me + $this->_w;            $this->_checkPoint($me, $next);        }        if ( $point & 8 ) {            $next = $me - 1;            $this->_checkPoint($me, $next);        }    }    private function _checkPoint($pNode, $next) {        if ( $this->_closed[$next] ) {            $_g = $this->_closed[$pNode][‘g‘] + $this->_getG($next);            if ( $_g < $check[‘g‘] ) {                $this->_closed[$next][‘g‘] = $_g;                $this->_closed[$next][‘f‘] = $this->_closed[$next][‘g‘] + $this->_closed[$next][‘h‘];                $this->_closed[$next][‘p‘] = $pNode;            }        } else {            $point[‘p‘] = $pNode;            $point[‘h‘] = $this->_getH($next);            $point[‘g‘] = $this->_getG($next);            $point[‘f‘] = $point[‘h‘] + $point[‘g‘];            $point[‘i‘] = $next;            $this->_open[] = $point;            $this->_closed[$next] = $point;        }    }    private function _getG($point) {        return abs($this->_start - $point);    }    private function _getH($point) {        return abs($this->_end - $point);    }}

延伸閱讀 《編程實用演算法實現整理》系列技術文章整理收藏 

1演算法導論:選擇排序的原理與實現

2一道PHP冒泡排序演算法筆試題

3WordPress的使用者密碼計算演算法

4PHP實現四種常用的排序演算法

5非常直觀的資料結構與演算法示範

6深入探討各種背包演算法問題

7圖解插入排序演算法

8圖解堆排序Heap Sort演算法

9約瑟夫環(Josephus)問題的C++演算法類比

10趣味演算法之兔子產子問題

11一些常見演算法的JavaScript實現

12趣味演算法之猴子吃桃問題

13平方根sqrt()函數的底層演算法效率

14二叉搜尋樹的一些相關演算法介紹

15歐幾裡德演算法(輾轉相處法)練手

16螞蟻爬木杆問題的演算法思路

17電腦編程中一些重要的演算法

18面試中常見的一些演算法問題

19JavaScript排序演算法之希爾排序

20JavaScript排序演算法之堆排序

21JavaScript排序演算法之歸併排序

22JavaScript排序演算法之選擇排序

23JavaScript排序演算法之快速排序

24JavaScript排序演算法之冒泡排序

25JavaScript排序演算法之插入排序

26合并排序演算法解說與例子

27醜數Ugly Number尋找演算法

28求大數階乘的演算法

29各排序演算法的C++實現與效能測試

30演算法導論中一個蒙提霍爾問題

31實現一個棧並擷取其最小元素

32親身體驗一下KMP演算法

33面試演算法題的快速思考方法

34矩陣逆時針旋轉的演算法

35Hash魔法:分布式雜湊演算法

36Hash魔法:一致性 hash 演算法

37字串逆序的各種實現演算法

38用遞迴實現的快速排序

39收集一些top軟體公司經典演算法面試題

40趣味演算法:猴子搬香蕉問題

41一些主流的個人化推薦演算法評析

42趣味演算法:生男生女的比例

43趣味演算法:老鼠試毒瓶問題

44使用PHP內建的DES演算法函數實現資料加密解密

45第九話:資料結構與演算法的關係

46第12話:什麼樣的演算法才是好演算法

47第11話:演算法的五個基本特徵

48第13話:演算法的效能分析

49第10話:什麼是演算法?

50第16話:演算法的空間複雜度

51第15話:演算法的最壞情況與平均情況

52第14話:如何計算演算法的時間複雜度

53順序棧的進棧操作

54順序棧:棧的順序儲存結構

55棧的定義與大概理解

56棧的抽象資料類型ADT

57鏈棧:棧的鏈式儲存結構

58鏈棧的進棧操作

59擷取順序棧的棧頂元素

60順序棧的出棧操作

61為什麼要使用棧這種資料結構

62鏈棧的置空操作與判斷鏈棧是否為空白

63遞迴,棧的重要應用之一

64棧是如何?遞迴的

65鏈棧的出棧操作

66鏈棧的初始化與遍曆

67漫談遞迴:遞迴的思想

68漫談遞迴:遞迴需要滿足的兩個條件

69漫談遞迴:字串迴文現象的遞迴判斷

70漫談遞迴:二分尋找演算法的遞迴實現

71漫談遞迴:遞迴的效率問題

72漫談遞迴:遞迴與迴圈

73漫談遞迴:迴圈與迭代是一回事嗎?

74漫談遞迴:從斐波那契開始瞭解尾遞迴

75漫談遞迴:尾遞迴與CPS

76漫談遞迴:補充一些Continuation的知識

77漫談遞迴:PHP裡的尾遞迴及其最佳化

78漫談遞迴:從彙編看尾遞迴的最佳化

79快速排序裡的學問:從猜數字開始

80快速排序裡的學問:再看看稱球問題

81快速排序裡的學問:資訊熵

82快速排序裡的學問:快速排序的過程

83快速排序裡的學問:霍爾與快速排序

84快速排序裡的學問:霍爾快排的實現

85快速排序裡的學問:樞紐元選擇與演算法效率

86快速排序裡的學問:隨機化快排

87Java程式員必須掌握的8大排序演算法

88RSA,DSA等加解密演算法介紹

89許可權項目總結(一)許可權設計


延伸閱讀

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

PHP樹產生迷宮及A*自動尋路演算法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.