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 采集心得技巧
May 15 PHP
PHP字符串 ==比较运算符的副作用
Oct 21 PHP
php模拟ping命令(php exec函数的使用方法)
Oct 25 PHP
ThinkPHP中RBAC类的四种用法分析
Nov 24 PHP
php实现Mongodb自定义方式生成自增ID的方法
Mar 23 PHP
php实现从上传文件创建缩略图的方法
Apr 02 PHP
php利用事务处理转账问题
Apr 22 PHP
PHP实现事件机制实例分析
Jun 26 PHP
PHP中使用curl伪造IP的简单方法
Aug 07 PHP
Yii2中hasOne、hasMany及多对多关联查询的用法详解
Feb 15 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
Nov 14 PHP
laravel实现前后台路由分离的方法
Oct 13 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
回答PHPCHINA上的几个问题:URL映射
2007/02/14 PHP
ThinkPHP3.1数据CURD操作快速入门
2014/06/19 PHP
PHP高手需要要掌握的知识点
2014/08/21 PHP
PHP中is_dir()函数使用指南
2015/05/08 PHP
浅析php-fpm静态和动态执行方式的比较
2016/11/09 PHP
PHP合并两个或多个数组的方法
2019/01/20 PHP
JS 文件传参及处理技巧分析
2010/05/13 Javascript
jquery高效反选具体实现
2013/05/05 Javascript
jQuery使用andSelf()来包含之前的选择集
2014/05/19 Javascript
Flexigrid在IE下不显示数据的有效处理方法
2014/09/04 Javascript
JavaScript学习笔记之定时器
2015/01/22 Javascript
Javascript中replace()小结
2015/09/30 Javascript
基于javascript实现漂亮的页面过渡动画效果附源码下载
2015/10/26 Javascript
node.js require() 源码解读
2015/12/13 Javascript
Vuejs第十一篇组件之slot内容分发实例详解
2016/09/09 Javascript
原生Javascript和jQuery做轮播图简单例子
2016/10/11 Javascript
jQuery命名空间与闭包用法示例
2017/01/12 Javascript
深入探究node之Transform
2017/07/20 Javascript
vue中使用refs定位dom出现undefined的解决方法
2017/12/21 Javascript
浅谈在react中如何实现扫码枪输入
2018/07/04 Javascript
vue中,在本地缓存中读写数据的方法
2018/09/21 Javascript
解决vue加scoped后就无法修改vant的UI组件的样式问题
2020/09/07 Javascript
[08:38]DOTA2-DPC中国联赛 正赛 VG vs Elephant 选手采访
2021/03/11 DOTA
python中的实例方法、静态方法、类方法、类变量和实例变量浅析
2014/04/26 Python
python实现从字符串中找出字符1的位置以及个数的方法
2014/08/25 Python
python实现颜色空间转换程序(Tkinter)
2015/12/31 Python
浅谈python中的getattr函数 hasattr函数
2016/06/14 Python
python递归下载文件夹下所有文件
2019/08/31 Python
tensorflow入门:TFRecordDataset变长数据的batch读取详解
2020/01/20 Python
Python爬虫获取op.gg英雄联盟英雄对位胜率的源码
2021/01/29 Python
会计系中文个人求职信
2013/12/24 职场文书
工程班组长岗位职责
2013/12/30 职场文书
批评与自我批评总结
2014/10/17 职场文书
大学辅导员述职报告
2015/01/10 职场文书
详解Java ES多节点任务的高效分发与收集实现
2021/06/30 Java/Android
Spring JPA 增加字段执行异常问题及解决
2022/06/10 Java/Android