C++回溯演算法Demo:以4皇后問題為例

來源:互聯網
上載者:User

標籤:

回溯演算法實際上是構造一棵推理樹,並由樹的葉子節點反向輸出曆史步驟;

其中,樹的構建過程較為複雜;一種簡化的方法是使用鏈表串連和構造各個節點的關係;

以4皇后問題為例,採用C++ vector容器——避免使用指標(當然換成了整數來代替指標表達對象的位置),解決了該問題。整體演算法思路清晰,便於理解。

見代碼;與書中不同,此代碼實際輸出的是所有4皇后問題的不同走法


//title:4皇后問題的回溯演算法求解//Demo: 1)回溯演算法實現4皇后問題;2)痛點:樹形結構的表達;3)用線性容器表達樹形結構,並實現樹的掃描——降低了樹實現的難度//author: Liping Chen//email: [email protected]//published date: 20125-4-11#include <iostream>#include <string.h>#include <vector>#include <stdlib.h>using namespace std;//定義4皇后棋局的資料結構及方法typedef struct Queen4 {int vals[16];int nQueens;int parent;//預設建構函式Queen4() { for(int i = 0; i < 16; i++) vals[i] = 0; parent = 0;nQueens = 0;}//建構函式1Queen4(int nvals[16]) { for(int i = 0; i < 16; i++) vals[i] = nvals[i]; parent = 0;nQueens = 0;}//找到當前布局中不為0的位置int getPosition() {for(int i = 0; i < 16; i++) if (vals[i] == 0) {return i;}return -1;}//當設定皇后位置時,標記水平、垂直和斜線位置掩碼void setQueen(int pos) {int row, col;vals[pos] = 1;nQueens++;row = pos / 4;col = pos % 4;for(int c = 1; c <= 3; c++) {//右下if (row + c < 4 && col + c < 4) if (vals[(row + c) * 4 + (col + c)] == 0)vals[(row + c) * 4 + (col + c)] = 2;//左上if (row - c >= 0 && col - c >= 0) if (vals[(row - c) * 4 + (col - c)] == 0)vals[(row - c) * 4 + (col - c)] = 2;//左下if (row + c < 4 && col - c >= 0) if (vals[(row + c) * 4 + (col - c)] == 0)vals[(row + c) * 4 + (col - c)] = 2;//右上if (row - c >= 0 && col + c >= 0) if (vals[(row - c) * 4 + (col + c)] == 0)vals[(row - c) * 4 + (col + c)] = 2;//右水平if (col + c < 4) if (vals[row * 4 + (col + c)] == 0)vals[row * 4 + (col + c)] = 2;//左水平if (col - c >= 0) if (vals[row * 4 + (col - c)] == 0)vals[row * 4 + (col - c)] = 2;//下if (row + c < 4) if (vals[(row + c) * 4 + col] == 0)vals[(row + c) * 4 + col] = 2;//上if (row - c >= 0) if (vals[(row - c) * 4 + col] == 0)vals[(row - c) * 4 + col] = 2;}}//輸出當前棋局void output(int level) {int cnt = 0;char chars[100];for(int k = 0; k < level; k++)chars[k] = ' ';chars[level] = '\0';cout << chars << "Queen4=" << endl  << chars;for(int i = 0; i < 16; i++) {cout << vals[i] << " ";cnt++;if (cnt % 4 == 0) cout << endl << chars;}}//遞迴調用輸出曆史棋局void outputHist(vector<Queen4>& tr) {if (parent)tr[parent].outputHist(tr);output(0);}//由棋的當前布局產生下一布局void reproduce(vector<Queen4>& tr, int pos) {int nvals[16];bool inserted;//思考:為什麼要使用nvalsfor(int i = 0; i < 16; i++)nvals[i] = vals[i];for(int i = 0; i < 16; i++) {if (nvals[i] == 0) {nvals[i] = 1;//新結果加入容器Queen4 q(tr[pos].vals);q.setQueen(i);q.parent = pos;tr.push_back(q);}}}}Queen4;//程式主函數int main() {Queen4 q0;//調用預設建構函式vector<Queen4> tr;//向量容器——作用相當於隊列,可以向期中添加新的棋盤布局int levels[1024] = {0};//記錄每層的孩子數量——用於分層tr.push_back(q0);//將初始棋盤加入容器int oldn = 0, newn = 1, level = 0;      //儲存變數//讓根節點產生新孩子,並把新孩子加入容器//若不再產生新孩子了,則認為已找到答案//那麼,最底層的就是答案(需要記錄每層所產生的孩子數)while(newn != oldn) {//讓最後的孩子再產生新孩子for(int i = oldn; i < newn; i++) tr[i].reproduce(tr, i);//更新老孩子和新孩子的數量oldn = newn;levels[++level] = newn;newn = tr.size();}oldn = 1;//輸出4皇后問題共有多少種解法for(int i = levels[level-1]; i < levels[level]; i++) {cout << "4皇后放置走法:" << oldn++ << endl;tr[i].outputHist(tr);}return 0;}


C++回溯演算法Demo:以4皇后問題為例

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.