7
10

More than 5 years have passed since last update.

PHPで深さ優先探索を用いて迷路問題を解く

Posted at

PHPで深さ優先探索を用いて迷路問題を解く

問題

S地点からG地点にたどり着くかどうか検証せよ
但し、0は進め、Xは進めないとする。
たどりついた場合はtrueを失敗した場合はfalseを返せ
迷路はCSVファイルから読み取る

コード

maze.csv
0,0,S,0,X,0
0,G,X,0,0,0
X,0,0,X,0,0
X,X,0,0,0,X
Maze.php
/*
迷路クラス
 深さ探索法で迷路を解く
 */

Class Maze{
    public $maze;    //迷路の配列
    public $reached; //探索した地点を記録する配列
    public $isGoal;  //ゴールできたらtrue
    const MAX_W = 6; //x軸方向の幅
    const MAX_H = 4; //y軸方向の幅

    public function __construct($filePath) {
        $this->maze    = self::createMazeFromCSV($filePath);
        $this->reached = array();
        $this->isGoal  = false;
    }

    //迷路のcsvファイルを読み取って、迷路の配列を作成する
    public function createMazeFromCSV($filePath) {
        $maze = array();

        $data  = file_get_contents($filePath);
        $lines = explode("\r\n", $data);
        foreach ($lines as $line) {
            $maze[] = explode(",",$line);
        }
        return $maze;
    }

    public function search($row, $col) {
        //Goalしていたらスキップする。
        if ($this->isGoal) {
            return true;
        }
        //迷路の外側か壁の場合は何もしない
        if ($row < 0 || self::MAX_H <= $row || $col < 0 || self::MAX_W <= $col || $this->maze[$row][$col] == 'X') {
            return false;
        }
        //既に到達している場合は何もしない
        if (isset($this->reached[$row][$col]) && $this->reached[$row][$col] == true) {
            return false ;
        }

        //今いる地点にチェックしたことを記録する
        $this->reached[$row][$col] = true;

        if ($this->maze[$row][$col] == 'G') {
            //exit('ゴール');
            $this->isGoal = true;
            //echo'<pre>';
            //var_dump($this->reached);
            //echo '</pre>';
            return true;
        }

        self::search($row, $col + 1); //右に進む
        //var_dump('実行した?');
        self::search($row, $col - 1); //左に進む
        //var_dump('実行した?');
         self::search($row + 1, $col); //上に進む
        //var_dump('実行した?');
        self::search($row - 1, $col); //下に進む

        //最終結果
        if ($this->isGoal) {
            return true;
        } else {
            return false;
        }
    }
}
mazeTest.php
/* 
深さ優先探索で迷路を解く
問題はS地点からG地点にたどり着くかどうか検証せよ
但し、0は進め、Xは進めないとする。
たどりついた場合はtrueを失敗した場合はfalseを返せ
 */

require_once './part/Maze.php';

$maze = new Maze('../file/maze.csv');
//S地点を引数にセットする
var_dump($maze->search(0, 2));


参考サイト (チョー分かりやすい)

参考書籍

最強最速アルゴリズマー養成講座 プログラミングコンテストTopCoder攻略ガイド

7
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10