gr8vyguy@Blogjava

应用Backtracking解一道算法题

在一个n乘n的棋盘上有一匹马,要求这匹马不重复的把每个格子都跳一边。这里马的走法和中国象棋里的马一样。如下图所示,一步只能跳到位于棋盘内的1到8的八个格子里。

 

对这道题目,一个最直观的解法就是使用所谓的Backtracking的思路,从起点开始,一直跳,没格子可跳了,就退回一步,接着往下跳。在这个过程中,记下所有跳过的格子,不重复跳到跳过的格子里。直到所有的格子都跳完为止,也就是发现一个解法,或者所有可能的跳法都试过,还没有找到一个跳法,也就是没有解法。

很简单的思路,但是如果你不熟悉Recursion的编程的话,要实现却不那么简单。Recursion是计算机科学中最重要的一个概念和工具,也是计算机科学强大动力的源泉,怎么强调都不过分。Recursion在计算机的各个学科都有着非常重要的作用。所有可计算的函数可以归结在Partial Recursive Function下。掌握和熟悉Recursion的思路可以说是您步入计算机科学殿堂的第一步。

下面是我用Java编写的跳马题的Recursive的解法


 1     private static int[][] board;
 2     private static int length;
 3 
 4     /**
 5      * search a solution of Springerproblem
 6      * 
 7      * @param n  board of n*n fields
 8      * @param x  [1 .. n] horizontal coordinate
 9      * @param y  [1 .. n] vertical coordinate
10      * @return   true found, false no
11      */
12     public static boolean search(int n, int x, int y) {
13         if (n < 1 || x < 1 || x > n || y < 1 || y > n) {
14             System.out.println("wrong input dimension.");
15             return false;
16         }
17 
18         board = new int[n + 1][n + 1];
19         length = n;
20         for (int i = 1; i <= length; i++)
21             for (int j = 1; j < length; j++)
22                 board[i][j] = 0;
23 
24         return research(x, y, 1);
25     }
26 
27     /**
28      * recursive search
29      * 
30      * @param x 起点x
31      * @param y 起点y
32      * @param step 第几步
33      * @return true 找到解法,false,失败了
34      */
35     private static boolean research(int x, int y, int step) {
36         if (x < 1 || x > length || y < 1 || y > length)
37             return false;
38         if (board[x][y] > 0)
39             return false;
40 
41         board[x][y] = step;
42         if (step == length * length)
43             return true;
44 
45         if (research(x - 1, y - 2, step + 1))
46             return true;
47         if (research(x - 1, y + 2, step + 1))
48             return true;
49         if (research(x + 1, y - 2, step + 1))
50             return true;
51         if (research(x + 1, y + 2, step + 1))
52             return true;
53         if (research(x - 2, y - 1, step + 1))
54             return true;
55         if (research(x - 2, y + 1, step + 1))
56             return true;
57         if (research(x + 2, y - 1, step + 1))
58             return true;
59         if (research(x + 2, y + 1, step + 1))
60             return true;
61 
62         board[x][y] = 0;
63         return false;
64     }

 

初学Recursion的时候,很不习惯他的思维方式。有时候甚至会奇怪这样就把问题解决了。在使用Recursion编程的时候,可以假定您已经有一个要找的函数f了,然后应用f 较小的情况来解决大的情况,最小的情况另外特殊求解。这个过程中最关键的就是设计f的接口和功能,在解题的过程中,您可能要不断的调整f的接口和功能。


转载请保留http://www.blogjava.net/xilaile/archive/2007/04/06/109001.html


posted on 2007-04-06 12:26 gr8vyguy 阅读(4212) 评论(0)  编辑  收藏 所属分类: 计算机科学基础


只有注册用户登录后才能发表评论。


网站导航:
 
<2007年4月>
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

导航

统计

公告

  • 转载请注明出处.
  • msn: gr8vyguy at live.com
  • 常用链接

    留言簿(9)

    随笔分类(68)

    随笔档案(80)

    文章分类(1)

    My Open Source Projects

    搜索

    积分与排名

    最新评论