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加密解密的代码
Oct 09 PHP
php中使用array_filter()函数过滤空数组的实现代码
Aug 19 PHP
CentOS 6.3下安装PHP xcache扩展模块笔记
Sep 10 PHP
PHP实现手机号码中间四位用星号(*)隐藏的自定义函数分享
Sep 27 PHP
php简单生成随机数的方法
Jul 30 PHP
PHP去掉json字符串中的反斜杠\及去掉双引号前的反斜杠
Sep 30 PHP
详解WordPress中给链接添加查询字符串的方法
Dec 18 PHP
PHP中spl_autoload_register()函数用法实例详解
Jul 18 PHP
PHP判断用户是否已经登录(跳转到不同页面或者执行不同动作)
Sep 22 PHP
Yii框架实现记录日志到自定义文件的方法
May 23 PHP
实例讲解PHP页面静态化
Feb 05 PHP
laravel 5.5 关闭token的3种实现方式
Oct 24 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生成静态HTML速度快类库
2007/03/18 PHP
让PHP支持页面回退的两种方法
2008/01/10 PHP
PHP格式化MYSQL返回float类型的方法
2016/03/30 PHP
javascript Demo模态窗口
2009/12/06 Javascript
javascript中的new使用
2010/03/20 Javascript
jquery中dom操作和事件的实例学习 仿yahoo邮箱登录框的提示效果
2011/11/30 Javascript
JQuery操作tr和td内容的方法实例
2013/03/06 Javascript
解析JavaScript中delete操作符不能删除的对象
2013/12/03 Javascript
Javascript 浮点运算精度问题分析与解决
2014/03/26 Javascript
js 调用百度地图api并在地图上进行打点添加标注
2014/05/13 Javascript
做web开发 先学JavaScript
2014/12/12 Javascript
node.js中的http.createClient方法使用说明
2014/12/15 Javascript
在父页面得到zTree已选中的节点的方法
2015/02/12 Javascript
JavaScript三元运算符的多种使用技巧
2015/04/16 Javascript
jquery实现华丽的可折角广告代码
2015/09/02 Javascript
javascript中select下拉框的用法总结
2016/01/07 Javascript
JavaScript prototype属性详解
2016/10/25 Javascript
分享ES6的7个实用技巧
2018/01/18 Javascript
AngularJS模态框模板ngDialog的使用详解
2018/05/11 Javascript
JavaScript设计模式之观察者模式(发布订阅模式)原理与实现方法示例
2018/07/27 Javascript
简述vue-cli中chainWebpack的使用方法
2019/07/30 Javascript
基于ajax及jQuery实现局部刷新过程解析
2020/09/12 jQuery
布同 统计英文单词的个数的python代码
2011/03/13 Python
Python datetime时间格式化去掉前导0
2014/07/31 Python
django中forms组件的使用与注意
2019/07/08 Python
详解python列表(list)的使用技巧及高级操作
2019/08/15 Python
pymysql 开启调试模式的实现
2019/09/24 Python
Alpine安装Python3依赖出现的问题及解决方法
2020/12/25 Python
Hotels.com英国:全球领先的酒店住宿提供商
2019/01/24 全球购物
Paradox London官方网站:英国新娘鞋婚礼鞋品牌
2019/08/29 全球购物
介绍一下游标
2012/01/10 面试题
如何执行一个shell程序
2012/11/23 面试题
财务部岗位职责
2015/02/03 职场文书
2016五四青年节活动总结范文
2016/04/06 职场文书
个人工作总结怎么写?
2019/04/09 职场文书
Python实现照片卡通化
2021/12/06 Python