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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

汉密尔顿回路问题

發(fā)布時(shí)間:2023/12/18 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 汉密尔顿回路问题 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

概述

這是自己這學(xué)期算法課的實(shí)驗(yàn)作業(yè)。下面給出漢密爾頓圖的定義。定義如下:對(duì)于連通圖G=(V,E),V1,V2,…,Vn是G 的一條通路,且圖中任意兩個(gè)頂點(diǎn)都可達(dá),若 中每個(gè)頂點(diǎn)在該通路中出現(xiàn)且僅出現(xiàn)一次,則稱(chēng)該通路為漢密爾頓通路。若 V1=Vn,則稱(chēng)該通路為漢密爾頓回路。


算法描述

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

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

例子

下面的例子是基于如下圖結(jié)構(gòu):

全部代碼如下:

#include <iostream> #include <cstring> #include <vector> #include <cstdio> using namespace std;/*邊與邊長(zhǎng):(起點(diǎn),終點(diǎn),長(zhǎng)度) 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 拉黑圣誕節(jié), int* isvisited; //訪問(wèn)數(shù)組 int Nv; //頂點(diǎn)數(shù) int Ne; //邊數(shù)vector<int> best_path; //漢密爾頓最佳路徑 public://構(gòu)造函數(shù)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;}//初始化訪問(wèn)數(shù)組 this->isvisited = new int[nv+1];memset(this->isvisited,0,sizeof(this->isvisited[0])*(nv+1));//對(duì)鄰接矩陣進(jìn)行初始化 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<<"請(qǐng)輸入邊與邊長(zhǎng):"<<endl;//對(duì)邊進(jìn)行初始化 for(int i = 0 ; i < ne ; i++){int v1,v2,weight;cin>>v1>>v2>>weight;this->data[v1][v2] = this->data[v2][v1] = weight;} }//求漢密爾頓回路函數(shù) int Hanmilton(){int path[1000] = {0};int cur_vertex = 0; //作為保存當(dāng)前結(jié)點(diǎn) int length = 0; //漢密爾頓回路長(zhǎng)度int min = 10000; //最小長(zhǎng)度 for(int i = 1 ; i < this->Nv+1 ; i++){//對(duì)每個(gè)頂點(diǎn)為初始點(diǎn)進(jìn)行比遍歷尋找漢密爾頓回路 length = 0; //重新設(shè)置最端長(zhǎng)度為0 memset(this->isvisited,0,sizeof(this->isvisited[0])*(this->Nv+1)); //重新初始化訪問(wèn)數(shù)組為0 this->isvisited[i] = 1; //標(biāo)記當(dāng)前結(jié)點(diǎn)為已訪問(wèn) path[1] = i; //保存到臨時(shí)路徑數(shù)組的第一個(gè)cur_vertex = i; //保存當(dāng)前頂點(diǎn)for(int j = 2 ; j < this->Nv+1 ; j++){//訪問(wèn)剩余的結(jié)點(diǎn) int k = 0;//尋找到第一個(gè)未訪問(wèn)的結(jié)點(diǎn) for(k = 2 ; k < this->Nv+1 ; k++){if(this->isvisited[k] == 0){break;}}int tmp = this->data[cur_vertex][k]; //保存當(dāng)前頂點(diǎn)到該結(jié)點(diǎn)的路徑長(zhǎng)度 for(int m = k+1 ; m < this->Nv+1 ; m++){//向后尋找有沒(méi)有路徑更短的節(jié)點(diǎn) if((!this->isvisited[m]) && (tmp > this->data[cur_vertex][m])){tmp = this->data[cur_vertex][m];//更新當(dāng)前最短路徑 k = m;//更新第一個(gè)未被訪問(wèn)的結(jié)點(diǎn) }}path[j] = k; //保存路徑上的結(jié)點(diǎn)this->isvisited[k] = 1; //標(biāo)記為已訪問(wèn) cur_vertex = k; //跟新當(dāng)前結(jié)點(diǎn) length += tmp; //跟新長(zhǎng)度 if(length > min){ //當(dāng)前長(zhǎng)度大于最小長(zhǎng)度,則改路徑無(wú)效,跳出循環(huán) break;}}length += this->data[cur_vertex][i];if(min > length){ //更新最小長(zhǎng)度并保存最佳路徑 min = length;for(int m = 0 ; m < this->Nv+1 ; m++){this->best_path[m] = path[m]; }}}//返回最小長(zhǎng)度 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<<"請(qǐng)輸入頂點(diǎn)數(shù)與邊數(shù):"<<endl;int nv,ne;cin>>nv>>ne;Graph graph(nv,ne);cout<<"鄰接矩陣為:"<<endl;graph.Print();cout<<"該圖的漢密爾頓回路長(zhǎng)度為:"<<endl;int length = 0;length = graph.Hanmilton();cout<<length<<endl;cout<<"漢密爾頓回路路徑為:"<<endl;graph.Print_Best_Path(); return 0; }

運(yùn)行結(jié)果如下:

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。