日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

汉密尔顿回路问题

發布時間:2023/12/18 编程问答 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 汉密尔顿回路问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

這是自己這學期算法課的實驗作業。下面給出漢密爾頓圖的定義。定義如下:對于連通圖G=(V,E),V1,V2,…,Vn是G 的一條通路,且圖中任意兩個頂點都可達,若 中每個頂點在該通路中出現且僅出現一次,則稱該通路為漢密爾頓通路。若 V1=Vn,則稱該通路為漢密爾頓回路。


算法描述

1)初始化最佳路徑數組best_path,同時初始化臨時路徑數組path與訪問數組isvisited,設置最小長度min,設置長度變量length = 0
2)開始對每個頂點進行遍歷尋找最佳路徑,首先堆訪問數組中對應頂點進行置1,并把當前頂點追加到path,同時利用cur_vertex這個臨時變量保存當前結點,并開始進行循環。
3)找到出cur_vertex之外與之相鄰且并未訪問的一個頂點k,利用tmp保存這兩點之間的權重,之后檢查是否存在比tmp更小且與cur_vertex相鄰的頂點,如有則更新tmp與訪問的頂點k,之后更新length += tmp,以及更新cur_vertex = k,如果length大于min,則說明改路徑無效,跳出循環。
4)重復步驟3遍歷每一個結點。循環結束后,對length更新,加上最后一個結點到cur_vertex結點的距離。這是如果min大于legnth,則對min更新,并把path數組復制到best_path中去。
5)重復步驟2)直至遍歷完每個結點。返回最小長度。

//求漢密爾頓回路函數 int Hanmilton(){int path[1000] = {0};int cur_vertex = 0; //作為保存當前結點 int length = 0; //漢密爾頓回路長度int min = 10000; //最小長度 for(int i = 1 ; i < this->Nv+1 ; i++){//對每個頂點為初始點進行比遍歷尋找漢密爾頓回路 length = 0; //重新設置最端長度為0 memset(this->isvisited,0,sizeof(this->isvisited[0])*(this->Nv+1)); //重新初始化訪問數組為0 this->isvisited[i] = 1; //標記當前結點為已訪問 path[1] = i; //保存到臨時路徑數組的第一個cur_vertex = i; //保存當前頂點for(int j = 2 ; j < this->Nv+1 ; j++){//訪問剩余的結點 int k = 0;//尋找到第一個未訪問的結點 for(k = 2 ; k < this->Nv+1 ; k++){if(this->isvisited[k] == 0){break;}}int tmp = this->data[cur_vertex][k]; //保存當前頂點到該結點的路徑長度 for(int m = k+1 ; m < this->Nv+1 ; m++){//向后尋找有沒有路徑更短的節點 if((!this->isvisited[m]) && (tmp > this->data[cur_vertex][m])){tmp = this->data[cur_vertex][m];//更新當前最短路徑 k = m;//更新第一個未被訪問的結點 }}path[j] = k; //保存路徑上的結點this->isvisited[k] = 1; //標記為已訪問 cur_vertex = k; //跟新當前結點 length += tmp; //跟新長度 if(length > min){ //當前長度大于最小長度,則改路徑無效,跳出循環 break;}}length += this->data[cur_vertex][i];if(min > length){ //更新最小長度并保存最佳路徑 min = length;for(int m = 0 ; m < this->Nv+1 ; m++){this->best_path[m] = path[m]; }}}//返回最小長度 return min; }

例子

下面的例子是基于如下圖結構:

全部代碼如下:

#include <iostream> #include <cstring> #include <vector> #include <cstdio> using namespace std;/*邊與邊長:(起點,終點,長度) 1 2 21 3 31 4 21 5 52 3 62 4 82 5 103 4 103 5 154 5 12 */ class Graph{private:int** data; //鄰接矩陣 到sa 拉黑圣誕節, int* isvisited; //訪問數組 int Nv; //頂點數 int Ne; //邊數vector<int> best_path; //漢密爾頓最佳路徑 public://構造函數Graph(int nv,int ne){this->Nv = nv;this->Ne = ne;this->data = new int*[nv+1];best_path.reserve(nv+1);for(int i = 0 ; i < nv+1 ; i++){best_path[i] = 0;}//初始化訪問數組 this->isvisited = new int[nv+1];memset(this->isvisited,0,sizeof(this->isvisited[0])*(nv+1));//對鄰接矩陣進行初始化 for(int i = 0 ; i < nv+1 ; i++){data[i] = new int[nv+1];memset(data[i],0,sizeof(data[i][0])*(nv+1));}cout<<"請輸入邊與邊長:"<<endl;//對邊進行初始化 for(int i = 0 ; i < ne ; i++){int v1,v2,weight;cin>>v1>>v2>>weight;this->data[v1][v2] = this->data[v2][v1] = weight;} }//求漢密爾頓回路函數 int Hanmilton(){int path[1000] = {0};int cur_vertex = 0; //作為保存當前結點 int length = 0; //漢密爾頓回路長度int min = 10000; //最小長度 for(int i = 1 ; i < this->Nv+1 ; i++){//對每個頂點為初始點進行比遍歷尋找漢密爾頓回路 length = 0; //重新設置最端長度為0 memset(this->isvisited,0,sizeof(this->isvisited[0])*(this->Nv+1)); //重新初始化訪問數組為0 this->isvisited[i] = 1; //標記當前結點為已訪問 path[1] = i; //保存到臨時路徑數組的第一個cur_vertex = i; //保存當前頂點for(int j = 2 ; j < this->Nv+1 ; j++){//訪問剩余的結點 int k = 0;//尋找到第一個未訪問的結點 for(k = 2 ; k < this->Nv+1 ; k++){if(this->isvisited[k] == 0){break;}}int tmp = this->data[cur_vertex][k]; //保存當前頂點到該結點的路徑長度 for(int m = k+1 ; m < this->Nv+1 ; m++){//向后尋找有沒有路徑更短的節點 if((!this->isvisited[m]) && (tmp > this->data[cur_vertex][m])){tmp = this->data[cur_vertex][m];//更新當前最短路徑 k = m;//更新第一個未被訪問的結點 }}path[j] = k; //保存路徑上的結點this->isvisited[k] = 1; //標記為已訪問 cur_vertex = k; //跟新當前結點 length += tmp; //跟新長度 if(length > min){ //當前長度大于最小長度,則改路徑無效,跳出循環 break;}}length += this->data[cur_vertex][i];if(min > length){ //更新最小長度并保存最佳路徑 min = length;for(int m = 0 ; m < this->Nv+1 ; m++){this->best_path[m] = path[m]; }}}//返回最小長度 return min;}//打印最佳漢密爾頓回路 void Print_Best_Path(){cout<<this->best_path[1];for(int i = 2 ; i < this->Nv+1 ; i++){cout<<" -> "<<this->best_path[i];}cout<<" -> "<<this->best_path[1];}//打印鄰接矩陣 void Print(){for(int i = 1 ; i < this->Nv+1 ; i++){for(int j = 1 ; j < this->Nv+1 ; j++){printf("%3d",this->data[i][j]);}cout<<endl;}} };int main() {cout<<"請輸入頂點數與邊數:"<<endl;int nv,ne;cin>>nv>>ne;Graph graph(nv,ne);cout<<"鄰接矩陣為:"<<endl;graph.Print();cout<<"該圖的漢密爾頓回路長度為:"<<endl;int length = 0;length = graph.Hanmilton();cout<<length<<endl;cout<<"漢密爾頓回路路徑為:"<<endl;graph.Print_Best_Path(); return 0; }

運行結果如下:

總結

以上是生活随笔為你收集整理的汉密尔顿回路问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。