基於回溯法尋找哈密頓回路


回溯法是一種選優搜索法,又稱為試探法,按選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為“回溯點”。

在包含問題的所有解的解空間樹中,按照深度優先搜索的策略,從根結點出發深度探索解空間樹。當探索到某一結點時,要先判斷該結點是否包含問題的解,如果包含,就從該結點出發繼續探索下去,如果該結點不包含問題的解,則逐層向其祖先結點回溯(其實回溯法就是對隱式圖的深度優先搜索算法)。 若用回溯法求問題的所有解時,要回溯到根,且根結點的所有可行的子樹都要已被搜索遍才結束。 而若使用回溯法求任一個解時,只要搜索到問題的一個解就可以結束。

 

哈密頓圖是一個無向圖,由天文學家哈密頓提出,由指定的起點前往指定的終點,途中經過所有其他節點且只經過一次。在圖論中是指含有哈密頓回路的圖,閉合的哈密頓路徑稱作哈密頓回路,含有圖中所有頂點的路徑稱作哈密頓路徑。

 

利用回溯法判斷哈密頓回路是一種簡單粗暴的試探,也因而容易理解,其方法如下代碼,因注釋詳細,不再詳述。

#include <iostream>
using namespace std;
const int MAX_V = 50;
void print(int path[], int V)
{
    cout << "存在哈密頓回路" << endl;
    for (int i = 0; i < V; i++) cout << path[i] << " ";
    cout << path[0] << endl;
}
//path記錄路徑,visited記錄頂點是否訪問過,len記錄當前路徑的長度
bool hamCycle(int graph[][MAX_V], int V, int path[], bool visited[], int current) {
    if (current == V) { //訪問到最后一個頂點
        if (graph[path[current - 1]][0] == 1)  return true;//有到0點的邊
        else return false;
    }
    //遍歷起點外其它頂點
    for (int v = 1; v < V; v++) {
        //如果沒訪問過,並且有邊相連
        if (!visited[v] && graph[path[current - 1]][v] == 1) {
            visited[v] = true;
            path[current] = v;
            //當本次遞歸的child也為true時返回true
            if (hamCycle(graph, V, path, visited, current + 1)) return true;
            //當本條遞歸線路失敗時恢復原圖
            path[current] = -1;
            visited[v] = false;
        }
    }
    return false;
}
//從起點開始引導
bool hamCycleStart(int graph[][MAX_V], int V) {
    int path[MAX_V];
    memset(path, -1, sizeof(path));
    bool visited[MAX_V] = { 0 };
    path[0] = 0;
    visited[V] = true; //把起點標記為訪問過
    //起點已確定,current從1開始
    if (hamCycle(graph, V, path, visited, 1) == false) {
        cout << "哈密頓回路不存在" << endl;
        return false;
    }
    print(path, V);
    return true;
}
int main() {
    int graph[MAX_V][MAX_V];
    int V;
    cout << "請輸入點的個數:" << endl;
    cin >> V;
    for (int i = 0;i < V;++i)
    {
        cout << "請輸入圖的第" << i << "" << endl;
        for (int j = 0;j < V;++j)
        {
            cin >> graph[i][j];
        }
    }
    hamCycleStart(graph, V);
    return 0;
}
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM