引言
      在<<算法系列---回溯算法>>一节,讨论回溯算法及其应用,回溯能够在可以接受的时间内解决某些规模的组合问题,这节再讨论它的一个非常有意思的应用---跳马问题(骑士周游问题)。

问题
跳马问题也称为骑士周游问题,是算法设计中的经典问题。其一般的问题描述是:

     考虑国际象棋棋盘上某个位置的一只马,它是否可能只走63步,正好走过除起点外的其他63个位置各一次?如果有一种这样的走法,则称所走的这条路线为一条马的周游路线。试设计一个算法找出这样一条马的周游路线。

此题实际上是一个Hamilton回路问题,和迷宫问题很相似,可以用回溯算法来解决.
考虑到马在每一个位置,最多有8种跳法,如下图所示:
 

K7

K0

K6

K1

K

K5

K2

K4

K3

可以使用N皇后问题的算法模板。
算法如下:

算法系列---回溯算法(续)#include <stdio.h>
算法系列---回溯算法(续)#include 
<stdlib.h>
该算法最坏的时间复杂度为O(8N*N)。这是一个相当大的数字,不能接受,但实际情况好得多。并且在37步的时候,开
发生回溯,可通过改BackTrace中的第一个if中的参数发现据说,总的回溯次数达300多百万次.
我的机子运行20分钟也没运行出结果.我们可以考虑,当N=8时,为2192,即使对于2100=1.3*1030,对于一台每秒1万亿(1012)次操作的计算机,也需要4*1010才能完成,超过了45亿年---地球的估计年龄.
但是,该算法可以适当改进,考虑到:
即向前看两步,当每准备跳一步时,设准备跳到(x, y)点,计算(x, y)这一点可能往几个方向跳(即向前看两步),将这个数目设为(x, y)点的权值,将所  有可能的(x, y)按权值排序,从最小的开始,循环遍历所有可能的(x, y),回溯求出结果。算法可以求出所有可能的马跳棋盘路径,算出一个可行 的结果很快,但在要算出所有可能结果时,仍然很慢,因为最坏时间复杂度本质上并没有改变,仍为O(8^(N * N)),但实际情况很好,在瞬间即可得到一个解,当然,要求得所有解,也需要很长的时间.
下面是实现这一思想的代码:

算法系列---回溯算法(续)#include <stdio.h>
算法系列---回溯算法(续)#include 
<stdlib.h>

如果如下:
算法系列---回溯算法(续)

相关文章:

  • 2021-09-11
  • 2021-11-23
  • 2021-11-23
猜你喜欢
  • 2021-06-07
  • 2022-03-06
  • 2021-04-02
  • 2021-11-13
相关资源
相似解决方案