[演算法之回溯演算法]

我是太陽啦啦啦發表於2017-11-12

前言:

本篇部落格來總結一下回溯演算法,作為演算法的積累:

核心:

演算法定義:

回溯法是一種優先搜尋法,按照選優條件深度優先搜尋,以達到目標.當搜尋到某一步時,發現原先選擇並不是最優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術稱為回溯法.

演算法思想:

回溯法是從初始狀態出發,按照深度優先搜尋的方式,根據產生子結點的條件約束,搜尋問題的解.當發現當前結點不滿足求解條件時,就回溯,嘗試其他的路徑.

回溯法是一種"能進則進,進不了則換,換不了則退"的搜尋方法.

解題步驟:

定義解空間

確定解空間的組織結構

搜尋解空間

n皇后問題

C++程式碼


#include "stdafx.h"
#include <iostream>
#include <cmath>   //求絕對值函式需要引入該標頭檔案
#define M 105


using namespace std;


int n;//n表示n個皇后
float x[M];  //x[i]表示第i個皇后放置在第i行第x[i]列
int countn;    //countn表示n皇后問題可行解的個數


bool Place(int t) //判斷第t個皇后能否放置在第i個位置
{
    bool ok=true;
    for(int j=1;j<t;j++)   //判斷該位置的皇后是否與前面t-1個已經放置的皇后衝突
    {
       if(x[t]==x[j]||t-j==fabs(x[t]-x[j]))//判斷列、對角線是否衝突
       {
           ok=false;
           break;
       }
    }
    return ok;
}


void Backtrack(int t)
{
    if(t>n)  //如果當前位置為n,則表示已經找到了問題的一個解
    {
        countn++;
        for(int i=1; i<=n;i++) //列印選擇的路徑
          cout<<x[i]<<" ";
        cout<<endl;
        cout<<"----------"<<endl;
    }
    else
        for(int i=1;i<=n;i++) //分別判斷n個分支,特別注意i不要定義為全域性變數,否則遞迴呼叫有問題
        {
            x[t]=i;
            if(Place(t))
                Backtrack(t+1); //如果不衝突的話進行下一行的搜尋
        }
}
int main()
{
    cout<<"請輸入皇后的個數 n:";
    cin>>n;
    countn=0;
    Backtrack(1);
    cout <<"答案的個數是:"<<countn<< endl;
	system("pause");
    return 0;
}

總結:

學習都是從基礎開始的,先學好基礎,好了,今天就總結到這裡了!

相關文章