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 相关文章推荐
apache+mysql+php+ssl服务器之完全安装攻略
Sep 05 PHP
php下实现在指定目录搜索指定类型文件的函数
Oct 03 PHP
php UTF-8、Unicode和BOM问题
May 18 PHP
使用PHP获取当前url路径的函数以及服务器变量
Jun 29 PHP
linux下编译安装memcached服务
Aug 03 PHP
学习php设计模式 php实现工厂模式(factory)
Dec 07 PHP
分享php邮件管理器源码
Jan 06 PHP
php编程每天必学之表单验证
Mar 01 PHP
php版微信支付api.mch.weixin.qq.com域名解析慢原因与解决方法
Oct 12 PHP
thinkphp分页集成实例
Jul 24 PHP
laravel excel 上传文件保存到本地服务器功能
Nov 14 PHP
PHP大文件分割分片上传实现代码
Dec 09 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
回首过去10年中最搞笑的10部动漫,哪一部让你节操尽碎?
2020/03/03 日漫
农民C键的运用技巧
2020/03/04 星际争霸
php环境配置之CGI、FastCGI、PHP-CGI、PHP-FPM、Spawn-FCGI比较?
2011/10/17 PHP
php smarty模板引擎的6个小技巧
2014/04/24 PHP
对比PHP对MySQL的缓冲查询和无缓冲查询
2016/07/01 PHP
[原创]php常用字符串输出方法分析(echo,print,printf及sprintf)
2016/07/09 PHP
thinkPHP模板中for循环与switch语句用法示例
2016/11/30 PHP
yii2中关于加密解密的那些事儿
2018/06/12 PHP
FireFox JavaScript全局Event对象
2009/06/14 Javascript
深入理解JavaScript系列(7) S.O.L.I.D五大原则之开闭原则OCP
2012/01/15 Javascript
jquery bind(click)传参让列表中每行绑定一个事件
2014/08/06 Javascript
javascript上下方向键控制表格行选中并高亮显示的方法
2015/02/13 Javascript
jQuery实现点击任意位置弹出层外关闭弹出层效果
2016/10/19 Javascript
基于javascript实现的快速排序
2016/12/02 Javascript
Canvas实现动态的雪花效果
2017/02/13 Javascript
微信小程序中使用ECharts 异步加载数据实现图表功能
2018/07/13 Javascript
微信小程序实现天气预报功能
2018/07/18 Javascript
layDate日期控件使用方法详解
2018/11/15 Javascript
用WebStorm进行Angularjs 2开发(环境篇:Windows 10,Angular-cli方式)
2018/12/05 Javascript
在vue中使用console.log无效的解决
2020/08/09 Javascript
JavaScript 如何计算文本的行数的实现
2020/09/14 Javascript
python基础_文件操作实现全文或单行替换的方法
2017/09/04 Python
不同版本中Python matplotlib.pyplot.draw()界面绘制异常问题的解决
2017/09/24 Python
Python for循环与range函数的使用详解
2019/03/23 Python
Python3.5 Pandas模块缺失值处理和层次索引实例详解
2019/04/23 Python
python 实现Requests发送带cookies的请求
2021/02/08 Python
AmazeUI 导航条的实现示例
2020/08/14 HTML / CSS
如果一个类实现了多个接口但是这些接口有相同的方法名将会怎样
2013/06/16 面试题
村长贪污检举信
2014/04/04 职场文书
简洁的英文求职信范文
2014/05/03 职场文书
节水口号标语
2014/06/19 职场文书
2014年党风廉政工作总结
2014/12/03 职场文书
世界气象日活动总结
2015/02/27 职场文书
Python如何识别银行卡卡号?
2021/06/10 Python
Windows Server 2012 R2 磁盘分区教程
2022/04/29 Servers
python数字图像处理:图像简单滤波
2022/06/28 Python