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自定义函数返回多个值
Nov 26 PHP
PHP截取汉字乱码问题解决方法mb_substr函数的应用
Mar 30 PHP
php cli换行示例
Apr 22 PHP
ThinkPHP模板输出display用法分析
Nov 26 PHP
WordPres对前端页面调试时的两个PHP函数使用小技巧
Dec 22 PHP
PHP数据库操作Helper类完整实例
May 11 PHP
PHP入门教程之字符串处理技巧总结(转换,过滤,解析,查找,截取,替换等)
Sep 11 PHP
Laravel中任务调度console使用方法小结
May 07 PHP
PHP7扩展开发教程之Hello World实现方法示例
Aug 03 PHP
详解PHP中的外观模式facade pattern
Feb 05 PHP
PHP Swoole异步MySQL客户端实现方法示例
Oct 24 PHP
浅析PHP中json_encode与json_decode的区别
Jul 15 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实现的仿阿里巴巴实现同类产品翻页
2009/12/11 PHP
PHPCMS的使用小结
2010/09/20 PHP
PHP Static延迟静态绑定用法分析
2016/03/16 PHP
PHP常用工具函数小结【移除XSS攻击、UTF8与GBK编码转换等】
2019/04/27 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
2019/11/24 PHP
轻轻松松学习JavaScript
2007/02/25 Javascript
利用JQuery动画制作滑动菜单项效果实现步骤及代码
2013/02/07 Javascript
iframe窗口高度自适应的实现方法
2014/01/08 Javascript
js的hasownproperty使用示例
2014/03/02 Javascript
Javascript中的delete操作符详细介绍
2014/06/06 Javascript
基于jQuery实现返回顶部实例代码
2016/01/01 Javascript
AngularJS 2.0入门权威指南
2016/10/08 Javascript
nodejs 实现钉钉ISV接入的加密解密方法
2017/01/16 NodeJs
详解微信小程序调起键盘性能优化
2018/07/24 Javascript
layer弹出层 iframe层去掉滚动条的实例代码
2018/08/17 Javascript
Vue实现Layui的集成方法步骤
2020/04/10 Javascript
微信小程序实现翻牌抽奖动画
2020/09/21 Javascript
利用TensorFlow训练简单的二分类神经网络模型的方法
2018/03/05 Python
Python中关键字global和nonlocal的区别详解
2018/09/03 Python
解决Python安装时报缺少DLL问题【两种解决方法】
2019/07/15 Python
详解KMP算法以及python如何实现
2020/09/18 Python
CSS3 calc()会计算属性详解
2018/02/27 HTML / CSS
不开辟用于交换数据的临时空间,如何完成字符串的逆序
2012/12/02 面试题
应届生服务员求职信
2013/10/31 职场文书
写给保洁员表扬信
2014/01/08 职场文书
幼教毕业生自我鉴定
2014/01/12 职场文书
干部现实表现材料
2014/02/13 职场文书
幼儿园毕业园长感言
2014/02/24 职场文书
廉政教育的心得体会
2014/09/01 职场文书
“四风”查摆问题自我剖析材料
2014/09/27 职场文书
写给父母的感谢信
2015/01/22 职场文书
鲁滨孙漂流记读书笔记
2015/06/30 职场文书
2015年入党积极分子培养考察意见
2015/08/12 职场文书
利用ajax+php实现商品价格计算
2021/03/31 PHP
Netty结合Protobuf进行编解码的方法
2021/06/26 Java/Android
Win11 Build 22000.51版本文件资源管理器“命令栏”和上下文菜单有什么新变化?
2021/11/21 数码科技