PHP实现基于回溯法求解迷宫问题的方法详解


Posted in PHP onAugust 17, 2017

本文实例讲述了PHP实现基于回溯法求解迷宫问题的方法。分享给大家供大家参考,具体如下:

引言

最近在leetcode上看了些算法题,有些看着很简单的很常用的东西,竟然一下子想不出来怎么求解,比如说:实现sqrt函数,求数组的排列。如果高数学的不好,这些看似简单的问题,第一次碰到也会感觉很难求解,当然了,今天要说的是这样一个问题,求解迷宫的所有解,这个问题的求解用到了回溯法的思想,不了解这个思想的话,很多稍微复杂点的问题都很难解了。

问题描述

这个问题是在实在瞎逛的时候碰到的,具体哪里记不太清了。

1   1   1   1
0   1   0   1
0   1   0   1
0   1   1   1

上面是一个迷宫,左上角是入口,右下角是出口,小萌(对,你没看错,是长了草的小明)从入口进入,从出口逃出(1个小时逃不出会被X怪物吃掉),其中1表示可以通行,0表示不能通行,只能向右和向下两个方向走,求出所有的小萌可能逃生的路线。

这个问题看似挺简单,一下就可以看到答案,但是将思想翻译为代码却不知道从何入手了。

如何解决

解决这个问题的一种方案就是回溯法,先一起看看回溯法(百度百科)的定义:

回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

我的思路:

1. 对上面的迷宫进行坐标化,左上角是(0,0),右下角是(3,3),其他点分散在坐标系中
2. 从(0,0)开始
3. 从给定的坐标点开始,先向右搜索,是1的话继续,是0的话向下搜索,搜索前记录当前已经搜索过的坐标
4. 当坐标等于(3,3)的时候就是一个回溯点了,这个时候也返回
5. 只要不越界,重复第三步骤

看看我的PHP实现:

<?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 相关文章推荐
php面向对象全攻略 (五) 封装性
Sep 30 PHP
php后台程序与Javascript的两种交互方式
Oct 25 PHP
php读取图片内容并输出到浏览器的实现代码
Aug 08 PHP
在PHP中使用redis
Nov 04 PHP
PHP中date与gmdate的区别及默认时区设置
May 12 PHP
分享下php5类中三种数据类型的区别
Jan 26 PHP
PHP实现算式验证码和汉字验证码实例
Mar 09 PHP
PHP函数checkdnsrr用法详解(Windows平台用法)
Mar 21 PHP
浅析Yii2 GridView实现下拉搜索教程
Apr 22 PHP
用PHP写的一个冒泡排序法的函数简单实例
May 26 PHP
php strftime函数获取日期时间(switch用法)
May 16 PHP
laravel框架模型中非静态方法也能静态调用的原理分析
Nov 23 PHP
PHP基于Closure类创建匿名函数的方法详解
Aug 17 #PHP
PHP编译configure时常见错误的总结
Aug 17 #PHP
基于PHP常用文件函数和目录函数整理
Aug 17 #PHP
PHP实现的堆排序算法详解
Aug 17 #PHP
基于php编程规范(详解)
Aug 17 #PHP
PHP数据库操作四:mongodb用法分析
Aug 16 #PHP
PHP Laravel 上传图片、文件等类封装
Aug 16 #PHP
You might like
PHP+javascript模拟Matrix画面
2006/10/09 PHP
PHP用GD库生成高质量的缩略图片
2011/03/09 PHP
php按单词截取字符串的方法
2015/04/07 PHP
PHP中preg_match正则匹配中的/u、/i、/s含义
2015/04/17 PHP
PHP技术开发微信公众平台
2015/07/22 PHP
javascript call方法使用说明
2010/01/11 Javascript
菜鸟javascript基础资料整理3 正则
2010/12/06 Javascript
jquery移动点击的项目到列表最顶端的方法
2015/06/24 Javascript
JS如何判断是否为ie浏览器的方法(包括IE10、IE11在内)
2015/12/13 Javascript
Windows 系统下设置Nodejs NPM全局路径
2016/04/26 NodeJs
全面解析JavaScript中的valueOf与toString方法(推荐)
2016/06/14 Javascript
vue 中自定义指令改变data中的值
2017/06/02 Javascript
利用chrome浏览器进行js调试并找出元素绑定的点击事件详解
2021/01/30 Javascript
vuejs2.0运用原生js实现简单拖拽元素功能
2020/08/21 Javascript
vue回到顶部监听滚动事件详解
2019/08/02 Javascript
vue2.x 对象劫持的原理实现
2020/04/19 Javascript
element-ui和vue表单(对话框)验证提示语(残留)清除操作
2020/09/11 Javascript
js canvas实现五子棋小游戏
2021/01/22 Javascript
[27:02]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS LGD第三场
2014/05/24 DOTA
python爬虫爬取快手视频多线程下载功能
2018/02/28 Python
python的常用模块之collections模块详解
2018/12/06 Python
python引用(import)某个模块提示没找到对应模块的解决方法
2019/01/19 Python
python实现删除列表中某个元素的3种方法
2020/01/15 Python
Win10里python3创建虚拟环境的步骤
2020/01/31 Python
Tensorflow之MNIST CNN实现并保存、加载模型
2020/06/17 Python
python help函数实例用法
2020/12/06 Python
python快速安装OpenCV的步骤记录
2021/02/22 Python
香港迪士尼乐园酒店预订:Hong Kong Disneyland Hotels
2017/05/02 全球购物
化学工程专业求职信
2014/08/10 职场文书
工作时间擅自离岗检讨书
2014/10/24 职场文书
2014年学校办公室工作总结
2014/12/19 职场文书
常务副总经理岗位职责
2015/02/02 职场文书
反邪教警示教育活动总结
2015/05/09 职场文书
暑期辅导班宣传单
2015/07/14 职场文书
小区物业管理2015年度工作总结
2015/10/22 职场文书
MySQL分库分表详情
2021/09/25 MySQL