【問題描述】
馬的遍歷問題。在8×8方格的棋盤上,從任意指定方格出發,為馬尋找一條走遍棋盤每一格並且只經過一次的一條路徑。
【初步設計】
首先這是乙個搜尋問題,運用深度優先搜尋進行求解。演算法如下:
1、 輸入初始位置座標x,y;
2、 步驟 c:
如果c>64輸出乙個解,返回上一步驟c--
(x,y) ← c
計算(x,y)的八個方位的子結點,選出那此可行的子結點
迴圈遍歷所有可行子結點,步驟c++重複2
顯然(2)是乙個遞迴呼叫的過程,大致如下:
void dfs(int x,int y,int count)for(i=0;i<8;++i)
}
這樣做是完全可行的,它輸入的是全部解,但是馬遍歷當8×8時解是非常之多的,用天文數字形容也不為過,這樣一來求解的過程就非常慢,並且出乙個解也非常慢。
怎麼才能快速地得到部分解呢?
【貪心演算法】
其實馬踏棋盤的問題很早就有人提出,且早在2023年,j.c.warnsdorff就提出了乙個有名的演算法。在每個結點對其子結點進行選取時,優先選擇『出口』最小的進行搜尋,『出口』的意思是在這些子結點中它們的可行子結點的個數,也就是『孫子』結點越少的越優先跳,為什麼要這樣選取,這是一種區域性調整最優的做法,如果優先選擇出口多的子結點,那出口少的子結點就會越來越多,很可能出現『死』結點(顧名思義就是沒有出口又沒有跳過的結點),這樣對下面的搜尋純粹是徒勞,這樣會浪費很多無用的時間,反過來如果每次都優先選擇出口少的結點跳,那出口少的結點就會越來越少,這樣跳成功的機會就更大一些。這種演算法稱為為貪心演算法,也叫貪婪演算法或啟發示演算法,它對整個求解過程的區域性做最優調整,它只適用於求較優解或者部分解,而不能求最優解。這樣的調整方法叫貪心策略,至於什麼問題需要什麼樣的貪心策略是不確定的,具體問題具體分析。實驗可以證明馬遍歷問題在運用到了上面的貪心策略之後求解速率有非常明顯的提高,如果只要求出乙個解甚至不用回溯就可以完成,因為在這個演算法提出的時候世界上還沒有計算機,這種方法完全可以用手工求出解來,其效率可想而知。
在前面的演算法基礎之上,增添一些程式加以實現:
函式1:計算結點出口多少
int ways_out(int x,int y)return count;
}
函式2:按結點出口進行排序
void sortnode(h_node *hn,int n)//採用簡單排序法,因為子結點數最多只有8
}}
函式3:修改後的搜尋函式
void dfs(int x,int y,int count)for(i=0;i<8;++i)//
求子結點和出口
sortnode(hn,8);
for(i=0;hn[i].waysout<0;++i);//
不考慮無用結點
for(;i<8;++i)
}
函式4:主調函式
void main()s[x][y]=1;
dfs(x,y,2);//
開始搜尋
}
貪心演算法 馬踏棋盤(C)
貪心演算法 又稱貪婪演算法 是指,在對 問題求解 時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,他所做出的僅是在某種意義上的區域性 最優解。貪心演算法不是對所有問題都能得到整體 最優解,但對範圍相當廣泛的許多問題他能產生整體最優解或者是整體最優解的近似解。貪婪演算法是一種改進...
馬踏棋盤之貪心演算法優化
問題描述 曾經用簡單的深度優先搜尋方法 遞迴的形式對馬踏棋盤進行搜尋,執行效率不甚理想。部落格見馬踏棋盤之遞迴實現 所以現在用貪心演算法將其優化了一下。問題解析 主要的思想沒有變,還是用深度優先搜尋,只是在選下乙個結點的時候做了貪心演算法優化,其思路如下 從起始點開始,根據 馬 的走法,它的下一步的...
資料結構 馬踏棋盤題解(貪心演算法)
使用迴圈建立棋盤與權值棋盤 權值為該位置可走的位置數量 將當前步數寫入棋盤陣列中 開始探測下一步該走的位置,分別測試八個方向 對可走位置進行查詢權值,將權值最少的作為下一步的位置 每次都將步數最少的可走位置作為下一步的位置即貪心的體現 迴圈2 4。馬踏棋盤 貪心題解 include include ...