matlab madian,马踏棋盘——贪心算法

原来一直认为算法没啥难的 , 前几天无意间在网上看到了马踏棋盘的问题 , 就尝试的做了做 。这才发现之前上的课真是白上了 , 什么回溯、递归、贪心 , 就记得点名字 , 其他全都通通忘了(其实 , 当时就没学明白 , 嘿嘿) 。正好借着这个机会 , 从新学习一遍 , 鉴于估计以后还得忘(记性不好) , 特此写一篇博文记录一下 。
-----------------------------我是分割线(怕自己看不懂 , 嘿嘿)--------------------------
?首先 , 对问题描述一下 。马踏棋盘问题就是在一个8X8的棋盘上 , 马按照日字形规则在棋盘上欢快的跳跃 , 如何才能将每个格子都走到 , 而且每个格子只能跳一次 。(不知道这个问题谁想的 , 一定是闲的蛋疼 。。。)抽象来看 , 就是一个搜索问题 , 如果用二叉树来表示 , 就是一个深度为64 , 每个树杈有不多于7种分支的树(自行脑补 , 懒得画图了) 。那么最直观的方法就是用遍历的方法 , 也就是所谓的深度搜索(听着好牛) , 但是这样的效率据说比较低(我也没验证 , 有时间再说) , 还有比较常用的就是贪心算法 , 也就是本文所用方法 。
这里大概说一下贪心算法的内涵 , 就是在每次决策的时候选取局部最优(就是这么简单) 。对于马踏棋盘的问题来说 , 每次选取出口最少的路径 。至于为什么这么选择 , 我看到有人说是因为出口少就代表选择性小 , 遍历的也就会快 , 也就越容易先排除 , 这样就增加了算法速度 。但是 , 如果按照这个理论也就意味着 , 在决策的时候要去找局部最差 , 显然这个解释不太合理(不过 , 我目前也没想明白) 。先不管为啥了 , 就这么做吧 。
再说说这里面要用到的回溯和递归算法 , 这两个算法的意思我就不解释了 。我要说的是在设计递归的时候 , 要把任务拆分成?循环任务 。同时 , 要设计出成功通道 , 也就是什么情况下递归结束 。对于该问题 , 递归函数要完成的有以下几点:1.查找可用的子节点;2.记录当前结点位置;3.进入一个子节点;4.判定递归成功 , 并从成功通道跳出递归 。
对于回溯算法 , 就是如果不成功 , 要从子节点回到父节点 。对于本问题 , 其实并不需要设置回到父节点的?程序 , 只需要将已经记录的位置清零(也就是相当于没走这条路) , 并且不再进行下一步的递归 , 跳出当前程序 , 也就是回溯了 。
在编程的时候 , 为了调代码方便 , 看到有人用5X5的棋盘做实验 , 我也就照猫画虎 。?但是 , 要注意的是5X5的棋盘并不是所有点都有解(就没人说过!!导致我还老以为我的代码出问题了 , 8X8的棋盘是所有点都有解的) 。
都说无图无真相 , 先放两张图 , 一张5X5 , 一张8X8
5X5解法
8X8解法
程序用文字描述如下:
【输出棋盘号 , 标志位】=查找路径【节点位置 , 输入棋盘号】
if 是否走完了所有位置
标志位置1;;
end
查找所有可能子节点
将子节点按照贪心算法排序
for 每个可能节点
递归查找路径函数
if 标志位为1
记录当前棋盘号;?