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.aygfsteel.com/xilaile/archive/2007/04/06/109001.html


          posted on 2007-04-06 12:26 gr8vyguy 閱讀(4229) 評論(0)  編輯  收藏 所屬分類: 計算機科學基礎

          <2007年4月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          導航

          統計

          公告

        1. 轉載請注明出處.
        2. msn: gr8vyguy at live.com
        3. 常用鏈接

          留言簿(9)

          隨筆分類(68)

          隨筆檔案(80)

          文章分類(1)

          My Open Source Projects

          搜索

          積分與排名

          最新評論

          主站蜘蛛池模板: 高邑县| 宜宾市| 新疆| 铜鼓县| 贞丰县| 行唐县| 通渭县| 靖远县| 新营市| 富民县| 泰兴市| 漾濞| 宿松县| 车致| 长乐市| 乌审旗| 新余市| 杂多县| 凤城市| 齐河县| 吉木乃县| 乐陵市| 时尚| 万荣县| 石城县| 桐柏县| 竹溪县| 马尔康县| 喀什市| 弥勒县| 离岛区| 哈巴河县| 旅游| 正安县| 恩施市| 磐安县| 永年县| 喜德县| 颍上县| 麦盖提县| 江安县|