当前位置: 首页 > news >正文

DFS中的奇偶剪枝学习笔记

奇偶剪枝学习笔记

描述

编辑

现假设起点为(sx,sy),终点为(ex,ey),给定t步恰好走到终点,
s
    
|
    
|
    
|
    
+
e
如图所示(“|”竖走,“—”横走,“+”转弯),易证abs(ex-sx)+abs(ey-sy)为此问题类中任意情况下,起点到终点的最短步数,记做step,此处step1=8;
s
 
 
+
 
|
+
   
|
    
+
e
如图,为一般情况下非 最短路径的任意走法举例,step2=14;
step2-step1=6,偏移路径为6,偶数(易证);

结论

编辑
推广之,若 t-[abs(ex-sx)+abs(ey-sy)] 结果为非偶数(奇数),则无法在t步恰好到达;
返回,false;
反之亦反。

原理补充

编辑
鉴于很多同学对奇偶剪枝根本原理的兴趣,所以hj决定再补充一下本词条。
还是以这个为例子吧,现在我把矩阵填满 0 和 1 [1]  
0
1
0
1
0
1
0
1
0
1
0
1
010
1
0101
0
1
0
1
0
我们现假设从 0 开始走,则不难证明,
从任意 0 走到任意 1 始终是奇数步;
从任意 0 走到任意 0 始终是偶数步;
引用描述里的“例子”, s 到 e 的最短步数为 t (当然你也可以理解成此时到终点刚好剩余 t 步等等)。
则,我们从 s 到 e 的步数之和(或者说总距离)总可以表示成 sum= t + extra ( extra>=0 ),其中 extra 表示额外的步数。 [2]  
比如“例子”里面的,做例1吧
s
 
 
+
 
|
+
   
|
    
+
e
此时 t=8,sum=14,所以我们容易得到 extra=6。也就是说按照这个走法,需要在最短的步数上再走额外的 6 步(先不用太在意这些偏移是在什么地方产生的)。
在来一个例2吧,
s
 
 
+
 
|
+
   
|
 +e
+
  
此时,t=7,sum=15,所以我们也容易得到 extra=8。
根据理科生的天性,由这两个一般性的例子,我们很容易嗅察到 extra 都为偶数。先带着疑惑,
再来看我给的 0 、1 矩阵。
0
1
0
1
0
1
0
1
0
1
0
1
010
1
0101
0
1
0
1
0
设左上角坐标为(1,1),右下角坐标为(5,5).
那么我们给的例1,
起点 s 的坐标为(1,1),此点为“0”;
终点 e 为(5,5),此点为“0”。
所以t=8,为偶数。
现在我们再倒过来看,从终点(也就是 e )出发,把最短步数 t=8 耗费掉,不妨这样走,
s
   +
   
+
   | 
  + 
  
e
如图所示从 e (5,5)耗费 8 步走到了(1,5)点。
因为是从 0 走偶数步,所以走到的坐标也一定是 0 ,就像这里的(1,5)点是 0 一样。
这是一个递归的过程,首先如果从0开始,目的地也是0,那末其中的最短距离t必然是个偶数,可其中有可能有障碍物或需要绕弯的情况,那末我们就现将最短距离t用于绕弯,从开始的0,走t步不管怎么走都只能到0,而这个0到终点0的最短路径t也必然是偶数,一直递归下去,直到你绕够了到达终点,这中间你额外的步数都是偶数。
注意到,(1,5)点和起点 s (1,1)都是 0,也就是说,这个 extra 必然是偶数!
再看例2,同样从终点 e 开始耗费 t=7 步,
则所到的点一定是 0 (不管她在哪里),再从这个点回到起点 s ,所用的 extra 也必然是个偶数!
所以无论如何,sum= t + extra ( extra>=0 ) 中的 extra 都是一个偶数
那么我们就可以用公式 t-[abs(ex-sx)+abs(ey-sy)] 计算出extra是否为偶数来判断当前点能否恰好在这么多步到达终点了。
有的同学可能会说以 1 为 起点呢。。其实是一样的啦,自己去捣鼓吧。
核心代码:
ans=t-time-abs(dx-x)-abs(dy-y); 
if(ans<0||ans&1) return;

说了这么多,再总结一下吧!

什么是奇偶剪枝?

把矩阵看成如下形式:
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
从为 0 的格子走一步,必然走向为 1 的格子 。
从为 1 的格子走一步,必然走向为 0 的格子 。
即:
从 0 走向 1 必然是奇数步,从 0 走向 0 必然是偶数步。

所以当遇到从 0 走向 0 但是要求时间是奇数的或者 从 1 走向 0 但是要求时间是偶数的,都可以直接判断不可达!

比如有一地图:

S...
....
....
....
...D

要求从S点到达D点,此时,从S到D的最短距离为s = abs ( dx - sx ) + abs ( dy - sy )。

如果地图中出现了不能经过的障碍物:

S..X
XX.X
...X
.XXX
...D

此时的最短距离s' = s + 4,为了绕开障碍,不管偏移几个点,偏移的距离都是最短距离s加上一个偶数距离。

就如同上面说的矩阵,要求你从0走到0,无论你怎么绕,永远都是最短距离(偶数步)加上某个偶数步;要求你从1走到0,永远只能是最短距离(奇数步)加上某个偶数步。

这里我来讲一下搜索中要用到的奇偶剪枝的原理:


 

看张图,没障碍物#时,S到E的最短路长为6,但是当有障碍物时,就要绕行了

看这张图,黑色为最短路径,当他绕行(红色加蓝色部分)时,其中蓝色部分其实还是最短路径部分平移来的,所以多走的步数也就是红色部分

对于红色部分我们可以分为两部分,一部分是远离最短路径的步数,另一部分是回到最短路径的部分,他们一定是对称的,所以多走的步数一定是偶数!!!


所以要是问走x步能否到达e,就算出最短路径长y,如果x-y是偶数就能到达,否则不能到达!


相关文章:

  • ubuntu 下 安装 sublime Text3
  • 关于伪造IP地址的疑问
  • COCOS2D-X 3.0在MAC下创建新IOS项目:
  • Ubuntu 14.04下单节点Ceph安装(by quqi99)
  • yield
  • StringBuffer类常用方法
  • Vim技能修炼教程(17) - 编译自己的Vim
  • 12306 外包给阿里巴巴、IBM 等大企业做是否可行?
  • HTTP中GET与POST的真正区别
  • “学”、“习”二合一:监督学习——支持向量机(SVM)入门
  • Halcon学习之五:有关图像的定义域的函数
  • 教你一招让网页用上漂亮的11PX中文字体
  • Xamarin XAML语言教程模板视图TemplatedView(二)
  • Mozilla “Common Voice” 开源语音识别项目
  • 物联网未来充满活力,但业界仍在探索中
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • Android系统模拟器绘制实现概述
  • Bytom交易说明(账户管理模式)
  • Cookie 在前端中的实践
  • Js基础知识(一) - 变量
  • JS学习笔记——闭包
  • Lucene解析 - 基本概念
  • oschina
  • Redis的resp协议
  • SQLServer之创建显式事务
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 给github项目添加CI badge
  • 关于 Cirru Editor 存储格式
  • 前端存储 - localStorage
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 数据可视化之 Sankey 桑基图的实现
  • 一些关于Rust在2019年的思考
  • C# - 为值类型重定义相等性
  • 大数据全解:定义、价值及挑战
  • ​2020 年大前端技术趋势解读
  • ​水经微图Web1.5.0版即将上线
  • #define、const、typedef的差别
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (论文阅读22/100)Learning a Deep Compact Image Representation for Visual Tracking
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (排序详解之 堆排序)
  • (十)c52学习之旅-定时器实验
  • (一)kafka实战——kafka源码编译启动
  • (转)JAVA中的堆栈
  • (转)Linq学习笔记
  • (转)创业家杂志:UCWEB天使第一步
  • (转)母版页和相对路径
  • ../depcomp: line 571: exec: g++: not found
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .net 设置默认首页
  • .net(C#)中String.Format如何使用