問題描述
在給定大小的方格狀棋盤上, 將棋子」馬」放在指定的起始位置 , 棋子」馬」 的走子的規則為必須在棋盤上走」日」字; 從棋子」馬」的起始位置開始, 搜尋出一條可行的路徑, 使得棋子」馬」能走遍棋盤上的所有落子點, 而且每個落子點只能走一次;
例如: 棋盤大小為5*5 , 棋子馬放的起始落子點為 ( 3 , 3 ) ; 演算法需要搜尋一條從位置( 3 , 3 ) 開始的一條包括從( 1 , 1 ) , ( 1 , 2 ) , ( 1 , 3 ) … ( 5 , 1 ) , ( 5 , 2 ) , ( 5 , 3 ) , ( 5 , 4 ) , ( 5 , 5 ) 總共25個可以落子的全部位置;
問題分析
通過上面的問題描述,我們對問題的內容有了正確的理解,接下來我們開始對問題進行具體細緻的分析,以求找到解決問題的正確的可行的合理的方法;
首先我們需要在程式中用合適的資料結構表示在問題中出現的棋盤 , 棋子 , 棋子的走子過程 ; 接下來我們需要對核心問題進行分析, 即如何搜尋一條可行的路徑 , 搜尋採取何種策略 , 搜尋的過程如何表示 ;
對於乙個大小為n*m大小的棋盤 , 棋子從當前位置( x , y ) 出發,可以到達的下乙個位置( x』 , y』 ):
(1) ( x +1 , y +2 )
(2) ( x +1 , y –2 )
(3) ( x – 1, y +2 )
(4) ( x – 1, y – 2 )
(5) ( x +2, y +1)
(6) ( x +2, y – 1)
(7) ( x -2, y + 1)
(8) ( x -2, y – 1 )
限制條件:
1. 1 <= x』 <= n , 1 <= y』 <= m; ( n : 棋盤的高度 , m: 棋盤的寬度 );
2. ( x』 , y』 ) 必須是棋子記錄表中沒有包括的新位置;
3. 棋子走子過程記錄表中沒有包括棋盤上的所有可以落子的位置;
對這個過程不停迭代的過程也就是對解空間搜尋的過程, 搜尋直到棋子走子記錄表中包括棋盤上的所有可以落子的位置 , 就搜尋到了一條可行的路徑,路徑包括棋盤上的所有落子點;或者搜尋完整個解空間,仍然找不到一條可行的解,則搜尋失敗;
下面我們舉例來說明搜尋的過程;
棋盤大小 : 5 * 5
棋子起始位置 : ( 3 , 3 )
搜尋過程 :
(1) 從當前位置( 3 , 3 )出發可以有8個新的位置選擇; 首先選擇新位置1 , 將新位置1
作為當前棋子位置 , 開始新的搜尋;
如果搜尋不成功, 則搜尋回退, 選擇新位置2 ,以此類推,就可以搜尋完整個解空間,只要從該問題有解 , 則可以保證一定可以搜尋到;
2) 從新位置1 開始新的搜尋,可以選擇的新位置有兩個,先選擇位置1 , 從位置1開始新的搜尋;
(3) 下圖是經過18步搜尋之後的狀態, 從位置18出發, 已經沒有沒走過的新位置可以選擇, 則搜尋失敗;
(4) 下圖展示了搜尋成功的整個搜尋過程;
系統設計
一. 用例圖
二. 類設計
三. 順序圖
四. 核心演算法設計
通過上面的分析, 我們現在可以將演算法的大概框架寫出來了 , 具體的**請參考本文章後面的源程式;
下面我們先列出了經典回溯演算法的框架; 由於考慮到程式實現的方便性 , 所以本文中採用的回溯演算法對經典演算法進行了適當的修改;
經典演算法:
void backtrack( int t ){
馬踏棋盤演算法
為.c檔案 include include include define rows 8 define cols 8 int cheesboard rows cols const int movex 8 const int movey 8 初始化棋盤,將棋盤所有的位置賦值為0 void initboa...
馬踏棋盤演算法
將馬隨機放在西洋棋的board 0 7 0 7 的某個方格中,馬按走棋規則進行移動。走遍棋盤上全部64個方格。編制非遞迴程式,求出馬的行走路線,並按求出的行走路線,將數字1,2,64依次填入乙個8 8的方陣,輸出之。利用回溯法的思想,馬的走法總共有8,c 8 b 8 c是橫座標,b是縱座標。總共有6...
馬踏棋盤演算法
在乙個8 8象棋棋盤中,定義馬的起始位置,如何讓馬踏遍整個棋盤 使用遞迴求解,從起始位置開始,往其四周可去的點行走,走到之後,再以到達點為起始點再向四周可去點走,直到走完 include includeusing namespace std define wei 8 定義棋盤維度 typedef s...